Jenkins 2.x实践指南
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

5.4 SonarQube:持续代码质量检查

SonarQube是一个代码质量管理工具,能对20多种编程语言源码进行代码味道(Code Smells)、Bug、安全漏洞方面的静态分析。SonarQube有4个版本:开源版、开发者版、企业版、数据中心版(Data Center Edition)。各版本之间的关键区别如图5-8所示。

图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插件依赖。

执行命令:

sonar.host.url参数用于指定SonarQube服务的地址。

这时,就可以在SonarQube的“Projects”中看到JUnit 4的分析结果,如图5-9所示。

图5-9 JUnit 4的分析结果

可以看到JUnit 4有11个Bug。

SonarQube服务默认允许任何人执行源码分析,因此在生产环境中使用会有安全隐患。以下几步可以提高其安全性:

(1)设置SonarQube禁止非登录用户使用,如图5-10所示。

图5-10 禁止非登录用户使用SonarQube

(2)为用户生成Token,Jenkins只能通过Token与SonarQube集成。登录SonarQube,进入个人设置页面中的Security tab页,如图5-11所示。

图5-11 SonarQube生成Token

(3)在执行mvn命令时加入相应的sonar.login参数。

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所示。

图5-12 配置SonarQube Scanner插件

(3)SonarQube:设置Webhooks。不同代码规模的源码,分析过程的耗时是不一样的。所以,当分析完成时,由SonarQube主动通知Jenkins。设置方法就是进入SonarQube的Adminstration→Configuration→Webhooks页,加入<Jenkins的地址>/sonarqube-webhook/,如图5-13所示。

图5-13 SonarQube新建Webhooks

<Jenkins的地址>/sonarqube-webhook/接口由Jenkins SonarQube插件提供。

(4)在Jenkinsfile中加入SonarQube的stage。

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所示。可以看出它是针对新代码的。所以,在初次及没有新代码加入的情况下,执行代码分析是不会报出构建失败的。

图5-14 设置质量阈值

5.4.3 使用SonarQube Scanner实现代码扫描

上文中,我们是使用Maven插件实现代码扫描的,也就是利用构建工具本身提供的插件来实现。在构建工具本身不支持的情况下,我们使用SonarQube本身提供的扫描工具(Scanner)进行代码扫描。

具体步骤如下:

(1)在安装SonarQube Scanner插件后,设置扫描工具自动下载并安装(推荐),如图5-15所示。

图5-15 自动安装SonarQube Scanner

也可以取消自动安装,改成手动安装后指定目录,如图5-16所示。

图5-16 手动指定SonarQube Scanner的安装路径

请注意,这里的Name值与图5-12中所设置的值是两码事。此处设置的是SonarScanner工具本身的名称与路径。

(2)在代码项目根目录下放入sonar-project.properties文件,sonar-scanner会读取其配置,内容如下:

(3)pipeline部分代码如下:

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所示。

图5-17 创建p3c profile

图5-18 设置p3c profile为默认

图5-19 创建p3c profile成功

(5)SonarQube:为p3c profile激活p3c规则。新创建的profile是没有激活任何规则的,需要手动激活。单击下三角按钮,选择“Activate More Rules”,如图5-20所示。

(6)跳转到激活页面,激活所有的p3c规则,如图5-21所示。

这样,当SonarQube分析Java代码时,就会使用p3c规则了。

图5-20 选择激活更多规则

图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所示。

图5-22 在SonarQube上安装GitLab插件

如果因为网络原因安装失败,则可进行手动安装。

(2)配置SonarQube GitLab插件,如图5-23所示。

图5-23 配置SonarQube GitLab插件

配置好SonarQube GitLab插件后,需要为sonar-scanner添加几个参数,以告诉SonarQube将分析结果关联到GitLab的相应commit上。

首先通过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所示。

图5-24 分析结果

分析结果是显示在行内还是评论区,由SonarQube GitLab插件的配置决定。关于该插件的更多参数本书就不做更多介绍了。