xiaodaiwang 2020-02-02
部门领导要求扫描代码质量,我们平时是用jenkins来做持续集成和持续发布的,所以就将jenkins和sonar做了集成,在编译完成后sonar自动扫描代码,然后在进行发布。
SonarQube 是一个开源的代码分析平台, 用来持续分析和评测项目源代码的质量。 通过SonarQube我们可以检测出项目中重复代码,潜在bug,代码风格问题,缺乏单元测试等问题, 并通过一个web ui展示出来。
这里摆一张从网上搜到的图:
123 | # useradd sonar# passwd sonar输入两次密码 |
下载地址:https://www.sonarqube.org/downloads/
我这里下载的是长期支持版6.7.7。
123 | # su - sonar# wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-6.7.7.zip# unzip -oq sonarqube-6.7.7.zip |
1234 | # mysql -uroot -pmysql> create database sonar default charset utf8;mysql> grant all on sonar.* to identified by 'sonar'; mysql> grant all on sonar.* to '%.%.%.%' identified by 'sonar';mysql> flush privileges; |
1234 | [ ~]$ cd sonarqube-6.7.7/[ sonarqube-6.7.7]$ lsbin conf COPYING data elasticsearch extensions lib logs temp web[ sonarqube-6.7.7]$ vim conf/sonar.properties |
12 | [ sonarqube-6.7.7]$ bin/linux-x86-64/sonar.sh start[ sonarqube-6.7.7]$ bin/linux-x86-64/sonar.sh stop |
访问sonar web:http://172.16.7.180:9000
默认账号密码是:admin/admin。登录完成后,建议去修改管理员密码。点击右上角的管理员头像,选择“我的账号”,然后点击“安全”,可以看到修改密码的地方。
使用管理员账号登录sonar web,点击第一行菜单中的“配置”。往下拉,在左侧最下方点击“通用”。在右侧,往下拉会看到可以配置邮件的地方。
1.添加组
可以针对一个项目添加一个组,把这些人放到这个组里面,然后再配置相应的权限。
使用管理员账号登录sonar web,点击第一行的“配置”,点击“权限”,在下拉菜单中选择“群组”。
然后点击右上方“创建群组”,输入群组名称即可创建群组。此时还没有添加用户,没有用户可以添加到新创建的群组中。
2.添加用户
使用管理员账号登录sonar web,点击第一行的“配置”,点击“权限”,在下拉菜单中选择“用户”。然后点击右上方的“创建用户”。
浏览器输入jenkins访问地址,以管理员账户登录后,点击左侧菜单的“系统管理”。然后找到“管理插件”,点击“可选插件”,输入sonarqube scanner,即可搜索到。我这边由于jenkins版本比较低,是2.73.3。最新的sonarqube scanner插件需要jenkins 2.89.4以上版本才可以安装,但是这里又不提供低版本的插件直接安装。查看sonarqube官方文档,有jenkins版本和sonarscanner版本对应关系。
这样就只能先下载好低版本的插件,然后通过“高级”选项卡上传插件进行安装。
我这里下载好了2.6.1版本的sonar.hpi。在插件管理里,选择“高级”选项卡。
往下拉,找到“上传插件”,点击“选择文件”,然后选择本地的sonar.hpi,点击“上传”。过一会儿就装好了。
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 内容大致如下:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950大专栏 Jenkins与sonar集成 class="line">51525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 | #sonarqube的地址sonar.host.url=http://172.16.7.180:9000# SonarQube 中唯一表示,must be unique in a given SonarQube instancesonar.projectKey=gemini #名字随意# ui里面显示的项目名称,this is the name displayed in the SonarQube UIsonar.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,serviceanalyseappeetablecore.projectBaseDir=/root/.jenkins/workspace/gemini_dev/eetablecoreeetablecore.sonar.projectName=eetablecoreeetablecore.sonar.sources=src,webeetablecore.sonar.java.binaries=/usr/local/gemini/eetablecore/classeseetablecore.sonar.exclusions=web/**/*.css,web/**/*.less,web/**/*.scss,web/**/*.min.jseetablemanage.projectBaseDir=/root/.jenkins/workspace/gemini_dev/eetablemanageeetablemanage.sonar.projectName=eetablemanageeetablemanage.sonar.sources=src,webeetablemanage.sonar.java.binaries=/usr/local/gemini/eetablemanage/classeseetablemanage.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/emapflowemapflow.sonar.projectName=emapflowemapflow.sonar.sources=src,webemapflow.sonar.java.binaries=/usr/local/gemini/emapflow/classesemapflow.sonar.exclusions=web/**/*.css,web/**/*.less,web/**/*.scss,web/**/*.min.js,src/org/activiti/**/*.javaemapfunauth.projectBaseDir=/root/.jenkins/workspace/gemini_dev/emapfunauthemapfunauth.sonar.projectName=emapfunauthemapfunauth.sonar.sources=src,webemapfunauth.sonar.java.binaries=/usr/local/gemini/emapfunauth/classesemapfunauth.sonar.exclusions=web/**/*.css,web/**/*.less,web/**/*.scss,web/**/*.min.jsemapsender.projectBaseDir=/root/.jenkins/workspace/gemini_dev/emapsenderemapsender.sonar.projectName=emapsenderemapsender.sonar.sources=srcemapsender.sonar.java.binaries=/usr/local/gemini/emapsender/classesemaptaskcenter.projectBaseDir=/root/.jenkins/workspace/gemini_dev/emaptaskcenteremaptaskcenter.sonar.projectName=emaptaskcenteremaptaskcenter.sonar.sources=src,webemaptaskcenter.sonar.java.binaries=/usr/local/gemini/emaptaskcenter/classesemaptaskcenter.sonar.exclusions=web/**/*.css,web/**/*.less,web/**/*.scss,web/**/*.min.jsemapturing.projectBaseDir=/root/.jenkins/workspace/gemini_dev/emapturingemapturing.sonar.projectName=emapturingemapturing.sonar.sources=src,webemapturing.sonar.java.binaries=/usr/local/gemini/emapturing/classesemapturing.sonar.exclusions=web/**/*.css,web/**/*.less,web/**/*.scss,web/**/*.min.jsflowstatistics.projectBaseDir=/root/.jenkins/workspace/gemini_dev/flowstatisticsflowstatistics.sonar.projectName=flowstatisticsflowstatistics.sonar.sources=src,webflowstatistics.sonar.java.binaries=/usr/local/gemini/flowstatistics/classesflowstatistics.sonar.exclusions=web/**/*.css,web/**/*.less,web/**/*.scss,web/**/*.min.jsskylobby.projectBaseDir=/root/.jenkins/workspace/gemini_dev/skylobbyskylobby.sonar.projectName=skylobbyskylobby.sonar.sources=src,webskylobby.sonar.java.binaries=/usr/local/gemini/skylobby/classesskylobby.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/temppersonneltemppersonnel.sonar.projectName=temppersonneltemppersonnel.sonar.sources=src,webtemppersonnel.sonar.java.binaries=/usr/local/gemini/temppersonnel/classestemppersonnel.sonar.exclusions=web/**/*.css,web/**/*.less,web/**/*.scss,web/**/*.min.jsgetemapapplist.projectBaseDir=/root/.jenkins/workspace/gemini_dev/getemapapplistgetemapapplist.sonar.projectName=getemapapplistgetemapapplist.sonar.sources=srcgetemapapplist.sonar.java.binaries=/usr/local/gemini/getemapapplist/classesgetybtapplist.projectBaseDir=/root/.jenkins/workspace/gemini_dev/getybtapplistgetybtapplist.sonar.projectName=getybtapplistgetybtapplist.sonar.sources=srcgetybtapplist.sonar.java.binaries=/usr/local/gemini/getybtapplist/classesemapposition.projectBaseDir=/root/.jenkins/workspace/gemini_dev/emappositionemapposition.sonar.projectName=emappositionemapposition.sonar.sources=src,webemapposition.sonar.java.binaries=/usr/local/gemini/emapposition/classesemapposition.sonar.exclusions=web/**/*.css,web/**/*.less,web/**/*.scss,web/**/*.min.jsresourcemonitor.projectBaseDir=/root/.jenkins/workspace/gemini_dev/resourcemonitorresourcemonitor.sonar.projectName=resourcemonitorresourcemonitor.sonar.sources=src,webresourcemonitor.sonar.java.binaries=/usr/local/gemini/resourcemonitor/classesresourcemonitor.sonar.exclusions=web/**/*.css,web/**/*.less,web/**/*.scss,web/**/*.min.jsserviceanalyseapp.projectBaseDir=/root/.jenkins/workspace/gemini_dev/serviceanalyseappserviceanalyseapp.sonar.projectName=serviceanalyseappserviceanalyseapp.sonar.sources=srcserviceanalyseapp.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界面查看: