- 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=1739343360-jPNRsvXmCSWijrwx6CRm7GE8xsoJyEOA-0-a3a867721a4827ec92106c1b88a9129e)
图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=1739343360-F2pzxuWLhEr8r9ZmEF7Kdw8eWr56OlQ5-0-ec829fa250fb7f7990f792c0cc9c8322)
执行命令:
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/76_3.jpg?sign=1739343360-va11AMAdXU0RfmqvIR6fSrqcYrhwc4Yd-0-3f0011aa192141a204a8bba831781f4e)
sonar.host.url参数用于指定SonarQube服务的地址。
这时,就可以在SonarQube的“Projects”中看到JUnit 4的分析结果,如图5-9所示。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/77_1.jpg?sign=1739343360-D30tKINFN6W1j3XeZwTxaCvpQ7MSEUro-0-f5d45d1a00512628cd041aad87407240)
图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=1739343360-UCTpZU5p5wtGemeqLz4hpwrExd83B3NO-0-0b10a5d1c30b4e8e3c0d6acff6c51f5b)
图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=1739343360-xfVPHE3UAJlYBg0uxdl37FIElIzIJ8Ty-0-84e6ed0c6bd1b8ba2669306761841c7d)
图5-11 SonarQube生成Token
(3)在执行mvn命令时加入相应的sonar.login参数。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/78_2.jpg?sign=1739343360-DUqwxuTD8TA89spXUePdoX7MGhCx5SuD-0-d4a7d5fcdd29a0acd167d1726d220f24)
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=1739343360-CdVtWbk6zcOeFGkYoBipyFPtPEHrgEib-0-00856184a5be2d0584b36f784b91a896)
图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=1739343360-uboRdeHw3QGN6mxbeb7yhcHHyYWCHVuc-0-3f250a5af97517e4c5d9f44258a1ad5b)
图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=1739343360-z9AutZoqgvuuTBUX9bDxPHe2E047TEOc-0-6a6f47cebab154ec1c1cb55a004c29b1)
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/80_1.jpg?sign=1739343360-XziKLrvuErnZ8EKQHP7VYWmzsQ7P7GsA-0-d34aff7a85805a37d3b5903c4f5718a2)
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=1739343360-WQubkdGUGHHTs1uNiO4ZkYhuaP5MlWqY-0-d2b3f961f9b6cbe9a07368a166f3f85f)
图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=1739343360-kI09fRDUNZPGQPLbMicdtkK8mcwKgNSw-0-14d923db4d66b49a7dd9b645526db75a)
图5-15 自动安装SonarQube Scanner
也可以取消自动安装,改成手动安装后指定目录,如图5-16所示。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/81_2.jpg?sign=1739343360-uBbkubPSx88FPcKbBdxMvbgBNYLZd1ns-0-827388443fdab344a834720d4df64742)
图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=1739343360-sYr0rmModTqZcZNGMbjjWwbQCa4jwVTd-0-6c5cc3cd609212c5f246ec29d9084e53)
(3)pipeline部分代码如下:
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/82_2.jpg?sign=1739343360-6hNmu4vkgHBIiOFd0zLwqWhkbU8HA9lc-0-d7e3d5126a17ae5c1933c27b1a49c020)
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=1739343360-sY8uCww7mfzNT0IUx4uNePFHI6fJsrTU-0-b7a0ca5bcafe80bf6bf049966eb8d82b)
图5-17 创建p3c profile
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/83_2.jpg?sign=1739343360-UTUYV0W1eWavlGKmdUkCS3AJvcy49utp-0-31d0625bb8e8e56cef148982ee6449a1)
图5-18 设置p3c profile为默认
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/83_3.jpg?sign=1739343360-LiD3QEClkJyjOmDfnD0PVqhHjXh2b0VC-0-0cbe958769581197b5659ebdc98fd4fc)
图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=1739343360-nLKJBhxkbdwV0erjW9XBcpHzePz0MfYV-0-64244791b34839d3cc16399239592678)
图5-20 选择激活更多规则
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/84_2.jpg?sign=1739343360-6DQ6qEwxEL6RmKoTlNMA6OgqTXLMAy9Z-0-1db8d95ee5f1785428661a58d99ebfd6)
图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=1739343360-1J4AgPF61rJFNAyTGAbok9xRgvdG2XYV-0-ed0ba2e841f775e4d50e5925a92ec657)
图5-22 在SonarQube上安装GitLab插件
如果因为网络原因安装失败,则可进行手动安装。
(2)配置SonarQube GitLab插件,如图5-23所示。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/85_1.jpg?sign=1739343360-nIrL7kVuIJfUXGyEql19BtauM7qpuDWe-0-8163559f16819a0ddec6ad9629b3e0c7)
图5-23 配置SonarQube GitLab插件
配置好SonarQube GitLab插件后,需要为sonar-scanner添加几个参数,以告诉SonarQube将分析结果关联到GitLab的相应commit上。
![](https://epubservercos.yuewen.com/29EDEB/13898202705417506/epubprivate/OEBPS/Images/85_2.jpg?sign=1739343360-bElCneQRvhV9XiaUPmMgafrTc2TvgMxd-0-669aff7fcc0a62ed259924f2d9ad9fca)
首先通过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=1739343360-9Uf4gIuE4WVcRPd9jNMjuXwELpVMsvLJ-0-db2b60732e501cd86295d744ae3815a5)
图5-24 分析结果
分析结果是显示在行内还是评论区,由SonarQube GitLab插件的配置决定。关于该插件的更多参数本书就不做更多介绍了。