Fork me on GitHub
Fork me on GitHub

Jenkins与sonar集成

部门领导要求扫描代码质量,我们平时是用jenkins来做持续集成和持续发布的,所以就将jenkins和sonar做了集成,在编译完成后sonar自动扫描代码,然后在进行发布。

sonar简介

SonarQube 是一个开源的代码分析平台, 用来持续分析和评测项目源代码的质量。 通过SonarQube我们可以检测出项目中重复代码,潜在bug,代码风格问题,缺乏单元测试等问题, 并通过一个web ui展示出来。
这里摆一张从网上搜到的图:

安装配置sonar

新建普通用户sonar

1
2
3
# useradd sonar
# passwd sonar
输入两次密码

下载sonar

下载地址:https://www.sonarqube.org/downloads/
我这里下载的是长期支持版6.7.7。

1
2
3
# su - sonar
# wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-6.7.7.zip
# unzip -oq sonarqube-6.7.7.zip

MySQL中新建sonar数据库

1
2
3
4
# mysql -uroot -p
mysql> create database sonar default charset utf8;
mysql> grant all on sonar.* to sonar@localhost identified by 'sonar'; mysql> grant all on sonar.* to zabbix@'%.%.%.%' identified by 'sonar';
mysql> flush privileges;

修改sonar.properties文件

1
2
3
4
[sonar@res ~]$ cd sonarqube-6.7.7/
[sonar@res sonarqube-6.7.7]$ ls
bin conf COPYING data elasticsearch extensions lib logs temp web
[sonar@res sonarqube-6.7.7]$ vim conf/sonar.properties

启动/停止sonar

1
2
[sonar@res sonarqube-6.7.7]$ bin/linux-x86-64/sonar.sh start
[sonar@res sonarqube-6.7.7]$ bin/linux-x86-64/sonar.sh stop

访问sonar web:http://172.16.7.180:9000
默认账号密码是:admin/admin。登录完成后,建议去修改管理员密码。点击右上角的管理员头像,选择“我的账号”,然后点击“安全”,可以看到修改密码的地方。

sonar配置邮件

使用管理员账号登录sonar web,点击第一行菜单中的“配置”。往下拉,在左侧最下方点击“通用”。在右侧,往下拉会看到可以配置邮件的地方。

sonar添加用户、组

1.添加组
可以针对一个项目添加一个组,把这些人放到这个组里面,然后再配置相应的权限。
使用管理员账号登录sonar web,点击第一行的“配置”,点击“权限”,在下拉菜单中选择“群组”。

然后点击右上方“创建群组”,输入群组名称即可创建群组。此时还没有添加用户,没有用户可以添加到新创建的群组中。

2.添加用户
使用管理员账号登录sonar web,点击第一行的“配置”,点击“权限”,在下拉菜单中选择“用户”。然后点击右上方的“创建用户”。

jenkins安装sonarqube scaner插件

浏览器输入jenkins访问地址,以管理员账户登录后,点击左侧菜单的“系统管理”。然后找到“管理插件”,点击“可选插件”,输入sonarqube scanner,即可搜索到。我这边由于jenkins版本比较低,是2.73.3。最新的sonarqube scanner插件需要jenkins 2.89.4以上版本才可以安装,但是这里又不提供低版本的插件直接安装。查看sonarqube官方文档,有jenkins版本和sonarscanner版本对应关系。

这样就只能先下载好低版本的插件,然后通过“高级”选项卡上传插件进行安装。
我这里下载好了2.6.1版本的sonar.hpi。在插件管理里,选择“高级”选项卡。

往下拉,找到“上传插件”,点击“选择文件”,然后选择本地的sonar.hpi,点击“上传”。过一会儿就装好了。

jenkins构建过程配置sonar

1.配置“SonarQube servers”
在jenkins页面,点击“系统管理”,点击“系统设置”,找到“SonarQube servers”,点击“Add SonarQube”,输入SonarQube的相关信息。

上图中的token,请访问sonar界面,使用管理员账号登录,点击右上角的管理员头像,选择“我的账号”,然后点击“安全”,第一项就是“令牌”。在输入框输入名字,随便定义,然后点击“生成”。

【注意】:请复制生成的token并保存下来,因为后来在进去就看不到了。

2.配置在构建过程中增加sonar扫描
点击某个项目进去,在“构建”处,点击“增加构建步骤”,选择“Execute SonarQube Scanner”,配置如下:

上图中在 Analysis properties 项里配置了一个参数,sonar.projectBaseDir=/root/.jenkins/workspace/gemini_dev。之所以配置这个参数,是因为我这个项目里配置有多个svn地址,每个svn地址都是项目的一个模块,这个情况下SonarQube的sonar.ProjectBaseDir参数默认会被设置为第一个项目的路径。这会导致找不到其他模块。详见官方issue:https://issues.jenkins-ci.org/browse/JENKINS-24044

上图中的 sonar-project.properties 内容大致如下:

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#sonarqube的地址
sonar.host.url=http://172.16.7.180:9000
# SonarQube 中唯一表示,must be unique in a given SonarQube instance
sonar.projectKey=gemini #名字随意
# ui里面显示的项目名称,this is the name displayed in the SonarQube UI
sonar.projectName=gemini #名字随意
#版本号
sonar.projectVersion=1.0 #版本随意
#用户名密码,用token代替
sonar.login=26e7ce1f5cc56a2442b7934b721749bd269f2dcc
#语言
#sonar.language=java,html,css,js #默认是多语言,但是不支持这么写
#源码位置
sonar.modules=eetablecore,eetablemanage,emapflow,emapfunauth,emapsender,emaptaskcenter,emapturing,flowstatistics,skylobby,temppersonnel,getemapapplist,getybtapplist,emapposition,resourcemonitor,serviceanalyseapp
eetablecore.projectBaseDir=/root/.jenkins/workspace/gemini_dev/eetablecore
eetablecore.sonar.projectName=eetablecore
eetablecore.sonar.sources=src,web
eetablecore.sonar.java.binaries=/usr/local/gemini/eetablecore/classes
eetablecore.sonar.exclusions=web/**/*.css,web/**/*.less,web/**/*.scss,web/**/*.min.js
eetablemanage.projectBaseDir=/root/.jenkins/workspace/gemini_dev/eetablemanage
eetablemanage.sonar.projectName=eetablemanage
eetablemanage.sonar.sources=src,web
eetablemanage.sonar.java.binaries=/usr/local/gemini/eetablemanage/classes
eetablemanage.sonar.exclusions=web/**/*.css,web/**/*.less,web/**/*.scss,web/**/*.min.js,web/public/design/plugin/**/*,web/public/design/public/**/*
emapflow.projectBaseDir=/root/.jenkins/workspace/gemini_dev/emapflow
emapflow.sonar.projectName=emapflow
emapflow.sonar.sources=src,web
emapflow.sonar.java.binaries=/usr/local/gemini/emapflow/classes
emapflow.sonar.exclusions=web/**/*.css,web/**/*.less,web/**/*.scss,web/**/*.min.js,src/org/activiti/**/*.java
emapfunauth.projectBaseDir=/root/.jenkins/workspace/gemini_dev/emapfunauth
emapfunauth.sonar.projectName=emapfunauth
emapfunauth.sonar.sources=src,web
emapfunauth.sonar.java.binaries=/usr/local/gemini/emapfunauth/classes
emapfunauth.sonar.exclusions=web/**/*.css,web/**/*.less,web/**/*.scss,web/**/*.min.js
emapsender.projectBaseDir=/root/.jenkins/workspace/gemini_dev/emapsender
emapsender.sonar.projectName=emapsender
emapsender.sonar.sources=src
emapsender.sonar.java.binaries=/usr/local/gemini/emapsender/classes
emaptaskcenter.projectBaseDir=/root/.jenkins/workspace/gemini_dev/emaptaskcenter
emaptaskcenter.sonar.projectName=emaptaskcenter
emaptaskcenter.sonar.sources=src,web
emaptaskcenter.sonar.java.binaries=/usr/local/gemini/emaptaskcenter/classes
emaptaskcenter.sonar.exclusions=web/**/*.css,web/**/*.less,web/**/*.scss,web/**/*.min.js
emapturing.projectBaseDir=/root/.jenkins/workspace/gemini_dev/emapturing
emapturing.sonar.projectName=emapturing
emapturing.sonar.sources=src,web
emapturing.sonar.java.binaries=/usr/local/gemini/emapturing/classes
emapturing.sonar.exclusions=web/**/*.css,web/**/*.less,web/**/*.scss,web/**/*.min.js
flowstatistics.projectBaseDir=/root/.jenkins/workspace/gemini_dev/flowstatistics
flowstatistics.sonar.projectName=flowstatistics
flowstatistics.sonar.sources=src,web
flowstatistics.sonar.java.binaries=/usr/local/gemini/flowstatistics/classes
flowstatistics.sonar.exclusions=web/**/*.css,web/**/*.less,web/**/*.scss,web/**/*.min.js
skylobby.projectBaseDir=/root/.jenkins/workspace/gemini_dev/skylobby
skylobby.sonar.projectName=skylobby
skylobby.sonar.sources=src,web
skylobby.sonar.java.binaries=/usr/local/gemini/skylobby/classes
skylobby.sonar.exclusions=web/**/*.css,web/**/*.less,web/**/*.scss,web/**/*.min.js,web/manager/components/UE/**/*,web/mobile/dependencies/**/*,web/mobile/static/**/*
temppersonnel.projectBaseDir=/root/.jenkins/workspace/gemini_dev/temppersonnel
temppersonnel.sonar.projectName=temppersonnel
temppersonnel.sonar.sources=src,web
temppersonnel.sonar.java.binaries=/usr/local/gemini/temppersonnel/classes
temppersonnel.sonar.exclusions=web/**/*.css,web/**/*.less,web/**/*.scss,web/**/*.min.js
getemapapplist.projectBaseDir=/root/.jenkins/workspace/gemini_dev/getemapapplist
getemapapplist.sonar.projectName=getemapapplist
getemapapplist.sonar.sources=src
getemapapplist.sonar.java.binaries=/usr/local/gemini/getemapapplist/classes
getybtapplist.projectBaseDir=/root/.jenkins/workspace/gemini_dev/getybtapplist
getybtapplist.sonar.projectName=getybtapplist
getybtapplist.sonar.sources=src
getybtapplist.sonar.java.binaries=/usr/local/gemini/getybtapplist/classes
emapposition.projectBaseDir=/root/.jenkins/workspace/gemini_dev/emapposition
emapposition.sonar.projectName=emapposition
emapposition.sonar.sources=src,web
emapposition.sonar.java.binaries=/usr/local/gemini/emapposition/classes
emapposition.sonar.exclusions=web/**/*.css,web/**/*.less,web/**/*.scss,web/**/*.min.js
resourcemonitor.projectBaseDir=/root/.jenkins/workspace/gemini_dev/resourcemonitor
resourcemonitor.sonar.projectName=resourcemonitor
resourcemonitor.sonar.sources=src,web
resourcemonitor.sonar.java.binaries=/usr/local/gemini/resourcemonitor/classes
resourcemonitor.sonar.exclusions=web/**/*.css,web/**/*.less,web/**/*.scss,web/**/*.min.js
serviceanalyseapp.projectBaseDir=/root/.jenkins/workspace/gemini_dev/serviceanalyseapp
serviceanalyseapp.sonar.projectName=serviceanalyseapp
serviceanalyseapp.sonar.sources=src
serviceanalyseapp.sonar.java.binaries=/usr/local/gemini/serviceanalyseapp/classes
#源码的编码
sonar.sourceEncoding=UTF-8

【说明】:
1.以上配置中 src 为java源代码目录,web为前端js目录。
2.新版本的SonarQube scanner的配置文件里扫描java源代码需要提供 java.binaries 定义,我这里对应每个模块建了个文件夹作为值。
3.配置文件可配参数更详细的介绍:
https://baiyangcao.github.io/notes/2017/01/11/sonarqube-analyz-parameter.html
https://docs.sonarqube.org/latest/analysis/analysis-parameters/
https://docs.sonarqube.org/latest/project-administration/narrowing-the-focus/

构建测试并查看结果

在jenkins相应项目上,点击“立即构建”,然后查看“Console Output”:

构建完成后可以登录sonar web界面查看: