这些配置项都是统一的,目前sonar支持将扫描参数以文件的方式存放或者以命令行传参的方式读取。
文件方式:可以将扫描参数放到项目的根目录或者sonar-scanner的配置文件目录等自定义的目录中;
命令行传参则可以直接将变量传递给sonarsacnner cli -Dsonar.projectKey=xxx 。
==方法2:命令行方式读取扫描参数==(命令行方式会覆盖掉配置文件方式的)
# 指定配置文件sonar-scanner-Dproject.settings=myproject.properties# 命令行传参sonar-scanner-Dsonar.projectKey=myproject-Dsonar.sources=src1
1.Java项目扫描
sonarqube服务器端需要安装Java语言规则插件
sonar-scanner-Dsonar.host.url=http:-Dsonar.projectKey=devops-maven-service \-Dsonar.projectName=devops-maven-service \-Dsonar.projectVersion=1.1 \-Dsonar.login=admin \-Dsonar.password=admin123 \-Dsonar.ws.timeout=30 \-Dsonar.projectDescription="my first project!"\-Dsonar.links.homepage=http:-Dsonar.links.ci=http:-Dsonar.sources=src \-Dsonar.sourceEncoding=UTF-8 \-Dsonar.java.binaries=target/classes \-Dsonar.java.test.binaries=target/test-classes \-Dsonar.java.surefire.report=target/surefire-reports
`sonar.projectKey` 指定项目的关键字`sonar.host.url`指定服务器地址(可以直接在配置文件中写死),`projectName`指定项目的名称, `projectVersion`指定项目的版本(可以用构建时间和构建ID定义),`login`指定登录用户名,`password`指定登录用户密码,`projectDescription`指定项目的描述信息, `links.homepage`指定项目的主页(超链接),`sources`指定扫描的目录, `sourceEncoding`指定扫描时的编码, `java.binaries`指定编译后的类文件目录(必填), `java.test.binaries`指定编译后的测试类目录,`java.surefire.report`指定测试报告目录。
💘 实践:Scanner进行项目代码扫描(测试成功)-2023.6.24 |
- 实验环境
sonarqube:9.9.0-community(docker方式部署)SonarScanner4.8.0.2856(部署在宿主机上)
实验软件(无)
手动扫描代码
在devops6-maven-service
项目里创建sonar-project.properties
文件:
# 定义唯一的关键字sonar.projectKey=devops6-maven-service# 定义项目名称sonar.projectName=devops6-maven-service# 定义项目的版本信息sonar.projectVersion=1.0# 指定扫描代码的目录位置(多个逗号分隔)sonar.sources=.# 执行项目编码sonar.sourceEncoding=UTF-8# 指定sonar Serversonar.host.url=http:# 认证信息sonar.login=adminsonar.password=Admin@123# java classessonar.java.binaries=target/classessonar.java.test.binaries=target/test-classessonar.java.surefire.report=target/surefire-reports
提交。
- 在本地
devops6-maven-service
本地项目里,拉取代码,然后扫描
#拉取代码[root@Devops6 devops6-maven-service]#pwd/data/devops6/devops6-maven-service[root@Devops6 devops6-maven-service]#lsmvnwmvnw.cmdpom.xmlsrctarget[root@Devops6 devops6-maven-service]#git pull[root@Devops6 devops6-maven-service]#lsmvnwmvnw.cmdpom.xmlsonar-project.propertiessrctarget#删除之前的打包好的缓存数据[root@Devops6 devops6-maven-service]#rm -rf target/#打包[root@Devops6 devops6-maven-service]#mvn clean package#扫描[root@Devops6 devops6-maven-service]#sonar-scanner
- 查看扫描报告
测试结束。😘
💘 实践:Scanner进行项目代码扫描(测试成功)-2022.5.24 |
自己实际测试过程:
- 克隆
devops4-maven-service
项目代码到sonarscanner机器:
[root@devops ~]#mkdir sonarProject[root@devops ~]#cd sonarProject/[root@devops sonarProject]#git clone http:Cloninginto'devops4-maven-service'...Usernamefor'http:Passwordfor'http:remote:Enumeratingobjects:52,done.remote:Countingobjects:100%(18/18),done.remote:Compressingobjects:100%(18/18),done.remote:Total52(delta 9),reused 0 (delta0),pack-reused 34Receivingobjects:100%(52/52),56.33 KiB |28.16MiB/s,done.Resolvingdeltas:100%(11/11),done.[root@devops sonarProject]#lsdevops4-maven-service[root@devops sonarProject]#cd devops4-maven-service/[root@devops devops4-maven-service]#lsbuild.shmvnwmvnw.cmdpom.xmlREADME.mdsrc[root@devops devops4-maven-service]#
- 在该项目目录下创建
sonar-project.properties
文件:
[root@devops devops4-maven-service]#pwd/root/sonarProject/devops4-maven-service[root@devops devops4-maven-service]#lsbuild.shmvnwmvnw.cmdpom.xmlREADME.mdsrc[root@devops devops4-maven-service]#vim sonar-project.properties# 定义项目关键字sonar.projectKey=devop4-maven-service# 定义项目名称sonar.projectName=devops4-maven-service# 定义项目的版本信息sonar.projectVersion=1.0# 指定扫描代码的目录位置(多个逗号分隔)sonar.sources=src# 执行项目编码sonar.sourceEncoding=UTF-8# 指定sonar Serversonar.host.url=http:# 认证信息sonar.login=adminsonar.password=admin123
- 进行扫描:
[root@devops devops4-maven-service]#sonar-scanner
此时会发现一个常见的报错:
注意:java类型项目比较特殊,扫描时要先对其进行下编译,因为sonarqube在扫描时需要用到它编译后的类!
- 此时再编辑下
sonar-project.properties
内容,并编译下后,再执行下扫描:
[root@devops devops4-maven-service]#vim sonar-project.properties# 定义项目关键字sonar.projectKey=devop4-maven-service# 定义项目名称sonar.projectName=devops4-maven-service# 定义项目的版本信息sonar.projectVersion=1.0# 指定扫描代码的目录位置(多个逗号分隔)sonar.sources=src# 执行项目编码sonar.sourceEncoding=UTF-8# 指定sonar Serversonar.host.url=http:# 认证信息sonar.login=adminsonar.password=admin123sonar.java.binaries=target/classes[root@devops devops4-maven-service]#mvn clean package[root@devops devops4-maven-service]#lsbuild.shmvnwmvnw.cmdpom.xmlREADME.mdsonar-project.propertiessrctarget[root@devops devops4-maven-service]#ls target/classesdemo-0.0.1-SNAPSHOT.jar.originalgenerated-test-sourcesmaven-statusdemo-0.0.1-SNAPSHOT.jargenerated-sourcesmaven-archivertest-classes[root@devops devops4-maven-service]#ls target/classes/application.propertiescomstatic
再次扫描下,查看结果:
[root@devops devops4-maven-service]#ls .scannerwork/css-bundlereport-task.txt[root@devops devops4-maven-service]#cat .scannerwork/report-task.txt projectKey=devop4-maven-serviceserverUrl=http:serverVersion=8.9.8.54436dashboardUrl=http:ceTaskId=AYD2jY87VkQu9X-kQ24qceTaskUrl=http:sonar.projectVersion=2.0
再次扫描下,再来看下效果: sonar-scanner 此时就可以看到新代码这里显示的bug数了:
⚠️ 注意:这里的sonar-project.properties
文件名是不能变的!
测试结束。😘
2.Web前端项目扫描
sonar-scanner\-Dsonar.projectKey=demo-devops-ui\-Dsonar.projectName=demo-devops-ui\-Dsonar.sources=src\-Dsonar.host.url=http:-Dsonar.login=0809881d71f2b06b64786ae3f81a9acf22078e8b\-Dsonar.projectVersion=2.0\-Dsonar.ws.timeout=30\-Dsonar.projectDescription="my first project!"\-Dsonar.links.homepage=http:-Dsonar.links.ci=http:-Dsonar.sourceEncoding=UTF-8
3.Golang项目扫描
sonar-scanner-Dsonar.projectKey=devops-golang-service\-Dsonar.projectName=devops-golang-service \-Dsonar.sources=src \-Dsonar.login=admin \-Dsonar.password=admin \-Dsonar.host.url=http:## 有测试用例的情况sonar.exclusions=***_test.go
4、CI流水线集成
1.JenkinsPipeline集成
本次集成重点演示两种方式: 1. 使用命令行方式 2. 使用Jenkins扩展插件的方式。
(1)使用命令行方式
💘 实践:Jenkins集成SonarQube(命令行方式)(测试成功)-2023.6.24 |
- 实验环境
jenkins/jenkins:2.346.3-2-lts-jdk11gitlab/gitlab-ce:15.0.3-ce.0sonarqube:9.9.0-communitySonarScanner4.8.0.2856
- 实验软件
链接:https:}
然后服务器地址,我们也把它写放在流水线里。
修改完
sonar-project.properties
配置内容后,提交。
# 定义唯一的关键字sonar.projectKey=devops6-maven-service# 定义项目名称sonar.projectName=devops6-maven-service# 定义项目的版本信息sonar.projectVersion=1.0# 指定扫描代码的目录位置(多个逗号分隔)sonar.sources=.# 执行项目编码sonar.sourceEncoding=UTF-8# 指定sonar Server# sonar.host.url=http:# 认证信息# sonar.login=admin# sonar.password=Admin@123# java classessonar.java.binaries=target/classessonar.java.test.binaries=target/test-classessonar.java.surefire.report=target/surefire-reports
- 这里编辑pipeline代码
我们期待的写法是这样的:
- 继续改写Jenkins pipeline代码
@Library("devops06@main") _defbuild =neworg.devops.Build()pipeline {agent {label "build"}stages{stage("CheckOut"){steps{script{build.CheckOut()}}}stage("Build"){steps{script{build.Build()}}} stage("CodeScan"){steps{script{withCredentials([usernamePassword(credentialsId:'003d1667-653e-40f3-8103-b74614643aba',passwordVariable:'SONAR_PASSWD',usernameVariable:'SONAR_USER')]) {sh """/data/devops6/sonar-scanner-4.8.0.2856-linux/bin/sonar-scanner \-Dsonar.login=${SONAR_USER} \-Dsonar.password=${SONAR_PASSWD} \-Dsonar.host.url=http:"""}}}}}}
提交。
- 运行
可以看到,代码检查步骤也是ok的。
测试结束。😘
💘 实践:Jenkins PipeLine中的代码扫描(测试成功)-2022.5.25 |
- 把sonar-project.properties文件提到devops4-maven-service工程里面去:
也就是来到Gitlab的devops4-maven-service
项目下,创建一个sonar-project.properties文件,并提交:
# 定义项目关键字sonar.projectKey=devop4-maven-service# 定义项目名称sonar.projectName=devops4-maven-service# 定义项目的版本信息sonar.projectVersion=2.0# 指定扫描代码的目录位置(多个逗号分隔)sonar.sources=src# 执行项目编码sonar.sourceEncoding=UTF-8# 指定sonar Serversonar.host.url=http:# 认证信息sonar.login=adminsonar.password=admin123sonar.java.binaries=target/classes
- 先在jenkins里跑一下devops4-maven-service项目流水线,看下是否可正常跑下去:
可以看到能够正常运行流水线。
- 在jenkins共享库里编写jenkinsfile文件,并提交,然后再次触发流水线:
完整Jenkinsfile代码如下:
@Library("mylib@main") _ importorg.devops.*defcheckout =newCheckout() defbuild =newBuild()defunittest =newUnitTest()pipeline {agent {label "build"}options {skipDefaultCheckout true}stages{stage("Checkout"){steps{script {println("GetCode")checkout.GetCode("${env.srcUrl}","${env.branchName}")}}}stage("Build"){steps{script{println("Build")sh "${env.buildShell}"}}}stage("CodeScan"){steps{script{cliPath="/usr/local/sonar-scanner/sonar-scanner-4.7.0.2747-linux/bin"sh "${cliPath}/sonar-scanner"}}}}}
- 这里优化下,把项目里的sonar-project.properties文件里的sonar.login和sonar.password使用jenkins的凭据功能给隐藏起来:
随便找一个流水线项目,利用流水线语法-片段生成器
,来生成代码:
withCredentials([usernamePassword(credentialsId:'79d8f75b-3733-49f4-950f-19f8480fda03',passwordVariable:'SONAR_PASSWD',usernameVariable:'SONAR_USER')]) {}
- 将生成的代码写在jenkins共享库的jenkiinsfile里面,然后再次跑一下流水线,观察效果:
@Library("mylib@main") _ importorg.devops.*defcheckout =newCheckout() defbuild =newBuild()defunittest =newUnitTest()pipeline {agent {label "build"}options {skipDefaultCheckout true}stages{stage("Checkout"){steps{script {println("GetCode")checkout.GetCode("${env.srcUrl}","${env.branchName}")}}}stage("Build"){steps{script{println("Build")sh "${env.buildShell}"}}}stage("CodeScan"){steps{script{cliPath="/usr/local/sonar-scanner/sonar-scanner-4.7.0.2747-linux/bin"withCredentials([usernamePassword(credentialsId:'79d8f75b-3733-49f4-950f-19f8480fda03',passwordVariable:'SONAR_PASSWD',usernameVariable:'SONAR_USER')]) {sh """${cliPath}/sonar-scanner \-Dsonar.login=${SONAR_USER} \-Dsonar.password=${SONAR_PASSWD} \-Dsonar.projectVersion=${env.branchName}"""}}}}}}
写好后提交:
记得要把devops4-maven-service项目的sonar-project.propertries文件里的相关信息给注释掉:
以上代码都修改完成后,进行提交,再来到jenkins上进行构建。
- 可以看到,能够正常构建成功:
- 接下来再进一步扩展:
进一步优化下jenkins共享库里的代码:
创建srg/org/devops/Sonar.groovy
文件:
packageorg.devopsdefCodeScan(branchName){cliPath="/usr/local/sonar-scanner/sonar-scanner-4.7.0.2747-linux/bin"withCredentials([usernamePassword(credentialsId:'79d8f75b-3733-49f4-950f-19f8480fda03',passwordVariable:'SONAR_PASSWD',usernameVariable:'SONAR_USER')]) {sh """${cliPath}/sonar-scanner \-Dsonar.login=${SONAR_USER} \-Dsonar.password=${SONAR_PASSWD} \-Dsonar.projectVersion=${branchName}"""}}
编写Jenkinsfile
里的代码:
@Library("mylib@main") _
importorg.devops.*defcheckout=newCheckout() defbuild=newBuild()defunittest=newUnitTest()defsonar=newSonar() pipeline{agent{label"build"}options{skipDefaultCheckouttrue}stages{stage("Checkout"){steps{script{println("GetCode")checkout.GetCode("${env.srcUrl}","${env.branchName}")}}}stage("Build"){steps{script{println("Build")sh"${env.buildShell}"}}}stage("CodeScan"){steps{script{profileName ="${JOB_NAME}".split("-")[0]sonar.Init("${JOB_NAME}","java",profileName)sonar.CodeScan("${env.branchName}")}}}}}
注意:也要保证devops4-maven-service
项目里sonar-project.properties文件的配置正确:
- 提交流水线,观察效果:
符合预期。😘
6、其他日常使用实践
1.规则的禁用与启用
目的: 掌握默认规则中的一部分规则如何激活和禁用。
质量规则、质量阈--这一般是由TeamLeader、开发人员去指定的。
进入质量配置页面, 可以看到所有的语言规则配置。在这里可以看到规则的使用情况。
这里假设我要调整Go语言的规则配置, 点击规则数量数字。
创建新的规则集:
点击更多激活规则
, 进入规则设置页面。
激活或者下线规则。(活动/挂起)
使用规则: 先在页面配置项目,然后使用SonarScanner扫描。
💘 实践:新建SonarQube质量配置(测试成功)-2023.6.25 |
自己测试过程:
- 测试环境
sonarqube:9.9.0-community
- 创建新的质量配置
- 给特定的配置规则指定项目
- 激活更多规则
完成。
2.质量阈的配置
目的: 适用于以质量门禁作为交付关卡。
💘 实践:新建SonarQube质量阈(测试成功)-2023.6.25 |
自己测试过程:
- 测试环境
sonarqube:9.9.0-community
- 创建新的质量阈
- 给新创建的质量阈指定项目
- 也可以添加新的条件
找一个具有大量单元测试的项目, 然后集成jacoco插件,生成覆盖率报告,最后由sonar收集。
- Maven集成Jacoco(本次在gitlab的devops4-maven-service项目里的
pom.xml
里修改)
添加jacoco-maven-plugin
和junit
插件。
<dependencies><dependency><groupId>org.jacoco</groupId><artifactId>jacoco-maven-plugin</artifactId><version>0.8.2</version><scope>test</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency></dependencies>
添加插件:
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.6.1</version><configuration><skipMain>true</skipMain><skip>true</skip><source>1.8</source><target>1.8</target></configuration></plugin><plugin><groupId>org.jacoco</groupId><artifactId>jacoco-maven-plugin</artifactId><version>0.7.5.201505241946</version><executions><execution><id>prepare-agent</id><goals><goal>prepare-agent</goal></goals></execution><execution><id>report</id><phase>prepare-package</phase><goals><goal>report</goal></goals></execution><execution><id>post-unit-test</id><phase>test</phase><goals><goal>report</goal></goals><configuration><dataFile>target/jacoco.exec</dataFile><outputDirectory>target/jacoco-reports</outputDirectory></configuration></execution></executions><configuration><systemPropertyVariables><jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile></systemPropertyVariables></configuration></plugin>
- SonarQube安装Jacoco插件(8.9.1 版本可以跳过,已经集成)