背景
项目组出过几次NPE事故,为保障代码健壮性, 提高项目稳定性, 在项目中引入findbugs插件, 进行静态代码检查.
任务目标
- Jenkins CI过程中, 引入静态代码检查, 生成检查报告
- 引入bug模板, 实现检查内容可配置
- 代码检查发现bug时, 阻断maven构建流程, 发送邮件告警
实施过程
引入maven插件findbugs-maven-plugin
注意点:
- 与pipeline配合, 在install阶段再报错, 让pipeline在compile阶段生成报告
- 配置includeFilterFile, 自定义bug检查类型
- 一些反向工程的代码可以配置
节点, 不做bug检查 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>3.0.5</version>
<configuration>
<failOnError>true</failOnError>
<findbugsXmlOutput>true</findbugsXmlOutput>
<xmlOutput>true</xmlOutput>
<includeFilterFile>${basedir}/src/main/resources/findbugs-include.xml</includeFilterFile>
</configuration>
<executions>
<execution>
<id>failOnError</id>
<phase>install</phase>
<goals>
<goal>check</goal>
</goals>
<configuration>
<effort>Max</effort>
<threshold>High</threshold>
<failOnError>true</failOnError>
</configuration>
</execution>
</executions>
</plugin>
注意点:
配置不需要检查的模块
1 | <plugin> |
自定义bug检查类型. findbugs-include.xml
注意:
- 当前阶段, 只配置了NP RCN两个, 大家可以根据需要配置对应目录/类和检查类型. (bug code/pattern 参考)
- 相应的, 如果有不想检查的目录/类, 可以配置findbugs-exclude.xml, 道理与findbugs-include.xml相同
1
2
3
4
5
6
7
<FindBugsFilter>
<Match>
<Package name="~com\.xxxxx\.xxxx\.xxxx\.author.*"/>
<Bug code="NP,RCN"/>
</Match>
</FindBugsFilter>
jenkins pipeline
重点内容:
- 新增stage Verify, 在compile后执行findbugs, 在此stage中生成报告
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56pipeline {
agent {
node {
label 'maven-jdk1.8'
}
}
stages {
stage('Verify'){
steps {
sh 'mvn -B -U clean compile findbugs:findbugs'
findbugs(pattern: '**/target/findbugsXml.xml')
}
}
stage('Build') {
steps {
sh 'mvn -B -U clean install'
}
}
}
post {
failure {
script {
def changeStr = getChangeString()
emailext body:
"""Job '${env.JOB_NAME}:${env.BUILD_NUMBER}\' 失败!\n
commit记录:
${changeStr}
点击进入Jenkins查看详情: ${env.BUILD_URL}""",
compressLog: true,
attachLog: true,
subject:"构建失败: ${env.JOB_NAME}:${env.BUILD_NUMBER}",
to:"alarmemail@xxxx.com"
}
}
}
triggers {
cron('H H/2 * * *')
gitlab(triggerOnPush: true, triggerOnMergeRequest: true, branchFilterType: 'All')
}
}
def getChangeString() {
def changeString = ""
def changeLogSets = currentBuild.changeSets
for (int i = 0; i < changeLogSets.size(); i++) {
def entries = changeLogSets[i].items
for (int j = 0; j < entries.length; j++) {
def entry = entries[j]
changeString += "-- "+"${entry.commitId} by ${entry.author} on ${new Date(entry.timestamp).format('yyyy-MM-dd HH:mm:ss')} ${entry.msg}"+"\n"
}
}
if (!changeString) {
changeString = "-- 无"
}
return changeString
}
成果展示




参考文档:
http://findbugs.sourceforge.net/manual/index.html
https://stackoverflow.com/questions/38632682/maven-execute-a-goal-on-build-fail-findbugs