目录
静态代码分析是指在不允许程序的前提下,对源代码进行分析或检查,范围包括代码风格、可能出现的空指针、代码块大小、重复的代码等。
没有通过编译,静态代码分析就没有意义。所以在整个pipeline中,静态代码分析通常被安排在编译阶段之后。非编译型语言就另当别论了。
写代码时大括号该不该换行?对于这样的问题很容易引起争议,如果公司对代码定标准,那符合与否不可能找一个人总盯着,开发组着虽然管理代码合并,也不可能逐行去看检查是否符合标准。
代码检查规范的方案是使用构建工具或者代码分析器进行代码检查,不通过,pipeline就中止。
PMD(https://pmd.github.io)是一款可扩展的静态代码分析器,它不仅可以对代码风格进行检查,还可以检查设计、对线程、性能等方面的问题。
Maven的PMD插件,是我们能在Maven上使用PMD
1.在Maven项目的pom.xml中加入PMD插件
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.8</version>
<configuration>
<rulesets>
<ruleset>rulesets/java/ali-comment.xml</ruleset>
<ruleset>rulesets/java/ali-concurrent.xml</ruleset>
<ruleset>rulesets/java/ali-exception.xml</ruleset>
<ruleset>rulesets/java/ali-flowcontrol.xml</ruleset>
<ruleset>rulesets/java/ali-naming.xml</ruleset>
<ruleset>rulesets/java/ali-oop.xml</ruleset>
<ruleset>rulesets/java/ali-orm.xml</ruleset>
<ruleset>rulesets/java/ali-other.xml</ruleset>
<ruleset>rulesets/java/ali-set.xml</ruleset>
</rulesets>
<printFailingErrors>true</printFailingErrors>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.alibaba.p3c</groupId>
<artifactId>p3c-pmd</artifactId>
<version>1.3.5</version>
</dependency>
</dependencies>
</plugin>
maven-pmd-plugin插件并不会自动使用p3c-pmd,需要在引入dependencies部分手动加入p3c-pmd依赖,然后在rulesets属性中引入p3c的规则。
2.安装Jenkins PMD插件,作用是将PMD报告呈现在任务详情页中。
3.在Jenkkinsfile中加入pmd步骤
pipeline {
agent any
tools {
maven 'mvn-3.5.4'
}
stages {
stage('pmd') {
steps {
sh "mvn pmd:pmd"
}
}
}
post {
always {
pmd(canRunOnFailed: true, pattern: '**/target/pmd.xml')
}
}
}
执行完成后,可以在任务详情页看到PMD报告的链接
单机链接进入报告页面,可以看到更详细的信息
目前每种语言基本都有自己的静态代码分析器,比如JAVA语言,除了PMD外,还有Check-style、FindBugs等。但是没有一款能“大统一”,实现对所有语言和场景的支持。
另外,同一种语言下的不同分析器,他们在功能上既有区别,又有重叠,读者需要根据自己团队的情况进行选择。但是不论选择哪款分析器,所有进行静态代码分析的地方都必须统一分析规则。比如我们决定使用阿里巴巴的开发规范,那Maven插件、IDE插件以及SonarQube都必须使用;否则,分析结果可能会不一致,进而影响分析结果的可信度。
SonarQube是一个代码质量管理工 具,能对20多种编程语言源码进行代码味道( Code Smells)、Bug、 安全漏洞方面的静态分析。SonarQube有4个版本:开源版、开发者版、企业版、数据中心版( Data Center Edition)。
详细的区别,可前往官方网站进行了解,本篇使用的是开源版6.7.5LTS,假设读者已经安装此版本。
为方便起见,我们就不自己写例子了而是直接使用JUnit 4源码来做示例。将JUnit 4从GitHub克隆下来后,在pom.xml中加入SonarQube插件依赖。
<build>
<plugins>
<plugin>
<groupId>org . codehaus . mojo</ groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.4.1.1168< /version>
</plugin>
</plugins>
</build>
执行命令:
mvn clean org.sonarsource.scanner.maven:sonar-maven-plugin:3.4.1.1168:sonar -Dsonar.host.url=http://127.0.0.1:9000
sonar.host.url参数用于指定SonarQube服务的地址。这时,就可以在SonarQube的"Projects" 中看到JUnit 4的分析结果,可以看到JUnit 4有11个Bug。
SonarQube服务默认允许任何人执行源码分析,因此在生产环境中使用会有安全隐患,以下几步可以提高其安全性:
1.设置SonarQube禁此非登录用户使用
2.为用户生成Token,Jenkins只能通过Token与SonarQube集成。登陆SonarQube,进入个人设置页面中的Security tab页
3.在执行mvn命令时加入相应的sonar.login参数
mvn clean package org.sonarsource.scanner.maven:sonar-maven- plugin:3.4.1.1168:sonar -Dsonar.host.url=http://192.168.1.8:9000 -Dsonar.login=e2f92b48d047be825fe3c2c06dec818788855a3e
将Maven与SonarQube集成,这时SonarQube对于Jenkins来说还是透明的,Jenkins并不知道代码质量如何。将集成Jenkins与SonarQube ,以实现当代码质量不合格时, Jenkins pipeline失败。
具体步骤如下:
1.Jenkins安装SonarQube Scanner插件
2.Jenkins配置SonarQube Scanner插件
3.SonarQube设置Webhooks,不同代码规模的源码,分析过程的耗时是不一样的。所以当分析完成时,由SonarQube主动通知Jenkins。设置方法就是进入SonarQube的Adminstration -》Configuration -》 Webhooks页 ,加入http://jenkins地址/sonarqube-webhook 这个接口地址由SonarQube插件提供
4.在Jenkinsfile中加入SonarQube的stage
pipeline {
angent any
tools {
maven ' mvn- -3.5.4
}
stages {
stage( 'Code Analysis') {
steps {
withSonarQubeEnv(' sonarqube') {
sh """
mvn clean package org.sonarsource.scanner.maven:sonar-maven-plugin:3.4.1.1168:sonar \
-Dsonar.host.url=${SONAR_ HOST_ URL} \
-Dsonar.login=${ SONAR_ AUTH_ TOKEN}
"""
}
}
}
stage("Quality Gate" ) {
steps {
timeout(time: 1, unit: 'HOURS') {
waitForQualityGate abortPipeline: true
}
}
}
}
}
withSonarQubeEnv是一个环境变量包装器,读取的是我们所配置的变量。在它的闭包内,我们可以使用以下变量。
waitForQualityGate步骤告诉Jenkins等待SonarQube返回的分析结果。当它的abortPipeline参数为true时,代表当质量不合格,将pipeline的状态设置为UNSTABLE。
我们同时使用了timeout包装器来设置waitForQualityGate步骤的超时时间,避免当网络出问题时, Jenkins任务-直处于等待状态。
5.设置Quality Gates(质量阈值)。 在SonarQube的"Quality Gates"下,我们可以看到系统自带的质量阈值,如图所示。可以看出它是针对新代码的。所以,在初次及没有新代码加入的情况下,执行代码分析是不会报出构建失败的。
使用Maven插件实现代码扫描的,也就是利用构建工具本身提供的插件来实现。在构建I具本身不支持的情况下,我们使用SonarQube本身提供的扫描工具(Scanner )进行代码扫描。
具体步骤如下:
1.在安装SonarQube Scanner插件后,设置扫描工具自动下载并安装(推荐)
也可以取消自动安装, 改成手动安装后指定目录
注意,这里的Name值与图中所设置的值是两码事,此处设置的是SonarScanner工具本身的名称与路径
2.在代码项目根目录下放入sonar-project.properties文件,sonar-scanner会读取其配置,内容如下:
# must be unique in a given SonarQube instance
sonar.projectKey=my:project
# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1.
sonar.projectName=My project
sonar.projectVersion=1.0
# This property is optional if sonar . modules is set.
sonar.sources=.
# Encoding of the source code. Default is default system encoding
#sonar.sourceEncoding=UTF-8
3.pipeline部分代码如下:
script{
def sonarHome = tool name: 'sonarqube3.2.0', type: 'hudson.plugins.sonar.SonarRunnerInstallation'
withSonarQubeEnv('sonar') {
sh "${sonarHome}/bin/sonar-scanner -Dsonar.host.url=${SONAR_HOST_URL} -Dsonar.login=${SONAR_AUTH_TOKEN}"
}
}
必须在所有做代码规范检查的地方使用同一套规范,而SonarQube默认使 用的是它自带的规范( SonarQube称为规则),所以也需要设置SonarQube使用p3c的规范。
有好心的朋友开源了SonarQube的p3cPMD插件,我们可以拿来直接使用。
具体步骤如下:
1.从GitHub下载p3c PMD插件,编译打包
2.将上一步打包好的JAR包放到SonarQube所在服务器的<SonarQube的home目录>/extensions/plugins
目录下
3.SonarQube:创建p3c profile,单击SonarQube顶部的"Quality Profiles",然后单击面右上角的"Create"按钮,输入新profile名称,选择Java语言。
4.SonarQube在profile列表中找到刚刚创建的p3c profile,单击其最右边的下三角按钮,选择"Set as Default"
5.创建成功
6.SonarQube为p3c profile激活p3c规则,新创建的profile是没有激活任何规则的,需要手动激活。单击下三角按钮,选择“Activate More Rules”
7.跳转到激活页面,激活所有的p3c规则,这样当SonarQube分析Java代码时,就会使用p3c规则了。
如果希望对每一次代码的commit都进行分析,并将分析结果与该commit关联起来,那么SonarQube的GitLab插件就是一个不错的选择。SonarQube Gitlab插件的功能就是将SonarQube的分析结果推送到GitLab。
1.在SonarQube上安装GitLab插件(https:/github.com/gabrie-allaigre/sonar-gitlab-plugin)如果因为网络原因安装失败,则可进行手动安装。
2.配置SonarQube GitLab插件
配置好SonarQube GitLab插件后,需要为sonar-scanner添加几个参数,以告诉SonarQube将分析结果关联到GitLab的相应commit上。
script{
def sonarHome = tool name: 'sonarqube3.2.0', type: 'hudson.plugins.sonar.SonarRunnerInstallation'
def GIT_COMMIT_ID = sh(
script: "git rev-parse --short=10 HEAD",
returnStdout: true
)
sh "${sonarHome}/bin/sonar-scanner -Dsonar.host.url=${SONAR_HOST_URL} -Dsonar.analysis.mode=preview -Dsonar.gitlab.ref_name=master -Dsonar.gitlab.project_ id=jenkins-book/sonarqube -Dsonar.projectName=jenkins-book -Dsonar.gitlab.commit_sha=${GIT_COMMIT_ID} -Dsonar.login=${SONAR_AUTH_TOKEN}"
}
首先通过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评论区看到分析结果了
分析结果是显示在行内还是评论区,由SonarQube GitLab插件的配置决定。
是不是觉得JUnit输出的测试报告不美观。不只是JUnit ,很多其他编程语言的测试框架的测试报告也差不多。Allure测试报告是一个框架,能将各种测试报告更美观地呈现出来。
接下来,我们将Allure、Maven、Jenkins集成。 Allure与其他编程语言及构建工具的集成与此类似。
具体步骤如下:
1.安装Allure Jenkins插件,进入Jenkins的Manage Jenkins ——》Global Tool Configuration-》Allure Commandline页,配置Allure自动下载并安装的版本
2.在pom.xml文件中加入依赖
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-junit4</artifactId>
<version>2.0-BETA13</version>
</dependency>
3.在pom.xml文件中加入Allure插件
<p1ugin>
<groupId>org.apache.maven.plugins</ groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<argLine>
- javaagent:" ${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
</argLine>
<properties>
<property>
<name>listener</name>
<value>io.qameta.allure.junit4.AllureJunit4</value>
</property>
</properties>
<systemProperties>
<property>
<name>allure.results.directory</name>
<value>${project.build.directory}/allure- results</value>
</property>
<property>
<name>allure.link.issue.pattern</name>
<value>https://example.org/issue/{}</value>
</property>
</systemProperties>
</configuration>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-maven</artifactId>
<version>2.8</version>
</plugin>
4.在jenkinsfile中的post阶段加入allure步骤
script {
allure([
includeProperties: false,
jdk:
properties:[],
reportBuildPolicy:' ALWAYS',
results: [[path: 'target/allure-results']]
])
}
构建完成后,可以看到在构建历史记录中出现了Allure的logo,单击就可以进入优美的测试报告页面了
手机扫一扫
移动阅读更方便
你可能感兴趣的文章