Hi,你有一份Code Review攻略待查收!
2022-06-27 yzx
Hi,你有一份Code Review攻略待查收!
作者:yzx 发布时间:2022-06-27 10:00:00

介绍

作为一名从业多年的后端开发人员,已经逐渐减少了自己写代码的时间,将更多的工作时间投入到code review中。通过code review可以减少bug出现的概率,提高代码质量,还可以帮助他人进步。

但在code review的过程中,会发现有些人的编码习惯不太好,导致代码结构、格式混乱,代码里面暗藏深坑。比如:

  1. 方法过长,把整个逻辑都写在一个方法里面,没有进行必要的抽象与封装。

  2. 方法没有必要注释,方法名还做不到望文生义。

  3. 文件打开以后,忘记关闭工作流。

等等情况。

我在code review的过程中,能够发现一些问题,但还有一些问题,也许是大意,也许是知识不够全面,可能就被遗漏了。

每次光是格式和编码习惯的检查就会占用大量code review时间,这种状况令人十分苦恼。

有没有一种可能,在我code review之前,自动把格式规范,编码习惯这些简单的问题都检查完成,告诉我一个检查结果,我只需要去review业务代码呢?

后来我发现了建木 + checkstyle + SonarQube。

组件介绍

建木:建木以触发器、流程编排、任务分发等功能为核心,可以应用在各类使用场景下,包括但不限于,CI/CD、DevOps、自动化运维、多业务系统集成等场景。在我的使用过程中,发现它十分灵活,可以自由组合各种功能,使用也十分简单,只要选好你心仪的节点,把它加入到你的流程中就OK啦。

checkstyle:一款代码规范检查的工具。

SonarQube:一款代码缺陷检查的工具。

整体使用流程

如图:

流程讲解:

  1. Coder将自己的代码提交到代码仓库,发起Merge Request。

  2. 代码仓库调用建木钩子,触发建木流程。

  3. 建木从仓库拉取代码,进行checkstyle和SonarQube静态代码扫描。

  4. 建木将扫描结果,以评论的方式,写回到Merge Request的评论中。

  5. Reviewer开始工作,参考扫描结果,进行Code Review。

自此,code review也有了“自动档”,有建木辅助merge的检查,点merge更有底气~

如何搭建

下面和大家分享一下如何使用建木来搭建这个流程🤓

  1. 对项目本身进行改造,在项目中引入checkstyle和SonarQube插件,并完成配置工作。关于checkstyle和sonarqube的配置使用可以参考:
  2. 开始准备我们需要使用到的建木节点🤪

克隆源分支和目标分支代码。

image-20220617175911152

执行mvn compile sonar:sonar来检查代码是否存在缺陷

执行mvn checkstyle:checkstyle-aggregate来检查代码是否规范

image-20220617180101850

比较源分支和目标分支的规范结果文件,结果大于0,说明本次合并新增加了不规范代码

注:checkstyle的扫描已经配置在执行maven命令时自动执行,check_style节点,只是用来获取分析maven执行日志中的扫描结果。

image-20220617180314482

获取本次代码新增BUG和新增漏洞的数量,以及获取sonarqube的部署地址。

注:SonarQube的扫描已经配置在执行maven命令时自动执行,SonarQube节点,只是用来获取maven执行日志中的扫描结果。

image-20220620134809384

向Gitlab的Merge Request中以评论方式通知扫描结果。

image-20220617180517393

发送相关通知到企业微信。

image-20220617180836792

  1. 然后编写DSL文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
name: java-style-check

# 可并发执行
global:
concurrent: true

trigger:
type: webhook
param:
- name: action
type: STRING
exp: $.body.json.object_attributes.action
- name: object_kind
type: STRING
exp: $.body.json.object_kind
- name: user_name
type: STRING
exp: $.body.json.object_attributes.last_commit.author.name
- name: project_name
type: STRING
exp: $.body.json.project.name
- name: source_branch
type: STRING
exp: $.body.json.object_attributes.source_branch
- name: target_branch
type: STRING
exp: $.body.json.object_attributes.target_branch
- name: remote_url
type: STRING
exp: $.body.json.project.git_http_url
- name: git_host
type: STRING
exp: $.header.x-real-ip
- name: project_id
type: STRING
exp: $.body.json.project.id
- name: iid
type: STRING
exp: $.body.json.object_attributes.iid
# webhook事件 一个merge事件open、update、reopen都可以触发该流程
only: (${trigger.object_kind} == "merge_request" && ${trigger.action} == "open" || ${trigger.action} == "update" || ${trigger.action} == "reopen")

workflow:
start:
type: start
targets:
- git_source_branch
- git_target_branch
# 源分支
git_source_branch:
type: "git_clone:1.1.1"
sources:
- start
targets:
- maven1
param:
remote_url: "${trigger.remote_url}"
ref: "refs/heads/${trigger.source_branch}"
netrc_password: "((gitlab.password))"
netrc_machine: "x.x.x.x"
netrc_username: "((gitlab.username))"
# 通过mvn命令,使用代码规范检查工具check-style检查源分支,生成规范结果文件
# 通过mvn命令,使用代码缺陷检查工具sonarqube来检查代码,并且把结果上传到服务器
maven1:
type: "jianmu/maven:jdk"
sources:
- git_source_branch
targets:
- sonarqube_analysis
param:
mvn_action: "compile sonar:sonar clean checkstyle:checkstyle-aggregate"
workspace: "${git_source_branch.git_path}"
maven_public_id: "maven-releases"
maven_public_url: "http://x.x.x.x:8081/repository/maven-public/"
# 获取本次代码新增BUG和新增漏洞的数量,以及获取sonarqube的部署地址
sonarqube_analysis:
sources:
- maven1
targets:
- check_style
type: "fat_squirrel/sonarqube_analysis:v2"
param:
ip: "x.x.x.x:9000"
project_name: "name"
# 目标分支
git_target_branch:
type: "git_clone:1.2.2"
sources:
- start
targets:
- maven2
param:
remote_url: "${trigger.remote_url}"
ref: "refs/heads/${trigger.target_branch}"
password: "((gitlab.password))"
username: "((gitlab.username))"
# 使用代码规范检查工具check-style检查目标分支,生成规范结果文件
maven2:
type: "maven_build:1.3.1-jdk"
sources:
- git_target_branch
targets:
- check_style
param:
mvn_action: "checkstyle:checkstyle-aggregate"
workspace: "${git_target_branch.git_path}"
maven_public_id: "maven-releases"
maven_public_url: "http://172.16.35.15:8081/repository/maven-public/"
# 从共享目录中获取源分支和目标分支的规范结果文件进行比较
check_style:
sources:
- sonarqube_analysis
- maven2
targets:
- condition
type: "jianmu/check_style:v3"
param:
file2: "${git_target_branch.git_path}/target/checkstyle-result.xml"
file1: "${git_source_branch.git_path}/target/checkstyle-result.xml"
# 判断节点,走不同的分支
condition:
sources:
- check_style
type: condition
expression: ${check_style.result}=="1"
cases:
true: qywx_notice
false: condition2
qywx_notice:
type: "qywx_notice:1.2.1"
sources:
- condition
targets:
- git_merge_comment1
param:
mentioned_mobile_list: "[]"
bot_webhook_url: "((chatbot.merge))"
text_content: "项目:${trigger.project_name},提交人:${trigger.user_name},消息:本次提交增加了不符合规范数:${check_style.diff}"
msgtype: "text"
mentioned_list: "[]"
git_merge_comment1:
type: "jianmu/git_merge_comment:v1"
sources:
- qywx_notice
targets:
- end
param:
project_id: "${trigger.project_id}"
host: "${trigger.git_host}"
comment: "action:${trigger.action},项目:${trigger.project_name},提交人:${trigger.user_name},消息:本次合并新增${check_style.diff}个格式问题,新增${sonarqube_analysis.new_bugs}个bug风新增,新增${sonarqube_analysis.new_vulnerabilities}个漏洞问题,详情可见:'${sonarqube_analysis.url}'"
merge_request_iid: "${trigger.iid}"
token: "((AUTOOPS.private_token))"
condition2:
sources:
- condition
type: condition
expression: ${check_style.result}=="0"
cases:
true: qywx_notice2
false: qywx_notice3
qywx_notice2:
type: "qywx_notice:1.2.1"
sources:
- condition2
targets:
- git_merge_comment2
param:
mentioned_mobile_list: "[]"
bot_webhook_url: "((chatbot.merge))"
text_content: "项目:${trigger.project_name},提交人:${trigger.user_name},消息:本次提交不多不少,正正好好!"
msgtype: "text"
mentioned_list: "[]"
git_merge_comment2:
type: "jianmu/git_merge_comment:v1"
sources:
- qywx_notice2
targets:
- end
param:
project_id: "${trigger.project_id}"
host: "${trigger.git_host}"
comment: "action:${trigger.action},项目:${trigger.project_name},提交人:${trigger.user_name},消息:本次合并无新增格式问题,新增${sonarqube_analysis.new_bugs}个bug风新增,新增${sonarqube_analysis.new_vulnerabilities}个漏洞问题,详情可见:'${sonarqube_analysis.url}'"
merge_request_iid: "${trigger.iid}"
token: "((AUTOOPS.private_token))"
qywx_notice3:
type: "qywx_notice:1.2.1"
sources:
- condition2
targets:
- git_merge_comment3
param:
mentioned_mobile_list: "[]"
bot_webhook_url: "((chatbot.merge))"
text_content: "项目:${trigger.project_name},提交人:${trigger.user_name},消息:本次提交减少了不符合规范数:${check_style.diff}"
msgtype: "text"
mentioned_list: "[]"
git_merge_comment3:
type: "jianmu/git_merge_comment:v1"
sources:
- qywx_notice3
targets:
- end
param:
project_id: "${trigger.project_id}"
host: "${trigger.git_host}"
comment: "action:${trigger.action},项目:${trigger.project_name},提交人:${trigger.user_name},消息:本次合并减少${check_style.diff}个格式问题,新增${sonarqube_analysis.new_bugs}个bug风新增,新增${sonarqube_analysis.new_vulnerabilities}个漏洞问题,详情可见:'${sonarqube_analysis.url}'"
merge_request_iid: "${trigger.iid}"
token: "((AUTOOPS.private_token))"
end:
type: end
sources:
- git_merge_comment1
- git_merge_comment2
- git_merge_comment3

DSL编写完以后,总流程它长这样🤩。

image-20220617181421845

  1. 触发流程

从建木中复制触发链接,在Gitlab中配置Merge Request的Webhook,将从建木复制的链接粘贴进去。当有人发起Merge Request时,就会触发流程了。

  1. 结果展示

image-20220617183501975

结尾

在使用建木 + checkstyle + SonarQube以后,工作的效率大大提高了,有更多的时间去完成更有意义的事情,毕竟人生苦短!