- Jenkins 2.x实践指南
- 翟志军编著
- 2084字
- 2020-08-28 00:01:34
5.4 SonarQube:持续代码质量检查
SonarQube是一个代码质量管理工具,能对20多种编程语言源码进行代码味道(Code Smells)、Bug、安全漏洞方面的静态分析。SonarQube有4个版本:开源版、开发者版、企业版、数据中心版(Data Center Edition)。各版本之间的关键区别如图5-8所示。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/76_1.jpg?sign=1739506811-dorFod5dJ7kOjxUCdbbtzTcMWLkKKyII-0-9c7367824d2f40a3b088b00e18a055c6)
图5-8 SonarQube各版本之间的区别
关于更详细的区别,可前往官方网站(https://www.sonarsource.com/plans-and-pricing/)进行了解。本书使用的是开源版6.7.5 LTS,假设读者已经安装此版本。
5.4.1 Maven与SonarQube集成
为方便起见,我们就不自己写例子了,而是直接使用JUnit 4源码来做示例。将JUnit 4从GitHub克隆下来后,在pom.xml中加入SonarQube插件依赖。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/76_2.jpg?sign=1739506811-FAudLCtGKq1NU2rFF26jEy8Nr4FnibaN-0-6b8edaa5f23aeb37dbe18c55782be8db)
执行命令:
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/76_3.jpg?sign=1739506811-5J0KY0SJJKC4WZP945S1hdeB1fTrtWhx-0-071da26726f4e28fc7c9a0da3095368f)
sonar.host.url参数用于指定SonarQube服务的地址。
这时,就可以在SonarQube的“Projects”中看到JUnit 4的分析结果,如图5-9所示。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/77_1.jpg?sign=1739506811-ztsQ1MR4wBbZXxkyXXmfdHd8JQzpprOX-0-44281bfaf40807457008a6881b2f12aa)
图5-9 JUnit 4的分析结果
可以看到JUnit 4有11个Bug。
SonarQube服务默认允许任何人执行源码分析,因此在生产环境中使用会有安全隐患。以下几步可以提高其安全性:
(1)设置SonarQube禁止非登录用户使用,如图5-10所示。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/77_2.jpg?sign=1739506811-eEuNjqPHlyj9jODRIbhmtAcv3PaqtDPz-0-475d34c395a6a00dbca25c095e6f0cb3)
图5-10 禁止非登录用户使用SonarQube
(2)为用户生成Token,Jenkins只能通过Token与SonarQube集成。登录SonarQube,进入个人设置页面中的Security tab页,如图5-11所示。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/78_1.jpg?sign=1739506811-9OEAs6vvKkMsstoIRashKfJ1JIi1Lxqi-0-8acbfce32fbab7b575783d817294aa3b)
图5-11 SonarQube生成Token
(3)在执行mvn命令时加入相应的sonar.login参数。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/78_2.jpg?sign=1739506811-OwMVajcK3imVjVV1umYAO16EG5Si2S2S-0-710317ccef571b4319bae5166a9e6ddd)
5.4.2 Jenkins与SonarQube集成
在上一节中,我们将Maven与SonarQube集成。这时,SonarQube对于Jenkins来说还是透明的,Jenkins并不知道代码质量如何。本节我们将集成Jenkins与SonarQube,以实现当代码质量不合格时,Jenkins pipeline失败。
具体步骤如下:
(1)Jenkins:安装SonarQube Scanner插件(https://plugins.jenkins.io/sonar),本书使用的版本是2.8。
(2)Jenkins:配置SonarQube Scanner插件,如图5-12所示。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/79_1.jpg?sign=1739506811-6Q5bZfVboirDresfiwvRJ6Mu5Q6ZgC87-0-3e51fa8d494ebd0361f180e3247aa81b)
图5-12 配置SonarQube Scanner插件
(3)SonarQube:设置Webhooks。不同代码规模的源码,分析过程的耗时是不一样的。所以,当分析完成时,由SonarQube主动通知Jenkins。设置方法就是进入SonarQube的Adminstration→Configuration→Webhooks页,加入<Jenkins的地址>/sonarqube-webhook/,如图5-13所示。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/79_2.jpg?sign=1739506811-jZVw5yT9dD2d0ceYSIIYV6NQAM6gJ56o-0-d1a10611630395486acda0197c5ad58f)
图5-13 SonarQube新建Webhooks
<Jenkins的地址>/sonarqube-webhook/接口由Jenkins SonarQube插件提供。
(4)在Jenkinsfile中加入SonarQube的stage。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/79_3.jpg?sign=1739506811-z73r13w22UuMBDawYSrOoHU604GEGYmd-0-45ccf78603e45f376eabbef98bb68837)
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/80_1.jpg?sign=1739506811-FMacGyBUUg7uz9wS7oGosh6IHwJ6EnBI-0-480a6c72ed2727634e61bbd6777ab478)
withSonarQubeEnv是一个环境变量包装器,读取的是我们在图5-12中所配置的变量。在它的闭包内,我们可以使用以下变量。
• SONAR_HOST_URL:SonarQube服务的地址。
• SONAR_AUTH_TOKEN:SonarQube认证所需要的Token。
waitForQualityGate 步骤告诉 Jenkins 等待 SonarQube 返回的分析结果。当它的abortPipeline参数为true时,代表当质量不合格时,将pipeline的状态设置为UNSTABLE。
我们同时使用了timeout包装器来设置waitForQualityGate步骤的超时时间,避免当网络出问题时,Jenkins任务一直处于等待状态。
(5)设置Quality Gates(质量阈值)。在SonarQube的“Quality Gates”下,我们可以看到系统自带的质量阈值,如图5-14所示。可以看出它是针对新代码的。所以,在初次及没有新代码加入的情况下,执行代码分析是不会报出构建失败的。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/80_2.jpg?sign=1739506811-17SEnNKMBf5i6GfnrsVRzGoD2r5t7uXj-0-ab7d55634b5fffc7b3893cab9b1358ef)
图5-14 设置质量阈值
5.4.3 使用SonarQube Scanner实现代码扫描
上文中,我们是使用Maven插件实现代码扫描的,也就是利用构建工具本身提供的插件来实现。在构建工具本身不支持的情况下,我们使用SonarQube本身提供的扫描工具(Scanner)进行代码扫描。
具体步骤如下:
(1)在安装SonarQube Scanner插件后,设置扫描工具自动下载并安装(推荐),如图5-15所示。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/81_1.jpg?sign=1739506811-3i8sHz9kXvffvWDCz50BP0jE5Y9VNFBX-0-9180c47cf8e9bf7d0818d3318670c5d3)
图5-15 自动安装SonarQube Scanner
也可以取消自动安装,改成手动安装后指定目录,如图5-16所示。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/81_2.jpg?sign=1739506811-K8yris2hwRV0U8T1NivFINsV5ECK8U4v-0-9c8f1f586b18b5d589f2d3f8c811424b)
图5-16 手动指定SonarQube Scanner的安装路径
请注意,这里的Name值与图5-12中所设置的值是两码事。此处设置的是SonarScanner工具本身的名称与路径。
(2)在代码项目根目录下放入sonar-project.properties文件,sonar-scanner会读取其配置,内容如下:
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/82_1.jpg?sign=1739506811-dK9MZuJIw8Ck8IV6bA0Fix6hYlAjNBH5-0-6f28597e287312878c86ecb4afd325db)
(3)pipeline部分代码如下:
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/82_2.jpg?sign=1739506811-w4jHR6NAV6GEEqbXZngLDomSGmjHmqIk-0-2505db0279a087ff85964e3bd128c57b)
5.4.4 SonarQube集成p3c
前文中,我们已经交待,必须在所有做代码规范检查的地方使用同一套规范。而SonarQube默认使用的是它自带的规范(SonarQube称为规则),所以也需要设置SonarQube使用p3c的规范。
有好心的朋友开源了SonarQube的p3c PMD插件(https://github.com/mrprince/sonar-p3c-pmd),我们可以拿来直接使用。
具体步骤如下:
(1)从GitHub下载p3c PMD插件,编译打包。
(2)将上一步打包好的JAR包放到SonarQube所在服务器的<SonarQube的home目录>/ext ensions/plugins目录下。
(3)SonarQube:创建p3c profile。单击SonarQube顶部的“Quality Profiles”,然后单击页面右上角的“Create”按钮,输入新profile名称,选择Java语言,如图5-17所示。
(4)SonarQube:在profile列表中找到刚刚创建的p3c profile,单击其最右边的下三角按钮,选择“Set as Default”,如图5-18所示。
创建p3c profile成功,如图5-19所示。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/83_1.jpg?sign=1739506811-AfnhkjkAJw9bJoMhoUaOCadvfMUQwwl5-0-5f4f2c4d06a6fa02383bdc4072a9cfd3)
图5-17 创建p3c profile
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/83_2.jpg?sign=1739506811-ozhXzQjO1owY0BOEu8ML9L5VXlKaxM3M-0-f780dd388324df4ba20cdf39b9676e62)
图5-18 设置p3c profile为默认
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/83_3.jpg?sign=1739506811-0CvZCgdMjSjnUrMgU5wgOFL14E4wNSb0-0-23d54a104fe44d958a4fea8302ac574a)
图5-19 创建p3c profile成功
(5)SonarQube:为p3c profile激活p3c规则。新创建的profile是没有激活任何规则的,需要手动激活。单击下三角按钮,选择“Activate More Rules”,如图5-20所示。
(6)跳转到激活页面,激活所有的p3c规则,如图5-21所示。
这样,当SonarQube分析Java代码时,就会使用p3c规则了。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/84_1.jpg?sign=1739506811-pn389a5YFTViNPWb9oMYyqmkGjLx5STa-0-3e76abfabfaaba32b4aa2254dd1e2e05)
图5-20 选择激活更多规则
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/84_2.jpg?sign=1739506811-opaispk1HthE9TulPZjikn1BfZLbjlNF-0-7f621e4338aec393733152857d400a1a)
图5-21 激活规则页面
5.4.5 将分析报告推送到GitLab
如果希望对每一次代码的commit都进行分析,并将分析结果与该commit关联起来,那么SonarQube的GitLab插件就是一个不错的选择。SonarQube GitLab插件的功能就是将SonarQube的分析结果推送到GitLab。
(1)在SonarQube上安装GitLab插件(https://github.com/gabrie-allaigre/sonar-gitlab-plugin),如图5-22所示。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/84_3.jpg?sign=1739506811-MTgHWabbb4cvOe9u5C5xXG6u0IHJ3hwn-0-34d418f0af5b39163f5a2930ef9df00d)
图5-22 在SonarQube上安装GitLab插件
如果因为网络原因安装失败,则可进行手动安装。
(2)配置SonarQube GitLab插件,如图5-23所示。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/85_1.jpg?sign=1739506811-XxJIiiHHeBlNxvfKhPCp0H9UhruqAkQU-0-80231526e4245669e8c329f60c7fc63c)
图5-23 配置SonarQube GitLab插件
配置好SonarQube GitLab插件后,需要为sonar-scanner添加几个参数,以告诉SonarQube将分析结果关联到GitLab的相应commit上。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/85_2.jpg?sign=1739506811-uVisFSoVoB2KoTBYzTnM1iUjSFl9l5kP-0-682d2b847d45ff7f916e1c6acd55dac5)
首先通过sh步骤获取代码的commit ID,然后在执行扫描时加入如下参数。
•-Dsonar.analysis.mode:分析报告模式,值为preview,代表将结果推送到GitLab。此参数虽然官方标注SonarQube 6.6后被废弃,但是笔者使用6.7版本依然需要加上它。
•-Dsonar.gitlab.ref_name:分支名称。
•-Dsonar.gitlab.project_id:GitLab对应的项目路径。
•-Dsonar.projectName:对应SonarQube上的项目名称。
•-Dsonar.gitlab.commit_sha:代码的commit ID。
当SonarQube分析完成后,我们就可以在GitLab的相应commit页面上的代码行内或commit评论区看到分析结果了,如图5-24所示。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/86_1.jpg?sign=1739506811-ECVNIuUyzMeEkCjih3empst41uuJuB0c-0-75670dc72f0a0deac9173672a96bc09a)
图5-24 分析结果
分析结果是显示在行内还是评论区,由SonarQube GitLab插件的配置决定。关于该插件的更多参数本书就不做更多介绍了。