![Jenkins 2.x实践指南](https://wfqqreader-1252317822.image.myqcloud.com/cover/830/25449830/b_25449830.jpg)
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=1739020256-3N171ouTmso7tk2pFISsVMiaj3mAMtjf-0-6f025e3f5093b244239b7069b974400f)
图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=1739020256-mTlercrxxLIwYChS9dpbJieKmLyegELA-0-1321eab6215c771bda64d63524343a07)
执行命令:
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/76_3.jpg?sign=1739020256-QwlkzoOlbgBdCxb3n0Ava6sCf5dybZYU-0-a0648948394c86cb5c47ae11d6790cb0)
sonar.host.url参数用于指定SonarQube服务的地址。
这时,就可以在SonarQube的“Projects”中看到JUnit 4的分析结果,如图5-9所示。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/77_1.jpg?sign=1739020256-cB3aWsoM1HYWqXTVIkuik3YzS003eOLN-0-778068b82ba6da832ded2e6c11bf1851)
图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=1739020256-zreXrHsrgxtmR9jjJAjOYZiczeBPUXib-0-0642d9439b2f8064929549d1d8e3a3fa)
图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=1739020256-oBcTDCt7f1ldmukFrkTAgwgMYavM9Ryy-0-50b5f94b569ea88d025ece5f3cfe7a30)
图5-11 SonarQube生成Token
(3)在执行mvn命令时加入相应的sonar.login参数。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/78_2.jpg?sign=1739020256-PANfcJSs39xfArJOxGEhCdKy0mx1XfH5-0-d4cc5a3f9c1ccb98865f8ab871558496)
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=1739020256-eFwqBb2JOOR8T9W2WOakBROsEVCdlM4y-0-08dc65e32cf8e3353ab2361950e350ca)
图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=1739020256-5pfRhUJCAd2zMjJzLnGz3N5Oue4jXiG8-0-12e95b61604ab854c6c545916477d439)
图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=1739020256-zH76lLKbvV9MisXkB64QF6V0TCXGxHIl-0-42f7c1ce76942bd0f0ca0ac03db5ab0f)
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/80_1.jpg?sign=1739020256-gxQEpgYjC6Vygp8DVKPppcMLZWYwsDS2-0-89909121f043da6114338c3b18a49e1f)
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=1739020256-6Tj8rA8yFJb4gE9AzmiLEBo5kstaodWo-0-4b4e0c428d944901dd8136e6baaae21b)
图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=1739020256-KKzywYs7skL77xWDGzuEuCTGfVlFO3IW-0-45e42fcb68bfcd34347fe67cf5db9dcb)
图5-15 自动安装SonarQube Scanner
也可以取消自动安装,改成手动安装后指定目录,如图5-16所示。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/81_2.jpg?sign=1739020256-0Op3qT3TGk8K24QJ6PLC628BBgSiSI7F-0-2b7e386e56ffbc883e1249063562184b)
图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=1739020256-Du73zZzk9McS8UiAzcptE6nOLqCyj559-0-96b4c2a060dda93b6f16cd7a553d9406)
(3)pipeline部分代码如下:
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/82_2.jpg?sign=1739020256-WrDTY8Hm5tTw1utIOdCMcyktIAfCzwvA-0-37531f2af951e29cfb5a451237dc2174)
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=1739020256-ziPoBDRehBe0z0kH5HEXPyTxYvVlC5Ky-0-6cc4e64ce44677237c56ac7a7141fb29)
图5-17 创建p3c profile
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/83_2.jpg?sign=1739020256-V5DAHBWXpaW9eVw5g7fldwyByLX5ZKzT-0-45264f53e4e40dcd381c9f94067b033e)
图5-18 设置p3c profile为默认
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/83_3.jpg?sign=1739020256-7i6rXnZAVaBvpgq8J2w3G0C1mTE23IgV-0-36894b13d712ac349d13198e4d98b663)
图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=1739020256-4FWHNYTS3czATWt7PquwZMYwYy7z2Q5w-0-24d51ada1650414c6be6498cc23d6735)
图5-20 选择激活更多规则
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/84_2.jpg?sign=1739020256-lAXO7WyTP5yYQQu1DBYzuHF8g148Fkbp-0-3e50e29c8a4c4c3f0ffee14c07adfc5f)
图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=1739020256-PWrJuY4eZjvYd0PDoe0rBwthU5eN3gjv-0-d29d3521727ed9c365903f8b558ad62f)
图5-22 在SonarQube上安装GitLab插件
如果因为网络原因安装失败,则可进行手动安装。
(2)配置SonarQube GitLab插件,如图5-23所示。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/85_1.jpg?sign=1739020256-NT5LpevZyLTSBJG7adjvAbEJszepvThx-0-82a17d6bb6fa2e48c97c054910c09b28)
图5-23 配置SonarQube GitLab插件
配置好SonarQube GitLab插件后,需要为sonar-scanner添加几个参数,以告诉SonarQube将分析结果关联到GitLab的相应commit上。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/85_2.jpg?sign=1739020256-yEiDrxk3hXjlVWgOSRFUrItPH7xMcugl-0-26eb4c5c24fc21106e906d2d41dd80aa)
首先通过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=1739020256-VZMUHc8yjn045N8lu2SRVdjSjBkZqWds-0-1658f0ae68536cb482157e7934aaf782)
图5-24 分析结果
分析结果是显示在行内还是评论区,由SonarQube GitLab插件的配置决定。关于该插件的更多参数本书就不做更多介绍了。