快捷菜单
常用功能一站直达
更多功能请点顶栏「快捷菜单」

[toc]
https://www.yuque.com/xyy-onlyone/aevhhf?# 《玩转Typora》

| 实战名称 |
|---|
| 💘 实践:Scanner进行项目代码扫描(测试成功)-2023.6.24 |
| 💘 实践:Jenkins集成SonarQube(命令行方式)(测试成功)-2023.6.24 |
| 💘 实践:Jenkins集成SonarQube(jenkins插件方式)(测试成功)-2023.6.24 |
| 💘 实践:新建SonarQube质量配置(测试成功)-2023.6.25 |
| 💘 实践:新建SonarQube质量阈(测试成功)-2023.6.25 |
| 💘 实践:SonarQube多分支代码扫描(测试成功)-2023.6.25 |
| 💘 实践:SonarQube控制代码扫描步骤运行(测试成功)-2023.6.25 |
SonarQube®是一种自动代码审查工具,可检测代码中的错误,漏洞和代码味道。它可以与您现有的工作流程集成,以实现跨项目分支和拉取请求的持续代码检查。
开发人员在IDE开发代码,可以安装SonarLint插件(本地代码扫描)进行提交前代码扫描。
当开发人员提交代码到版本控制系统中,自动触发jenkins进行代码扫描。
sonarQube本身具有消息通知webhook,当然也可以借助Jenkins的email插件来发送消息通知。
组件与服务组成:
SonarQube Server启动包含3个主要进程:
SonarQube数据库要存储:SonarQube实例的配置(安全,插件设置等)项目,视图质量快照。
服务器上安装了多个SonarQube插件,可能包括语言,SCM,集成,身份验证和管理插件。
在持续集成服务器上运行一个或多个SonarScanner,以分析项目。



==见单独md。==
代码扫描过程: 本地(构建节点)安装配置SonarScanner环境,然后通过设置sonar的一系列参数进行扫描分析。
==方法1:配置文件方式读取扫描参数==
一个基本的sonar-project.properties配置文件的参数:
1# 定义唯一的关键字
2sonar.projectKey=devops6-maven-service
3
4# 定义项目名称
5sonar.projectName=devops6-maven-service
6
7# 定义项目的版本信息
8sonar.projectVersion=1.0
9
10# 指定扫描代码的目录位置(多个逗号分隔)
11sonar.sources=.
12
13# 执行项目编码
14sonar.sourceEncoding=UTF-8
15
16# 指定sonar Server
17sonar.host.url=http://172.29.9.101:9000
18
19# 认证信息
20sonar.login=admin
21sonar.password=Admin@123这些配置项都是统一的,目前sonar支持将扫描参数以文件的方式存放或者以命令行传参的方式读取。
文件方式:可以将扫描参数放到项目的根目录或者sonar-scanner的配置文件目录等自定义的目录中;
命令行传参则可以直接将变量传递给sonarsacnner cli -Dsonar.projectKey=xxx 。
==方法2:命令行方式读取扫描参数== (命令行方式会覆盖掉配置文件方式的)
1# 指定配置文件
2sonar-scanner -Dproject.settings=myproject.properties
3
4# 命令行传参
5sonar-scanner -Dsonar.projectKey=myproject -Dsonar.sources=src1sonarqube服务器端需要安装Java语言规则插件

1sonar-scanner -Dsonar.host.url=http://192.168.1.200:9000 \
2-Dsonar.projectKey=devops-maven-service \
3-Dsonar.projectName=devops-maven-service \
4-Dsonar.projectVersion=1.1 \
5-Dsonar.login=admin \
6-Dsonar.password=admin123 \
7-Dsonar.ws.timeout=30 \
8-Dsonar.projectDescription="my first project!" \
9-Dsonar.links.homepage=http://192.168.1.200/devops/devops-maven-service \
10-Dsonar.links.ci=http://192.168.1.200:8080/job/demo-pipeline-service/ \
11-Dsonar.sources=src \
12-Dsonar.sourceEncoding=UTF-8 \
13-Dsonar.java.binaries=target/classes \
14-Dsonar.java.test.binaries=target/test-classes \
15-Dsonar.java.surefire.report=target/surefire-reports 1`sonar.projectKey` 指定项目的关键字
2`sonar.host.url`指定服务器地址(可以直接在配置文件中写死),
3`projectName`指定项目的名称,
4`projectVersion`指定项目的版本(可以用构建时间和构建ID定义),
5`login`指定登录用户名,
6`password`指定登录用户密码,
7`projectDescription`指定项目的描述信息,
8`links.homepage`指定项目的主页(超链接),
9`sources`指定扫描的目录,
10`sourceEncoding`指定扫描时的编码,
11`java.binaries`指定编译后的类文件目录(必填),
12 `java.test.binaries`指定编译后的测试类目录,
13`java.surefire.report`指定测试报告目录。| 💘 实践:Scanner进行项目代码扫描(测试成功)-2023.6.24 |

1sonarqube:9.9.0-community (docker方式部署)
2SonarScanner 4.8.0.2856 (部署在宿主机上)实验软件(无)
手动扫描代码
在devops6-maven-service项目里创建sonar-project.properties文件:
1# 定义唯一的关键字
2sonar.projectKey=devops6-maven-service
3
4# 定义项目名称
5sonar.projectName=devops6-maven-service
6
7# 定义项目的版本信息
8sonar.projectVersion=1.0
9
10# 指定扫描代码的目录位置(多个逗号分隔)
11sonar.sources=.
12
13# 执行项目编码
14sonar.sourceEncoding=UTF-8
15
16# 指定sonar Server
17sonar.host.url=http://172.29.9.101:9000
18
19# 认证信息
20sonar.login=admin
21sonar.password=Admin@123
22
23# java classes
24sonar.java.binaries=target/classes
25sonar.java.test.binaries=target/test-classes
26sonar.java.surefire.report=target/surefire-reports
提交。
devops6-maven-service本地项目里,拉取代码,然后扫描 1#拉取代码
2[root@Devops6 devops6-maven-service]#pwd
3/data/devops6/devops6-maven-service
4[root@Devops6 devops6-maven-service]#ls
5mvnw mvnw.cmd pom.xml src target
6[root@Devops6 devops6-maven-service]#git pull
7[root@Devops6 devops6-maven-service]#ls
8mvnw mvnw.cmd pom.xml sonar-project.properties src target
9
10#删除之前的打包好的缓存数据
11[root@Devops6 devops6-maven-service]#rm -rf target/
12
13#打包
14[root@Devops6 devops6-maven-service]#mvn clean package
15
16#扫描
17[root@Devops6 devops6-maven-service]#sonar-scanner


测试结束。😘
| 💘 实践:Scanner进行项目代码扫描(测试成功)-2022.5.24 |

自己实际测试过程:
devops4-maven-service项目代码到sonarscanner机器: 1[root@devops ~]#mkdir sonarProject
2[root@devops ~]#cd sonarProject/
3[root@devops sonarProject]#git clone http://172.29.9.101/devops4/devops4-maven-service.git
4Cloning into 'devops4-maven-service'...
5Username for 'http://172.29.9.101': root
6Password for 'http://root@172.29.9.101':
7remote: Enumerating objects: 52, done.
8remote: Counting objects: 100% (18/18), done.
9remote: Compressing objects: 100% (18/18), done.
10remote: Total 52 (delta 9), reused 0 (delta 0), pack-reused 34
11Receiving objects: 100% (52/52), 56.33 KiB | 28.16 MiB/s, done.
12Resolving deltas: 100% (11/11), done.
13[root@devops sonarProject]#ls
14devops4-maven-service
15[root@devops sonarProject]#cd devops4-maven-service/
16[root@devops devops4-maven-service]#ls
17build.sh mvnw mvnw.cmd pom.xml README.md src
18[root@devops devops4-maven-service]#sonar-project.properties文件: 1[root@devops devops4-maven-service]#pwd
2/root/sonarProject/devops4-maven-service
3[root@devops devops4-maven-service]#ls
4build.sh mvnw mvnw.cmd pom.xml README.md src
5[root@devops devops4-maven-service]#vim sonar-project.properties
6# 定义项目关键字
7sonar.projectKey=devop4-maven-service
8
9# 定义项目名称
10sonar.projectName=devops4-maven-service
11
12# 定义项目的版本信息
13sonar.projectVersion=1.0
14
15 # 指定扫描代码的目录位置(多个逗号分隔)
16sonar.sources=src
17
18 # 执行项目编码
19sonar.sourceEncoding=UTF-8
20
21 # 指定sonar Server
22sonar.host.url=http://172.29.9.101:9000
23
24 # 认证信息
25sonar.login=admin
26sonar.password=admin123 1[root@devops devops4-maven-service]#sonar-scanner此时会发现一个常见的报错:

注意:java类型项目比较特殊,扫描时要先对其进行下编译,因为sonarqube在扫描时需要用到它编译后的类!
sonar-project.properties内容,并编译下后,再执行下扫描: 1[root@devops devops4-maven-service]#vim sonar-project.properties
2# 定义项目关键字
3sonar.projectKey=devop4-maven-service
4
5# 定义项目名称
6sonar.projectName=devops4-maven-service
7
8# 定义项目的版本信息
9sonar.projectVersion=1.0
10
11 # 指定扫描代码的目录位置(多个逗号分隔)
12sonar.sources=src
13
14 # 执行项目编码
15sonar.sourceEncoding=UTF-8
16
17 # 指定sonar Server
18sonar.host.url=http://172.29.9.101:9000
19
20 # 认证信息
21sonar.login=admin
22sonar.password=admin123
23
24sonar.java.binaries=target/classes
25
26[root@devops devops4-maven-service]#mvn clean package
27[root@devops devops4-maven-service]#ls
28build.sh mvnw mvnw.cmd pom.xml README.md sonar-project.properties src target
29[root@devops devops4-maven-service]#ls target/
30classes demo-0.0.1-SNAPSHOT.jar.original generated-test-sources maven-status
31demo-0.0.1-SNAPSHOT.jar generated-sources maven-archiver test-classes
32[root@devops devops4-maven-service]#ls target/classes/
33application.properties com static再次扫描下,查看结果:

1[root@devops devops4-maven-service]#ls .scannerwork/
2css-bundle report-task.txt
3[root@devops devops4-maven-service]#cat .scannerwork/report-task.txt
4projectKey=devop4-maven-service
5serverUrl=http://172.29.9.101:9000
6serverVersion=8.9.8.54436
7dashboardUrl=http://172.29.9.101:9000/dashboard?id=devop4-maven-service
8ceTaskId=AYD2jY87VkQu9X-kQ24q
9ceTaskUrl=http://172.29.9.101:9000/api/ce/task?id=AYD2jY87VkQu9X-kQ24q到sonarqube server上验证:
http://172.29.9.101:9000/dashboard?id=devop4-maven-service
这里可以设置为误判:
注意:soarqube会把源代码下载下来的,因此一定要保护好sonarqube的账户信息。
可以看到这里是1.0版本:

此时我们修改下sonar-project.properties的sonar.projectVersion=1.0
1[root@devops devops4-maven-service]#vim sonar-project.properties
2sonar.projectVersion=2.0再次扫描下,再来看下效果:
sonar-scanner
此时就可以看到新代码这里显示的bug数了:

⚠️ 注意:这里的sonar-project.properties文件名是不能变的!

测试结束。😘

1sonar-scanner \
2 -Dsonar.projectKey=demo-devops-ui \
3 -Dsonar.projectName=demo-devops-ui \
4 -Dsonar.sources=src \
5 -Dsonar.host.url=http://192.168.1.200:9000 \
6 -Dsonar.login=0809881d71f2b06b64786ae3f81a9acf22078e8b \
7 -Dsonar.projectVersion=2.0 \
8 -Dsonar.ws.timeout=30 \
9 -Dsonar.projectDescription="my first project!" \
10 -Dsonar.links.homepage=http://192.168.1.200/devops/devops-maven-service \
11 -Dsonar.links.ci=http://192.168.1.200:8080/job/demo-pipeline-service/ \
12 -Dsonar.sourceEncoding=UTF-8 
1sonar-scanner -Dsonar.projectKey=devops-golang-service \
2-Dsonar.projectName=devops-golang-service \
3-Dsonar.sources=src \
4-Dsonar.login=admin \
5-Dsonar.password=admin \
6-Dsonar.host.url=http://192.168.1.200:9000
7
8
9## 有测试用例的情况
10sonar.exclusions=**/*_test.go
11sonar.tests=.
12sonar.test.inclusions=**/*_test.go本次集成重点演示两种方式: 1. 使用命令行方式 2. 使用Jenkins扩展插件的方式。
| 💘 实践:Jenkins集成SonarQube(命令行方式)(测试成功)-2023.6.24 |
1jenkins/jenkins:2.346.3-2-lts-jdk11
2gitlab/gitlab-ce:15.0.3-ce.0
3sonarqube:9.9.0-community
4SonarScanner 4.8.0.2856链接:https://pan.baidu.com/s/1TWnlWTaHP_XP3O1aErXCdA?pwd=0820
提取码:0820
2023.6.24-Jenkins集成SonarQube-code

devops6-maven-service共享库设置



构建成功。
devops6-maven-service的sonar-project.properties文件里是不是存在一些问题,需要修改的呢?
这里的SnoarQube账号密码怎么能用明文来显示呢。显示是存在问题的。
Valut专门用来管理秘钥的,那是目前来说最安全的一种方式了。


同时利用Jenkinbs的片段生成器来生成代码:

1withCredentials([usernamePassword(credentialsId: '003d1667-653e-40f3-8103-b74614643aba', passwordVariable: 'SONAR_PASSWD', usernameVariable: 'SONAR_USER')]) {
2 // some block
3}然后服务器地址,我们也把它写放在流水线里。
修改完sonar-project.properties配置内容后,提交。

1# 定义唯一的关键字
2sonar.projectKey=devops6-maven-service
3
4# 定义项目名称
5sonar.projectName=devops6-maven-service
6
7# 定义项目的版本信息
8sonar.projectVersion=1.0
9
10# 指定扫描代码的目录位置(多个逗号分隔)
11sonar.sources=.
12
13# 执行项目编码
14sonar.sourceEncoding=UTF-8
15
16# 指定sonar Server
17# sonar.host.url=http://172.29.9.101:9000
18
19# 认证信息
20# sonar.login=admin
21# sonar.password=Admin@123
22
23# java classes
24sonar.java.binaries=target/classes
25sonar.java.test.binaries=target/test-classes
26sonar.java.surefire.report=target/surefire-reports我们期待的写法是这样的:

1@Library("devops06@main") _
2
3//import src/org/devops/Build.groovy
4def build = new org.devops.Build()
5
6pipeline {
7 agent {label "build"}
8 stages{
9 stage("CheckOut"){
10 steps{
11 script{
12 build.CheckOut()
13 }
14 }
15 }
16
17 stage("Build"){
18 steps{
19 script{
20 build.Build()
21 }
22 }
23
24 }
25
26 stage("CodeScan"){
27 steps{
28 script{
29
30 withCredentials([usernamePassword(credentialsId: '003d1667-653e-40f3-8103-b74614643aba',
31 passwordVariable: 'SONAR_PASSWD',
32 usernameVariable: 'SONAR_USER')]) {
33
34 sh """/data/devops6/sonar-scanner-4.8.0.2856-linux/bin/sonar-scanner \
35 -Dsonar.login=${SONAR_USER} \
36 -Dsonar.password=${SONAR_PASSWD} \
37 -Dsonar.host.url=http://172.29.9.101:9000
38 """
39 }
40
41
42 }
43 }
44 }
45
46 }
47}
提交。


可以看到,代码检查步骤也是ok的。

测试结束。😘
| 💘 实践:Jenkins PipeLine中的代码扫描(测试成功)-2022.5.25 |

也就是来到Gitlab的devops4-maven-service项目下,创建一个sonar-project.properties文件,并提交:

1# 定义项目关键字
2sonar.projectKey=devop4-maven-service
3
4# 定义项目名称
5sonar.projectName=devops4-maven-service
6
7# 定义项目的版本信息
8sonar.projectVersion=2.0
9
10 # 指定扫描代码的目录位置(多个逗号分隔)
11sonar.sources=src
12
13 # 执行项目编码
14sonar.sourceEncoding=UTF-8
15
16 # 指定sonar Server
17sonar.host.url=http://172.29.9.101:9000
18
19 # 认证信息
20sonar.login=admin
21sonar.password=admin123
22
23sonar.java.binaries=target/classes
可以看到能够正常运行流水线。


完整Jenkinsfile代码如下:
1@Library("mylib@main") _ //加载共享库
2import org.devops.* // 导入库
3
4def checkout = new Checkout() //New实例化
5def build = new Build()
6def unittest = new UnitTest()
7
8//env.buildType = "${JOB_NAME}".split("-")[1]
9
10//流水线
11pipeline {
12 agent { label "build" }
13
14 options {
15 skipDefaultCheckout true
16 }
17
18 stages{
19 stage("Checkout"){
20 steps{
21 script {
22 println("GetCode")
23 checkout.GetCode("${env.srcUrl}", "${env.branchName}")
24 }
25 }
26 }
27
28 stage("Build"){
29 steps{
30 script{
31 println("Build")
32 //build.CodeBuild("${env.buildType}")
33 sh "${env.buildShell}"
34
35 }
36 }
37 }
38
39 /*stage("UnitTest"){
40 steps{
41 script{
42 unittest.CodeTest("${env.buildType}")
43 }
44 }
45 }*/
46
47 stage("CodeScan"){
48 steps{
49 script{
50 cliPath="/usr/local/sonar-scanner/sonar-scanner-4.7.0.2747-linux/bin"
51 sh "${cliPath}/sonar-scanner"
52 }
53 }
54 }
55 }
56}

随便找一个流水线项目,利用流水线语法-片段生成器,来生成代码:



1withCredentials([usernamePassword(credentialsId: '79d8f75b-3733-49f4-950f-19f8480fda03', passwordVariable: 'SONAR_PASSWD', usernameVariable: 'SONAR_USER')]) {
2 // some block
3} 1@Library("mylib@main") _ //加载共享库
2import org.devops.* // 导入库
3
4def checkout = new Checkout() //New实例化
5def build = new Build()
6def unittest = new UnitTest()
7
8//env.buildType = "${JOB_NAME}".split("-")[1]
9
10//流水线
11pipeline {
12 agent { label "build" }
13
14 options {
15 skipDefaultCheckout true
16 }
17
18 stages{
19 stage("Checkout"){
20 steps{
21 script {
22 println("GetCode")
23 checkout.GetCode("${env.srcUrl}", "${env.branchName}")
24 }
25 }
26 }
27
28 stage("Build"){
29 steps{
30 script{
31 println("Build")
32 //build.CodeBuild("${env.buildType}")
33 sh "${env.buildShell}"
34
35 }
36 }
37 }
38
39 /*stage("UnitTest"){
40 steps{
41 script{
42 unittest.CodeTest("${env.buildType}")
43 }
44 }
45 }*/
46
47 stage("CodeScan"){
48 steps{
49 script{
50 cliPath="/usr/local/sonar-scanner/sonar-scanner-4.7.0.2747-linux/bin"
51 withCredentials([usernamePassword(credentialsId: '79d8f75b-3733-49f4-950f-19f8480fda03',
52 passwordVariable: 'SONAR_PASSWD',
53 usernameVariable: 'SONAR_USER')]) {
54 // some block
55 sh """${cliPath}/sonar-scanner \
56 -Dsonar.login=${SONAR_USER} \
57 -Dsonar.password=${SONAR_PASSWD} \
58 -Dsonar.projectVersion=${env.branchName}
59 """
60 }
61
62 }
63 }
64 }
65 }
66}写好后提交:
记得要把devops4-maven-service项目的sonar-project.propertries文件里的相关信息给注释掉:

以上代码都修改完成后,进行提交,再来到jenkins上进行构建。



进一步优化下jenkins共享库里的代码:
创建srg/org/devops/Sonar.groovy文件:
1package org.devops
2
3def CodeScan(branchName){
4 cliPath="/usr/local/sonar-scanner/sonar-scanner-4.7.0.2747-linux/bin"
5 withCredentials([usernamePassword(credentialsId: '79d8f75b-3733-49f4-950f-19f8480fda03',
6 passwordVariable: 'SONAR_PASSWD',
7 usernameVariable: 'SONAR_USER')]) {
8 // some block
9 sh """${cliPath}/sonar-scanner \
10 -Dsonar.login=${SONAR_USER} \
11 -Dsonar.password=${SONAR_PASSWD} \
12 -Dsonar.projectVersion=${branchName}
13 """
14 }
15}编写Jenkinsfile里的代码:
1@Library("mylib@main") _ //加载共享库
2import org.devops.* // 导入库
3
4def checkout = new Checkout() //New实例化
5def build = new Build()
6def unittest = new UnitTest()
7def sonar = new Sonar()
8
9//env.buildType = "${JOB_NAME}".split("-")[1]
10
11//流水线
12pipeline {
13 agent { label "build" }
14
15 options {
16 skipDefaultCheckout true
17 }
18
19 stages{
20 stage("Checkout"){
21 steps{
22 script {
23 println("GetCode")
24 checkout.GetCode("${env.srcUrl}", "${env.branchName}")
25 }
26 }
27 }
28
29 stage("Build"){
30 steps{
31 script{
32 println("Build")
33 //build.CodeBuild("${env.buildType}")
34 sh "${env.buildShell}"
35
36 }
37 }
38 }
39
40 /*stage("UnitTest"){
41 steps{
42 script{
43 unittest.CodeTest("${env.buildType}")
44 }
45 }
46 }*/
47
48 stage("CodeScan"){
49 steps{
50 script{
51 sonar.CodeScan("${env.branchName}")
52 }
53
54 }
55 }
56
57 }
58}修改完成后,提交并构建:


可以看到,可以成功构建!😘
| 💘 实践:Jenkins集成SonarQube(Jenkins插件方式)(测试成功)-2023.6.24 |
1jenkins/jenkins:2.346.3-2-lts-jdk11
2gitlab/gitlab-ce:15.0.3-ce.0
3sonarqube:9.9.0-community
4SonarScanner 4.8.0.2856链接:https://pan.baidu.com/s/1TWnlWTaHP_XP3O1aErXCdA?pwd=0820
提取码:0820
2023.6.24-Jenkins集成SonarQube-code

参考:https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-jenkins/

1sqa_1339c18e86d442f9209bf363376554d5df5ca7a5我的账号-生成令牌。




生成代码:

1withSonarQubeEnv(credentialsId: 'bdefe5e2-62a0-4e20-bf5a-51abedfe6df1') {
2 // some block
3}

在片段生成器中查看用法, 注入与所选SonarQube 安装相关的环境变量。将设置以下变量:
1SONAR_HOST_URL ## 在jenkins管理页面配置的sonar地址
2SONAR_AUTH_TOKEN ## 在jenkins管理页面配置的sonar认证信息使用withSonarQubeEnv DSL引入在Jenkins中配置的sonar环境。
1@Library("devops06@main") _
2
3//import src/org/devops/Build.groovy
4def build = new org.devops.Build()
5
6pipeline {
7 agent {label "build"}
8 stages{
9 stage("CheckOut"){
10 steps{
11 script{
12 build.CheckOut()
13 }
14 }
15 }
16
17 stage("Build"){
18 steps{
19 script{
20 build.Build()
21 }
22 }
23
24 }
25
26 stage("CodeScan"){
27 steps{
28 script{
29
30 // withCredentials([usernamePassword(credentialsId: '003d1667-653e-40f3-8103-b74614643aba',
31 // passwordVariable: 'SONAR_PASSWD',
32 // usernameVariable: 'SONAR_USER')]) {
33
34 // sh """/data/devops6/sonar-scanner-4.8.0.2856-linux/bin/sonar-scanner \
35 // -Dsonar.login=${SONAR_USER} \
36 // -Dsonar.password=${SONAR_PASSWD} \
37 // -Dsonar.host.url=http://172.29.9.101:9000
38 // """
39 // }
40
41
42 withSonarQubeEnv(credentialsId: 'bdefe5e2-62a0-4e20-bf5a-51abedfe6df1') {
43 sh """/data/devops6/sonar-scanner-4.8.0.2856-linux/bin/sonar-scanner \
44 -Dsonar.login=${SONAR_AUTH_TOKEN} \
45 -Dsonar.host.url=${SONAR_HOST_URL}
46 """
47 }
48
49 }
50 }
51 }
52
53 }
54}
用了插件的好处:这里可以直接跳过去,看报告。
最终的效果如下:
相比命令行只是增加了一些扩展链接, 对于经常操作Jenkins的用户方便些。


测试成功。😘
| 💘 实践:GitLab PipeLine中的代码扫描(测试成功)-2022.5.26 |

来到devops4组下:



编辑jobs/CI.yaml文件:

1.pipelineInit:
2 tags:
3 - "${RUNNER_TAG}"
4 stage: .pre
5 variables:
6 GIT_CHECKOUT: "true" ##局部开启作业的代码下载
7 script:
8 - ls -l
9
10.cibuild:
11 tags:
12 - "${RUNNER_TAG}"
13 stage: build
14 script:
15 - echo "${BUILD_SHELL}"
16 - ${BUILD_SHELL}
17 # artifacts:
18 # paths:
19 # - ${ARTIFACT_PATH}
20
21.citest:
22 tags:
23 - "${RUNNER_TAG}"
24 stage: test
25 script:
26 - echo "${TEST_SHELL}"
27 - ${TEST_SHELL}
28 # artifacts:
29 # reports:
30 # junit: ${TEST_REPORTS}
31
32.codescan:
33 tags:
34 - "${RUNNER_TAG}"
35 stage: codescan
36 script:
37 |-
38 /usr/local/sonar-scanner/sonar-scanner-4.7.0.2747-linux/bin/sonar-scanner \
39 -Dsonar.login=${SONAR_USER} \
40 -Dsonar.password=${SONAR_PASSWD} \
41 -Dsonar.projectVersion=${CI_COMMIT_BRANCH}编辑.gitlabci.yml文件:

1include:
2 - project: 'devops4/devops4-gitlablib-service'
3 ref: main
4 file:
5 - '/jobs/CI.yaml'
6
7workflow:
8 rules:
9 - if: $CI_PIPELINE_SOURCE == "web"
10 when: always
11 - if: $CI_COMMIT_BEFORE_SHA == "0000000000000000000000000000000000000000"
12 when: never
13 - when: always
14
15variables:
16 GIT_CHECKOUT: "false" ## 全局关闭作业代码下载
17 BUILD_SHELL: "sh -x build.sh" ## 构建命令
18 TEST_SHELL: "/usr/local/apache-maven-3.8.5/bin/mvn test " ## 测试命令
19 # ARTIFACT_PATH: "target/*jar" ## 制品路径
20 # TEST_REPORTS: "target/surefire-reports/TEST-*.xml" ##测试报告
21 RUNNER_TAG: "builder"
22
23stages:
24 - build
25 - test
26 - codescan
27
28pipelineInit:
29 extends:
30 - .pipelineInit
31
32cibuild:
33 extends:
34 - .cibuild
35
36citest:
37 extends:
38 - .citest
39
40codescan:
41 extends:
42 - .codescan


测试完成。😘
3.插件方式
| 💘 实践:Jenkins插件进行扫描(测试成功)-2022.5.26 |


参考:https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-jenkins/





使用withSonarQubeEnv DSL引入在Jenkins中配置的sonar环境:

1withSonarQubeEnv(credentialsId: '09a996dd-2b05-46c8-90f9-09905bbc22c9') {
2 // some block
3} 1@Library("mylib@main") _ //加载共享库
2import org.devops.* // 导入库
3
4def checkout = new Checkout() //New实例化
5def build = new Build()
6def unittest = new UnitTest()
7def sonar = new Sonar()
8
9//env.buildType = "${JOB_NAME}".split("-")[1]
10
11//流水线
12pipeline {
13 agent { label "build" }
14
15 options {
16 skipDefaultCheckout true
17 }
18
19 stages{
20 stage("Checkout"){
21 steps{
22 script {
23 println("GetCode")
24 checkout.GetCode("${env.srcUrl}", "${env.branchName}")
25 }
26 }
27 }
28
29 stage("Build"){
30 steps{
31 script{
32 println("Build")
33 //build.CodeBuild("${env.buildType}")
34 sh "${env.buildShell}"
35
36 }
37 }
38 }
39
40 /*stage("UnitTest"){
41 steps{
42 script{
43 unittest.CodeTest("${env.buildType}")
44 }
45 }
46 }*/
47
48 stage("CodeScan"){
49 steps{
50 script{
51
52 withSonarQubeEnv(credentialsId: '09a996dd-2b05-46c8-90f9-09905bbc22c9') {
53 cliPath="/usr/local/sonar-scanner/sonar-scanner-4.7.0.2747-linux/bin"
54 sh """${cliPath}/sonar-scanner \
55 -Dsonar.projectVersion=master
56 """
57 }
58 }
59 }
60
61 }
62 }
63}相比命令行只是增加了一些扩展链接, 对于经常操作Jenkins的用户方便些。



测试完成。😘
| 💘 实践:SonarQube REST API(测试成功)-2022.5.27 |
SonarQube系统的API文档: http://172.29.9.101:9000/web_api
1//查找项目
2api/projects/search?projects=${projectName}"
3
4//创建项目
5api/projects/create?name=${projectName}&project=${projectName}"
6
7//更新语言规则集
8api/qualityprofiles/add_project?language=${language}&qualityProfile=${qualityProfile}&project=${projectName}"
9
10//项目授权
11api/permissions/apply_template?projectKey=${projectKey}&templateName=${templateName}"
12
13//更新质量阈
14api/qualitygates/select?projectKey=${projectKey}&gateId=${gateId}"
SonarQube API的请求方法
1curl --location \
2--request GET \
3'http://192.168.1.200:9000/api/projects/search?projects=day4-maven2-service' \
4--header 'Authorization: Basic YWRtaW46YWRtaW4xMjM0'jenkins代码中不要存在敏感信息, 将base64格式的SonarQube 用户token YWRtaW46YWRtaW4xMjM0存储到Jenkins凭据中(Secret Text类型),后续使用withCredentials将值赋值给变量SONAR_TOKEN 。
考虑到Api的URL都具有相同部分http://192.168.1.200:9000/api所以单独复制给变量sonarApi。每个接口返回的都是JSON类型的数据, 这里使用readJSON进行解析和处理。【所以有了下面的代码】
1def SonarRequest(apiUrl,method){
2 withCredentials([string(credentialsId: "52df4ad9-7167-4bf6-a1fc-2f9f17713472", variable: 'SONAR_TOKEN')]) {
3 sonarApi = "http://192.168.1.200:9000/api"
4 response = sh returnStdout: true,
5 script: """
6 curl --location \
7 --request ${method} \
8 "${sonarApi}/${apiUrl}" \
9 --header "Authorization: Basic ${SONAR_TOKEN}"
10 """
11 try {
12 response = readJSON text: """ ${response - "\n"} """
13 } catch(e){
14 response = readJSON text: """{"errors" : true}"""
15 }
16 return response
17
18 }
19}接口地址和参数: http://172.29.9.101:9000/api/projects/search?projects=day4-maven-service
请求类型: GET


转换cURL命令:
1curl --location --request GET 'http://172.29.9.101:9000/api/projects/search?projects=devops4-maven-service' \
2--header 'Authorization: Basic YWRtaW46YWRtaW4xMjM='
YWRtaW46YWRtaW4xMjM0存储到Jenkins凭据中(Secret Text类型),后续使用withCredentials将值赋值给变量SONAR_TOKEN 。在jenkins里添加凭据:

利用片段式语法生成代码:

1pipeline {
2 agent {
3 label "build"
4 }
5
6 stages {
7 stage("run"){
8 steps{
9 script{
10 result = ProjectSearch("devops4-maven-service")
11 println(result)
12 }
13 }
14 }
15 }
16}
17
18// 查找项目
19def ProjectSearch(projectName){
20 apiUrl = "projects/search?projects=${projectName}"
21 response = SonarRequest(apiUrl,"GET")
22
23 if (response.paging.total == 0){
24 println("Project not found!.....")
25 return false
26 }
27 return true
28}
29
30
31def SonarRequest(apiUrl,method){
32 withCredentials([string(credentialsId: "66b7dd41-5434-43a3-8d02-505e2f2dc38f", variable: 'SONAR_TOKEN')]) {
33 sonarApi = "http://172.29.9.101:9000/api"
34 response = sh returnStdout: true,
35 script: """
36 curl --location \
37 --request ${method} \
38 "${sonarApi}/${apiUrl}" \
39 --header "Authorization: Basic ${SONAR_TOKEN}"
40 """
41 try {
42 response = readJSON text: """ ${response - "\n"} """
43 } catch(e){
44 response = readJSON text: """{"errors" : true}"""
45 }
46 return response
47
48 }
49}运行测试:



可以看到,会提示项目不存在。
接口地址和参数: http://172.29.9.101:9000/api/projects/create?name=devops4-maven-service&project=devops4-maven-service
请求类型:POST

cURL:
1curl --location --request POST 'http://172.29.9.101:9000/api/projects/create?name=devops4-maven-service&project=devops4-maven-service' \
2--header 'Authorization: Basic YWRtaW46YWRtaW4xMjM=' 1// 创建项目
2def CreateProject(projectName){
3 apiUrl = "projects/create?name=${projectName}&project=${projectName}"
4 response = SonarRequest(apiUrl,"POST")
5 try{
6 if (response.project.key == projectName ) {
7 println("Project Create success!...")
8 return true
9 }
10 }catch(e){
11 println(response.errors)
12 return false
13 }
14}完整代码如下:
1pipeline {
2 agent {
3 label "build"
4 }
5
6 stages {
7 stage("run"){
8 steps{
9 script{
10 projectName = "devops4-maven-service"
11 result = ProjectSearch("devops4-maven-service")
12 println(result)
13
14 if (result == false){
15 CreateProject(projectName)
16 }
17 }
18 }
19 }
20 }
21}
22
23// 查找项目
24def ProjectSearch(projectName){
25 apiUrl = "projects/search?projects=${projectName}"
26 response = SonarRequest(apiUrl,"GET")
27
28 if (response.paging.total == 0){
29 println("Project not found!.....")
30 return false
31 }
32 return true
33}
34
35
36def SonarRequest(apiUrl,method){
37 withCredentials([string(credentialsId: "66b7dd41-5434-43a3-8d02-505e2f2dc38f", variable: 'SONAR_TOKEN')]) {
38 sonarApi = "http://172.29.9.101:9000/api"
39 response = sh returnStdout: true,
40 script: """
41 curl --location \
42 --request ${method} \
43 "${sonarApi}/${apiUrl}" \
44 --header "Authorization: Basic ${SONAR_TOKEN}"
45 """
46 try {
47 response = readJSON text: """ ${response - "\n"} """
48 } catch(e){
49 response = readJSON text: """{"errors" : true}"""
50 }
51 return response
52
53 }
54}
55
56// 创建项目
57def CreateProject(projectName){
58 apiUrl = "projects/create?name=${projectName}&project=${projectName}"
59 response = SonarRequest(apiUrl,"POST")
60 try{
61 if (response.project.key == projectName ) {
62 println("Project Create success!...")
63 return true
64 }
65 }catch(e){
66 println(response.errors)
67 return false
68 }
69}

可以看到,sonar上项目被创建成功!
接口地址和参数: http://172.29.9.101:9000/api/qualityprofiles/add_project?language=java&project=devops4-maven-service&qualityProfile=devop4
请求类型:POST
postman调试:

cUrl:
1curl --location --request POST 'http://172.29.9.101:9000/api/qualityprofiles/add_project?language=java&project=devops4-maven-service&qualityProfile=devops4' \
2--header 'Authorization: Basic YWRtaW46YWRtaW4xMjM='Jenkins Pipeline:
1// 更新项目质量配置
2def UpdateQualityProfiles(lang, projectName, profileName){
3 apiUrl = "qualityprofiles/add_project?language=${lang}&project=${projectName}&qualityProfile=${profileName}"
4 response = SonarRequest(apiUrl,"POST")
5
6 if (response.errors != true){
7 println("ERROR: UpdateQualityProfiles ${response.errors}...")
8 return false
9 } else {
10 println("SUCCESS: UpdateQualityProfiles ${lang} > ${projectName} > ${profileName}" )
11 return true
12 }
13}完整代码如下:
1pipeline {
2 agent {
3 label "build"
4 }
5
6 stages {
7 stage("run"){
8 steps{
9 script{
10 projectName = "devops4-maven-service"
11 result = ProjectSearch("devops4-maven-service")
12 println(result)
13
14 if (result == false){
15 CreateProject(projectName)
16 }
17
18 UpdateQualityProfiles("java", projectName, "devops4")
19 }
20 }
21 }
22 }
23}
24
25// 查找项目
26def ProjectSearch(projectName){
27 apiUrl = "projects/search?projects=${projectName}"
28 response = SonarRequest(apiUrl,"GET")
29
30 if (response.paging.total == 0){
31 println("Project not found!.....")
32 return false
33 }
34 return true
35}
36
37
38def SonarRequest(apiUrl,method){
39 withCredentials([string(credentialsId: "66b7dd41-5434-43a3-8d02-505e2f2dc38f", variable: 'SONAR_TOKEN')]) {
40 sonarApi = "http://172.29.9.101:9000/api"
41 response = sh returnStdout: true,
42 script: """
43 curl --location \
44 --request ${method} \
45 "${sonarApi}/${apiUrl}" \
46 --header "Authorization: Basic ${SONAR_TOKEN}"
47 """
48 try {
49 response = readJSON text: """ ${response - "\n"} """
50 } catch(e){
51 response = readJSON text: """{"errors" : true}"""
52 }
53 return response
54
55 }
56}
57
58// 创建项目
59def CreateProject(projectName){
60 apiUrl = "projects/create?name=${projectName}&project=${projectName}"
61 response = SonarRequest(apiUrl,"POST")
62 try{
63 if (response.project.key == projectName ) {
64 println("Project Create success!...")
65 return true
66 }
67 }catch(e){
68 println(response.errors)
69 return false
70 }
71}
72
73// 更新项目质量配置
74def UpdateQualityProfiles(lang, projectName, profileName){
75 apiUrl = "qualityprofiles/add_project?language=${lang}&project=${projectName}&qualityProfile=${profileName}"
76 response = SonarRequest(apiUrl,"POST")
77
78 if (response.errors != true){
79 println("ERROR: UpdateQualityProfiles ${response.errors}...")
80 return false
81 } else {
82 println("SUCCESS: UpdateQualityProfiles ${lang} > ${projectName} > ${profileName}" )
83 return true
84 }
85}运行后效果:


项目没有配置质量, 默认使用sonarway(内置质量)。
默认直接使用sonarscanner,扫描的项目,使用的内置的默认质量。
如果具有单独的质量配置,例如每个组织一个质量配置。 此时就需要先手动在web页面创建一个空的项目,然后在项目的配置中设置目标质量配置。(下面是手动的操作步骤)




自动化实现方式 :
查询项目是否存在
1stage("sonartest"){
2 steps{
3 script{
4
5 // 判断项目是否存在
6 sonarProjectName = "${JOB_NAME.split('/')[-1]}"
7 result = ProjectSearch(sonarProjectName)
8 println(result)
9
10 if (result != true){
11 println("Create Sonar Project!...")
12 CreateProject(sonarProjectName)
13 }
14
15 // 指定项目的配置
16 UpdateQualityProfiles("java", sonarProjectName, "${sonarProjectName.split('-')[0]}")
17 }
18 }
19 }完整的jenkinsfile代码:
1pipeline {
2
3 agent {
4 label "build"
5 }
6
7 stages{
8 stage("sonartest"){
9 steps{
10 script{
11
12 // 判断项目是否存在
13 sonarProjectName = "${JOB_NAME.split('/')[-1]}"
14 result = ProjectSearch(sonarProjectName)
15 println(result)
16
17 if (result != true){
18 println("Create Sonar Project!...")
19 CreateProject(sonarProjectName)
20 }
21
22 // 指定项目的配置
23 UpdateQualityProfiles("java", sonarProjectName, "${sonarProjectName.split('-')[0]}")
24 }
25 }
26 }
27 }
28}
29
30def SonarRequest(apiUrl,method){
31 withCredentials([string(credentialsId: "52df4ad9-7167-4bf6-a1fc-2f9f17713472", variable: 'SONAR_TOKEN')]) {
32 sonarApi = "http://192.168.1.200:9000/api"
33 response = sh returnStdout: true,
34 script: """
35 curl --location \
36 --request ${method} \
37 "${sonarApi}/${apiUrl}" \
38 --header "Authorization: Basic ${SONAR_TOKEN}"
39 """
40 try {
41 response = readJSON text: """ ${response - "\n"} """
42 } catch(e){
43 response = readJSON text: """{"errors" : true}"""
44 }
45 return response
46
47 }
48}
49
50// 更新质量阈
51def UpdateQualityProfiles(lang, projectName, profileName){
52 apiUrl = "qualityprofiles/add_project?language=${lang}&project=${projectName}&qualityProfile=${profileName}"
53 response = SonarRequest(apiUrl,"POST")
54
55 if (response.errors != true){
56 println("ERROR: UpdateQualityProfiles ${response.errors}...")
57 return false
58 } else {
59 println("SUCCESS: UpdateQualityProfiles ${lang} > ${projectName} > ${profileName}" )
60 return true
61 }
62}
63
64// 创建项目
65def CreateProject(projectName){
66 apiUrl = "projects/create?name=${projectName}&project=${projectName}"
67 response = SonarRequest(apiUrl,"POST")
68 try{
69 if (response.project.key == projectName ) {
70 println("Project Create success!...")
71 return true
72 }
73 }catch(e){
74 println(response.errors)
75 return false
76 }
77}
78
79// 查找项目
80def ProjectSearch(projectName){
81 apiUrl = "projects/search?projects=${projectName}"
82 response = SonarRequest(apiUrl,"GET")
83
84 if (response.paging.total == 0){
85 println("Project not found!.....")
86 return false
87 }
88 return true
89}🍀 自己实际测试过程如下:
devops4-jenkinslib-service,我们创在Sonar.grovy文件里进行编辑:
1package org.devops
2
3def CodeScan(branchName){
4 cliPath="/usr/local/sonar-scanner/sonar-scanner-4.7.0.2747-linux/bin"
5 withCredentials([usernamePassword(credentialsId: '79d8f75b-3733-49f4-950f-19f8480fda03',
6 passwordVariable: 'SONAR_PASSWD',
7 usernameVariable: 'SONAR_USER')]) {
8 // some block
9 sh """${cliPath}/sonar-scanner \
10 -Dsonar.login=${SONAR_USER} \
11 -Dsonar.password=${SONAR_PASSWD} \
12 -Dsonar.projectVersion=${branchName}
13 """
14 }
15}
16
17def Init(projectName, lang, profileName){
18 result = ProjectSearch(projectName)
19 println(result)
20
21 if (result == false){
22 CreateProject(projectName)
23 }
24
25 UpdateQualityProfiles(lang, projectName, profileName)
26}
27
28
29
30// 查找项目
31def ProjectSearch(projectName){
32 apiUrl = "projects/search?projects=${projectName}"
33 response = SonarRequest(apiUrl,"GET")
34
35 if (response.paging.total == 0){
36 println("Project not found!.....")
37 return false
38 }
39 return true
40}
41
42
43def SonarRequest(apiUrl,method){
44 withCredentials([string(credentialsId: "66b7dd41-5434-43a3-8d02-505e2f2dc38f", variable: 'SONAR_TOKEN')]) {
45 sonarApi = "http://172.29.9.101:9000/api"
46 response = sh returnStdout: true,
47 script: """
48 curl --location \
49 --request ${method} \
50 "${sonarApi}/${apiUrl}" \
51 --header "Authorization: Basic ${SONAR_TOKEN}"
52 """
53 try {
54 response = readJSON text: """ ${response - "\n"} """
55 } catch(e){
56 response = readJSON text: """{"errors" : true}"""
57 }
58 return response
59
60 }
61}
62
63// 创建项目
64def CreateProject(projectName){
65 apiUrl = "projects/create?name=${projectName}&project=${projectName}"
66 response = SonarRequest(apiUrl,"POST")
67 try{
68 if (response.project.key == projectName ) {
69 println("Project Create success!...")
70 return true
71 }
72 }catch(e){
73 println(response.errors)
74 return false
75 }
76}
77
78// 更新项目质量配置
79def UpdateQualityProfiles(lang, projectName, profileName){
80 apiUrl = "qualityprofiles/add_project?language=${lang}&project=${projectName}&qualityProfile=${profileName}"
81 response = SonarRequest(apiUrl,"POST")
82
83 if (response.errors != true){
84 println("ERROR: UpdateQualityProfiles ${response.errors}...")
85 return false
86 } else {
87 println("SUCCESS: UpdateQualityProfiles ${lang} > ${projectName} > ${profileName}" )
88 return true
89 }
90}jenkinsfile代码:

1@Library("mylib@main") _ //加载共享库
2import org.devops.* // 导入库
3
4def checkout = new Checkout() //New实例化
5def build = new Build()
6def unittest = new UnitTest()
7def sonar = new Sonar()
8
9//env.buildType = "${JOB_NAME}".split("-")[1]
10
11//流水线
12pipeline {
13 agent { label "build" }
14
15 options {
16 skipDefaultCheckout true
17 }
18
19 stages{
20 stage("Checkout"){
21 steps{
22 script {
23 println("GetCode")
24 checkout.GetCode("${env.srcUrl}", "${env.branchName}")
25 }
26 }
27 }
28
29 stage("Build"){
30 steps{
31 script{
32 println("Build")
33 //build.CodeBuild("${env.buildType}")
34 sh "${env.buildShell}"
35
36 }
37 }
38 }
39
40 /*stage("UnitTest"){
41 steps{
42 script{
43 unittest.CodeTest("${env.buildType}")
44 }
45 }
46 }*/
47
48 stage("CodeScan"){
49 steps{
50 script{
51 profileName = "${JOB_NAME}".split("-")[0]
52 sonar.Init("${JOB_NAME}", "java", profileName)
53 sonar.CodeScan("${env.branchName}")
54 }
55
56 }
57 }
58
59 }
60}注意:也要保证devops4-maven-service项目里sonar-project.properties文件的配置正确:




符合预期。😘

目的: 掌握默认规则中的一部分规则如何激活和禁用。
质量规则、质量阈–这一般是由TeamLeader、开发人员去指定的。
进入质量配置页面, 可以看到所有的语言规则配置。在这里可以看到规则的使用情况。

这里假设我要调整Go语言的规则配置, 点击规则数量数字。


创建新的规则集:

点击更多激活规则, 进入规则设置页面。

激活或者下线规则。(活动/挂起)

使用规则: 先在页面配置项目,然后使用SonarScanner扫描。

| 💘 实践:新建SonarQube质量配置(测试成功)-2023.6.25 |
自己测试过程:
1sonarqube:9.9.0-community





完成。
目的: 适用于以质量门禁作为交付关卡。


| 💘 实践:新建SonarQube质量阈(测试成功)-2023.6.25 |
自己测试过程:
1sonarqube:9.9.0-community


找一个具有大量单元测试的项目, 然后集成jacoco插件,生成覆盖率报告,最后由sonar收集。
pom.xml里修改)添加jacoco-maven-plugin 和junit插件。
1<dependencies>
2 <dependency>
3 <groupId>org.jacoco</groupId>
4 <artifactId>jacoco-maven-plugin</artifactId>
5 <version>0.8.2</version>
6 <scope>test</scope>
7 </dependency>
8 <dependency>
9 <groupId>junit</groupId>
10 <artifactId>junit</artifactId>
11 <version>4.12</version>
12 <scope>test</scope>
13 </dependency>
14</dependencies>添加插件:
1<plugin>
2 <groupId>org.apache.maven.plugins</groupId>
3 <artifactId>maven-compiler-plugin</artifactId>
4 <version>3.6.1</version>
5 <configuration>
6 <skipMain>true</skipMain>
7 <skip>true</skip>
8 <source>1.8</source>
9 <target>1.8</target>
10 </configuration>
11</plugin>
12
13
14<plugin>
15 <groupId>org.jacoco</groupId>
16 <artifactId>jacoco-maven-plugin</artifactId>
17 <version>0.7.5.201505241946</version>
18 <executions>
19 <execution>
20 <id>prepare-agent</id>
21 <goals>
22 <goal>prepare-agent</goal>
23 </goals>
24 </execution>
25 <execution>
26 <id>report</id>
27 <phase>prepare-package</phase>
28 <goals>
29 <goal>report</goal>
30 </goals>
31 </execution>
32 <execution>
33 <id>post-unit-test</id>
34 <phase>test</phase>
35 <goals>
36 <goal>report</goal>
37 </goals>
38 <configuration>
39 <dataFile>target/jacoco.exec</dataFile>
40 <outputDirectory>target/jacoco-reports</outputDirectory>
41 </configuration>
42 </execution>
43 </executions>
44 <configuration>
45 <systemPropertyVariables>
46 <jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile>
47 </systemPropertyVariables>
48 </configuration>
49</plugin>
1# 指定代码覆盖率工具为jacoco
2sonar.core.codeCoveragePlugin=jacoco
3# 指定exec二进制文件存放路径
4sonar.jacoco.reportPaths=target/jacoco.exec 1cd devops-jacoco-service/
2sonar-scanner -Dsonar.host.url=http://192.168.1.200:9000 \
3-Dsonar.projectKey=devops-jacoco-service \
4-Dsonar.projectName=devops-jacoco-service \
5-Dsonar.projectVersion=1.0 \
6-Dsonar.login=admin \
7-Dsonar.password=admin \
8-Dsonar.ws.timeout=30 \
9-Dsonar.projectDescription="my first project!" \
10-Dsonar.links.homepage=http://www.baidu.com \
11-Dsonar.sources=src \
12-Dsonar.sourceEncoding=UTF-8 \
13-Dsonar.java.binaries=target/classes \
14-Dsonar.java.test.binaries=target/test-classes \
15-Dsonar.java.surefire.report=target/surefire-reports \
16-Dsonar.core.codeCoveragePlugin=jacoco \
17-Dsonar.jacoco.reportPaths=target/jacoco.exec


==测试效果:(失败)==—老师当时这里也是没做实际测试的!
测试时间:2023年6月25日
测试环境:
1apache-maven-3.9.2
2jenkins/jenkins:2.346.3-2-lts-jdk11
3gitlab/gitlab-ce:15.0.3-ce.0
4sonarqube:9.9.0-community
5SonarScanner 4.8.0.2856当前maven版本无jacoco插件:

构建失败:


https://github.com/mc1arke/sonarqube-community-branch-plugin/releases

将插件放到extensions/plugins 和 lib/common目录中,然后重启sonar。
1## 临时方案
2docker exec -it sonarqube bash
3cd /opt/sonarqube/lib/common
4cp ../../extensions/plugins/sonarqube-community-branch-plugin-1.3.2 ./
5exit
6
7docker restart sonarqube
8
9
10## 持久化lib目录后
11[root@zeyang-nuc-service sonarqube]# ls
12sonarqube_conf sonarqube_data sonarqube_extensions sonarqube_lib sonarqube_logs
13[root@zeyang-nuc-service sonarqube]# cp /root/sonarqube-community-branch-plugin-1.3.2.jar sonarqube_extensions/plugins/
14[root@zeyang-nuc-service sonarqube]# chmod +x sonarqube_extensions/plugins/sonarqube-community-branch-plugin-1.3.2.jar
15[root@zeyang-nuc-service sonarqube]#
16[root@zeyang-nuc-service sonarqube]#
17[root@zeyang-nuc-service sonarqube]# cp /root/sonarqube-community-branch-plugin-1.3.2.jar sonarqube_lib/common/
18[root@zeyang-nuc-service sonarqube]# chmod +x sonarqube_lib/common/sonarqube-community-branch-plugin-1.3.2.jar
19[root@zeyang-nuc-service sonarqube]#
20
21
22docker restart sonarqube
1##扫描参数增加 –Dsonar.branch.name=
2
3sonar-scanner -Dsonar.host.url=http://192.168.1.200:9000 \
4-Dsonar.projectKey=devops-maven2-service \
5-Dsonar.projectName=devops-maven2-service \
6-Dsonar.projectVersion=1.0 \
7-Dsonar.login=admin \
8-Dsonar.password=admin \
9-Dsonar.ws.timeout=30 \
10-Dsonar.projectDescription="my first project!" \
11-Dsonar.links.homepage=http://192.168.1.200/devops/devops-maven-service \
12-Dsonar.links.ci=http://192.168.1.200:8080/job/demo-pipeline-service/ \
13-Dsonar.sources=src \
14-Dsonar.sourceEncoding=UTF-8 \
15-Dsonar.java.binaries=target/classes \
16-Dsonar.java.test.binaries=target/test-classes \
17-Dsonar.java.surefire.report=target/surefire-reports \
18-Dsonar.branch.name=release-1.1.1⚠️ 注意: 需要先把主分支扫描一遍,不然会报错。
1ERROR: Error during SonarScanner execution
2ERROR: No branches currently exist in this project. Please scan the main branch without passing any branch parameters.
3ERROR:
4ERROR: Re-run SonarScanner using the -X switch to enable full debug logging.新版本插件的配置有变化,效果和使用方式不变。
1# cd /data/cicd2/sonarqube/
2# ls
3sonarqube_conf sonarqube_data sonarqube_extensions sonarqube_logs
4
5# cat sonarqube_conf/sonar.properties
6sonar.web.javaAdditionalOpts=-javaagent:./extensions/plugins/sonarqube-community-branch-plugin-1.8.1.jar=web
7sonar.ce.javaAdditionalOpts=-javaagent:./extensions/plugins/sonarqube-community-branch-plugin-1.8.1.jar=ce
8
9# ls sonarqube_extensions/plugins/
10sonar-gitlab-plugin-4.1.0-SNAPSHOT.jar sonar-l10n-zh-plugin-8.9.jar sonarqube-community-branch-plugin-1.8.0.jar11. Copy the plugin JAR file to the extensions/plugins/ directory of your SonarQube instance
2
32. Add -javaagent:./extensions/plugins/sonarqube-community-branch-plugin-${version}.jar=web to the sonar.web.javaAdditionalOptions property in your Sonarqube installation's config/sonar.properties file, e.g. sonar.web.javaAdditionalOpts=-javaagent:./extensions/plugins/sonarqube-community-branch-plugin-1.8.0.jar=web
4
53. Add -javaagent:./extensions/plugins/sonarqube-community-branch-plugin-${version}.jar=ce to the sonar.ce.javaAdditionalOptions property in your Sonarqube installation's config/sonar.properties file, e.g. sonar.ce.javaAdditionalOpts=-javaagent:./extensions/plugins/sonarqube-community-branch-plugin-1.8.0.jar=ce
6
74. Start Sonarqube, and accept the warning about using third-party plugins
| 💘 实践:SonarQube多分支代码扫描(测试成功)-2023.6.25 |

1jenkins/jenkins:2.346.3-2-lts-jdk11
2gitlab/gitlab-ce:15.0.3-ce.0
3sonarqube:9.9.0-community
4SonarScanner 4.8.0.2856
https://github.com/mc1arke/sonarqube-community-branch-plugin
本次找到1.14.0插件:


1#(1)下载插件
2[root@Devops6 ~]#cd /data/devops6/sonarqube/
3[root@Devops6 sonarqube]#ls
4sonarqube_conf sonarqube_data sonarqube_extensions sonarqube_logs
5[root@Devops6 sonarqube]#cd sonarqube_extensions/plugins/
6[root@Devops6 plugins]#ls
7sonar-l10n-zh-plugin-9.9.jar
8[root@Devops6 plugins]#wget https://gh.ddlc.top/https://github.com/mc1arke/sonarqube-community-branch-plugin/releases/download/1.14.0/sonarqube-community-branch-plugin-1.14.0.jar
9[root@Devops6 plugins]#ll -h
10total 13M
11-rw-r--r-- 1 1000 1000 69K Jun 24 08:17 sonar-l10n-zh-plugin-9.9.jar
12-rw-r--r-- 1 root root 13M Dec 31 23:46 sonarqube-community-branch-plugin-1.14.0.jar
13[root@Devops6 plugins]#
14
15#(2)更新sonar服务端的配置文件
16[root@Devops6 sonarqube]#pwd
17/data/devops6/sonarqube
18[root@Devops6 sonarqube]#ls
19sonarqube_conf sonarqube_data sonarqube_extensions sonarqube_logs
20[root@Devops6 sonarqube]#cd sonarqube_conf/
21[root@Devops6 sonarqube_conf]#ls
22[root@Devops6 sonarqube_conf]#vim sonar.properties #这里新建次文件
23sonar.web.javaAdditionalOpts=-javaagent:./extensions/plugins/sonarqube-community-branch-plugin-1.14.0.jar=web
24sonar.ce.javaAdditionalOpts=-javaagent:./extensions/plugins/sonarqube-community-branch-plugin-1.14.0.jar=ce
25
26#(3)重启sonarqube
27[root@Devops6 ~]#docker restart sonarqube9重启sonarqube完成后,就可以看到这里的项目出现了分支字样:


Sonar.groovy的代码:
1@Library("devops06@main") _
2
3//import src/org/devops/Build.groovy
4def build = new org.devops.Build()
5
6pipeline {
7 agent {label "build"}
8 stages{
9 stage("CheckOut"){
10 steps{
11 script{
12 build.CheckOut()
13 }
14 }
15 }
16
17 stage("Build"){
18 steps{
19 script{
20 build.Build()
21 }
22 }
23
24 }
25
26 stage("CodeScan"){
27 steps{
28 script{
29
30 // withCredentials([usernamePassword(credentialsId: '003d1667-653e-40f3-8103-b74614643aba',
31 // passwordVariable: 'SONAR_PASSWD',
32 // usernameVariable: 'SONAR_USER')]) {
33
34 // sh """/data/devops6/sonar-scanner-4.8.0.2856-linux/bin/sonar-scanner \
35 // -Dsonar.login=${SONAR_USER} \
36 // -Dsonar.password=${SONAR_PASSWD} \
37 // -Dsonar.host.url=http://172.29.9.101:9000
38 // """
39 // }
40
41
42 withSonarQubeEnv(credentialsId: 'bdefe5e2-62a0-4e20-bf5a-51abedfe6df1') {
43 sh """/data/devops6/sonar-scanner-4.8.0.2856-linux/bin/sonar-scanner \
44 -Dsonar.login=${SONAR_AUTH_TOKEN} \
45 -Dsonar.host.url=${SONAR_HOST_URL} \
46 -Dsonar.branch.name=${env.branchName}
47 """
48 }
49
50 }
51 }
52 }
53
54 }
55}提交。



符合预期,测试结束。😘
⚠️ 注意:
7.几,8.几的版本有这个插件,但9版本已经不支持次功能了。
提前装好插件:https://github.com/gabrie-allaigre/sonar-gitlab-plugin/tree/4.1.0-SNAPSHOT插件的说明文档查看该插件的Readme文档。 (仅质量阈失败后才可以展示扫描报告)
1# cp sonar-gitlab-plugin-4.1.0-SNAPSHOT.jar /data/cicd/sonarqube/sonarqube_extensions/plugins/
2
3# chmod +x /data/cicd/sonarqube/sonarqube_extensions/plugins/sonar-gitlab-plugin-4.1.0-SNAPSHOT.jar
4
5# docker restart sonarqube
1-Dsonar.gitlab.failure_notification_mode 值为commit-status表示更改提交状态, 值为nothing不做任何动作。 1sonar-scanner -Dsonar.host.url=http://192.168.1.200:9000 \
2-Dsonar.projectKey=devops-jacoco-service \
3-Dsonar.projectName=devops-jacoco-service \
4-Dsonar.projectVersion=1.0 \
5-Dsonar.login=0809881d71f2b06b64786ae3f81a9acf22078e8b \
6-Dsonar.ws.timeout=30 \
7-Dsonar.projectDescription="my first project!" \
8-Dsonar.links.homepage=http://www.baidu.com \
9-Dsonar.sources=src \
10-Dsonar.sourceEncoding=UTF-8 \
11-Dsonar.java.binaries=target/classes \
12-Dsonar.java.test.binaries=target/test-classes \
13-Dsonar.java.surefire.report=target/surefire-reports \
14-Dsonar.core.codeCoveragePlugin=jacoco \
15-Dsonar.jacoco.reportPaths=coverage/jacoco.exec \
16-Dsonar.gitlab.commit_sha=f898a9fdbd319e68d519aa2ff42ad80da5186103 \
17-Dsonar.gitlab.ref_name=main \
18-Dsonar.gitlab.project_id=37 \
19-Dsonar.dynamicAnalysis=reuseReports \
20-Dsonar.gitlab.failure_notification_mode=commit-status \
21-Dsonar.gitlab.url=http://192.168.1.200 \
22-Dsonar.gitlab.user_token=CwmDA_4TKevDPRh4_SEf \
23-Dsonar.gitlab.api_version=v4
| 💘 实践:扫描结果关联commitid(静态配置)(测试failed)-2022.6.3 |

自己实际测试过程:
提前装好插件:https://github.com/gabrie-allaigre/sonar-gitlab-plugin/tree/4.1.0-SNAPSHOT

1#(1)上传插件
2[root@devops ~]#ll -h sonar-gitlab-plugin-4.1.0-SNAPSHOT.jar
3-rw-r--r-- 1 root root 9.9M May 28 15:43 sonar-gitlab-plugin-4.1.0-SNAPSHOT.jar
4[root@devops ~]#docker cp sonar-gitlab-plugin-4.1.0-SNAPSHOT.jar sonarqube:/opt/sonarqube/extensions/plugins
5
6#(2)重启sonarqube容器
7[root@devops ~]#docker restart sonarqube
8sonarqube

devops4-maven-service项目下:找一次commit信息:并拷贝commitid
5abc33244088898bdfb494ed0a3fc134ab0f5c80

可以看到这里的评论是空的:


编辑,提交后构建运行,观察效果:


但是自己是没有效果的:……
好奇怪:

==老师这里是有效果的==:😥


好奇怪……😥
这里先放在这里,先进行动态配置,观察效果。
| 💘 实践:扫描结果关联commitid(动态配置)(测试成功)-2022.6.3 |


1-Dsonar.gitlab.commit_sha=f898a9fdbd319e68d519aa2ff42ad80da5186103 \
2-Dsonar.gitlab.ref_name=main \
3-Dsonar.gitlab.project_id=37 \
4-Dsonar.dynamicAnalysis=reuseReports \
5-Dsonar.gitlab.failure_notification_mode=commit-status \
6-Dsonar.gitlab.url=http://192.168.1.200 \
7-Dsonar.gitlab.user_token=CwmDA_4TKevDPRh4_SEf \
8-Dsonar.gitlab.api_version=v41//获取CommitID
2def GetCommitID(){
3 ID = sh returnStdout: true, script:"git rev-parse HEAD"
4 return ID -"\n"
5}
6
7[root@devops devops4-maven-service]#git rev-parse HEAD
8b1087191a26bf36b7f77f31093a9e226a8846674因为我们是有规范的,jenkins的作业name和gitlab的项目是保持一致的:


1curl --location --request GET 'http://172.29.9.101/api/v4/projects?search=devops4-maven-service' \
2--header 'PRIVATE-TOKEN: MhEV52bNpbUnnSfNg1nc' \
3--header 'Authorization: Basic YWRtaW46YWRtaW4xMjM='如果获取一个不存在的项目的话,这里返回值为空。

完整代码:
1pipeline {
2 agent {
3 label "build"
4 }
5
6 stages {
7 stage("Run") {
8 steps{
9 script{
10 commitID = GetCommitID()
11 groupName = "${JOB_NAME}".split('-')[0]
12 projectID = GetProjectID("${JOB_NAME}", groupName)
13
14 println("commitID: ${commitID}")
15 println("projectID: ${projectID}")
16 }
17 }
18 }
19 }
20}
21
22//获取CommitID
23def GetCommitID(){
24 ID = sh returnStdout: true, script:"git rev-parse HEAD"
25 return ID -"\n"
26}
27
28//获取ProjectID
29// fork
30// namespace
31// usera/devops-service-app
32// userb/devops-service-app
33def GetProjectID(projectName, groupName){
34 response = sh returnStdout: true,
35 script: """
36 curl --location --request GET \
37 http://172.29.9.101/api/v4/projects?search=${projectName} \
38 --header 'PRIVATE-TOKEN: MhEV52bNpbUnnSfNg1nc' \
39 --header 'Authorization: Basic YWRtaW46YWRtaW4xMjM='
40 """
41 response = readJSON text: response
42 if (response != []){
43 for (p in response) {
44 if (p["namespace"]["name"] == groupName){
45 return response[0]["id"]
46 }
47 }
48 }
49}运行后效果如下:

符合预期,但是注意下,这个commitID好像不是最新一次的commitID……
共享库例的代码如下:
Jenkinsfile
1@Library("mylib@main") _ //加载共享库
2import org.devops.* // 导入库
3
4def checkout = new Checkout() //New实例化
5def build = new Build()
6def unittest = new UnitTest()
7def sonar = new Sonar()
8def gitcli = new GitLab()
9
10//env.buildType = "${JOB_NAME}".split("-")[1]
11
12//流水线
13pipeline {
14 agent { label "build" }
15
16 options {
17 skipDefaultCheckout true
18 }
19
20 stages{
21 stage("Checkout"){
22 steps{
23 script {
24 println("GetCode")
25 checkout.GetCode("${env.srcUrl}", "${env.branchName}")
26 }
27 }
28 }
29
30 stage("Build"){
31 steps{
32 script{
33 println("Build")
34 //build.CodeBuild("${env.buildType}")
35 sh "${env.buildShell}"
36
37 }
38 }
39 }
40
41 /*stage("UnitTest"){
42 steps{
43 script{
44 unittest.CodeTest("${env.buildType}")
45 }
46 }
47 }*/
48
49 stage("CodeScan"){
50 steps{
51 script{
52 profileName = "${JOB_NAME}".split("-")[0]
53 sonar.Init("${JOB_NAME}", "java", profileName)
54
55
56 //commit-status
57 commitID = gitcli.GetCommitID()
58 groupName =profileName
59 projectID = gitcli.GetProjectID("${JOB_NAME}", groupName)
60 sonar.CodeScan("${env.branchName}", commitID, projectID)
61 }
62
63 }
64 }
65
66 }
67}
GitLab.groovy

1package org.devops
2
3//获取CommitID
4def GetCommitID(){
5 ID = sh returnStdout: true, script:"git rev-parse HEAD"
6 return ID -"\n"
7}
8
9//获取ProjectID
10// fork
11// namespace
12// usera/devops-service-app
13// userb/devops-service-app
14def GetProjectID(projectName, groupName){
15 response = sh returnStdout: true,
16 script: """
17 curl --location --request GET \
18 http://172.29.9.101/api/v4/projects?search=${projectName} \
19 --header 'PRIVATE-TOKEN: MhEV52bNpbUnnSfNg1nc' \
20 --header 'Authorization: Basic YWRtaW46YWRtaW4xMjM='
21 """
22 response = readJSON text: response
23 if (response != []){
24 for (p in response) {
25 if (p["namespace"]["name"] == groupName){
26 return response[0]["id"]
27 }
28 }
29 }
30}可以看到,构建成功:

在gitlab的devops4-maven-service项目的commit查看效果:

符合预期,测试结束。😘
1stage("SonarScan"){
2 when {
3 environment name: 'skipSonar', value: 'false'
4 }
5}

| 💘 实践:SonarQube控制代码扫描步骤运行(测试成功)-2023.6.25 |
自己测试过程:
1jenkins/jenkins:2.346.3-2-lts-jdk11
2gitlab/gitlab-ce:15.0.3-ce.0
3sonarqube:9.9.0-community
4SonarScanner 4.8.0.2856实验软件(无)
修改jenkins共享库里的代码:
修改Jenkinsfile共享库里的下代码,添加when片段:

devops6-maven-servicepipeline里添加选项参数:
不扫描代码:



扫描代码:


可以看到,本次就跳过代码扫描了。
测试结束。😘
sonarQube也很危险,之前暴露过很多漏洞,因为你的源代码也会在sonarQube里保留下来。
1SonarQube:
2之前6版本还支持Mysql,现在的7版本不支持Mysql了,也是Jdk11了;
3
4要升级的话:
51.jdk要升级到jdk11;
62.数据库:要做迁移的;
7
8多分支代码扫描是企业版本的一个特性,但开源版本有一个插件,可以实现这个功能。snoar:代码扫描工具
sonar 代码质量检查:硬编码检查,安全检查,单元测试是否通过,代码质量
snoar:
旧项目:还是算了哈哈。(一扫就扫除很多bug哈哈) 需要有一个宽容的规范,例如对于旧的项目,我们只需要考虑新增代码的质量,然后你再慢慢去改这个旧代码。
新项目:用sonar去扫描,很容易改;一开始,就开发按照这个语言规范去写,基本上就没有什么问题;
SonQuar:5-9版本
企业里,6版本应该用的比较多些。
6版本是支持mysql的。
但7版本后,不支持mysql了。

jdk版本需要注意:
从7开始,jdk就11以上了。

Mysql–>迁移到 PG数据库。

课程里使用docker安装的SonarQube。


SonarQube中各种语言的扫描规则都是以jar包的方式。在SonarQube8.9.1之前版本,默认没有安装语言规则插件, 需要手动安装。 服务端安装Java Code Quality and Security,SonarJS SonarGO 插件,并重启服务器。(如果这里由于网速原因下载不了插件,可以使用课程提供的压缩包,解压到downloads目录下然后重启sonarqube)
由于本次实验使用的是SonarQube8.9.1版本,所以不用在手动安装语言插件了。

1[root@devops ~]#docker exec -it sonarqube bash
2bash-5.1# cd /opt/sonarqube/lib/extensions/
3bash-5.1# ls
4sonar-csharp-plugin-8.22.0.31243.jar sonar-jacoco-plugin-1.1.1.1157.jar sonar-python-plugin-3.4.1.8066.jar
5sonar-css-plugin-1.4.2.2002.jar sonar-java-plugin-6.15.1.26025.jar sonar-ruby-plugin-1.8.3.2219.jar
6sonar-flex-plugin-2.6.1.2564.jar sonar-javascript-plugin-7.4.4.15624.jar sonar-scala-plugin-1.8.3.2219.jar
7sonar-go-plugin-1.8.3.2219.jar sonar-kotlin-plugin-1.8.3.2219.jar sonar-vbnet-plugin-8.22.0.31243.jar
8sonar-html-plugin-3.4.0.2754.jar sonar-php-plugin-3.17.0.7439.jar sonar-xml-plugin-2.2.0.2973.jar
9bash-5.1# 如果低于该版本,可以参考如下操作。(可选,跳过)
1[root@zeyang-nuc-service ~]# cd /data/cicd/plugin-sonar/
2[root@zeyang-nuc-service plugin-sonar]# ls
3sonar-go-plugin-1.6.0.719.jar sonar-l10n-zh-plugin-1.29.jar
4sonar-java-plugin-6.3.2.22818.jar sonar-typescript-plugin-2.1.0.4359.jar
5sonar-javascript-plugin-6.2.2.13315.jar
6[root@zeyang-nuc-service plugin-sonar]# cp sonar-go-plugin-1.6.0.719.jar sonar-java-plugin-6.3.2.22818.jar sonar-javascript-plugin-6.2.2.13315.jar sonar-typescript-plugin-2.1.0.4359.jar /data/cicd/sonarqube/sonarqube_extensions/downloads/
7[root@zeyang-nuc-service plugin-sonar]# ls /data/cicd/sonarqube/sonarqube_extensions/downloads/
8sonar-go-plugin-1.6.0.719.jar sonar-javascript-plugin-6.2.2.13315.jar
9sonar-java-plugin-6.3.2.22818.jar sonar-typescript-plugin-2.1.0.4359.jar
10[root@zeyang-nuc-service plugin-sonar]# chmod +x /data/cicd/sonarqube/sonarqube_extensions/downloads/*
11[root@zeyang-nuc-service plugin-sonar]# ls /data/cicd/sonarqube/sonarqube_extensions/downloads/
12sonar-go-plugin-1.6.0.719.jar sonar-javascript-plugin-6.2.2.13315.jar
13sonar-java-plugin-6.3.2.22818.jar sonar-typescript-plugin-2.1.0.4359.jar
14[root@zeyang-nuc-service plugin-sonar]# docker restart sonarqube
15sonarqube
🍀 老师之前写的一个python代码,可以拿来即用:
1import os
2import requests
3import json
4import sys
5
6
7class SonarQube(object):
8 def __init__(self, project_name, lang, profile_name, cmds):
9 self.server_api = "http://192.168.1.200:9000/api/"
10 self.auth_token = "YWRtaW46YWRtaW4xMjM="
11 self.project_name = project_name
12 self.lang = lang
13 self.profile_name = profile_name
14 self.cmds = cmds
15
16 def http_req(self, method, apiUrl):
17 url = self.server_api + apiUrl
18 payload={}
19 headers = {
20 'Authorization': 'Basic ' + self.auth_token
21 }
22 response = requests.request(method, url, headers=headers, data=payload)
23 print(response.text)
24
25 if response.text != "":
26 data = json.loads(response.text)
27 return data
28 return {}
29
30
31 def SearchProject(self):
32 """查找项目"""
33 url = "projects/search?projects=" + self.project_name
34 response = self.http_req("GET", url)
35 if response["paging"]["total"] == 0:
36 return False
37 return True
38
39 def CreateProject(self):
40 """创建项目"""
41 apiUrl = "projects/create?name={0}&project={1}".format(self.project_name, self.project_name)
42 response = self.http_req("POST", apiUrl)
43 try:
44 if response["project"]["key"] == self.project_name:
45 return True
46 except Exception as e :
47 print(e)
48 print(response["errors"])
49 return False
50
51 def UpdateQualityProfiles(self):
52 apiUrl = "qualityprofiles/add_project?language={0}&project={1}&qualityProfile={2}".format(
53 self.lang, self.project_name, self.profile_name)
54
55 response = self.http_req("POST", apiUrl)
56
57 try :
58 print("ERROR: UpdateQualityProfiles{0}...".format(response["errors"]))
59 return False
60 except Exception as e :
61 print(e)
62 print("SUCCESS: UpdateQualityProfiles {0} > {1} > ${2}".format(
63 self.lang, self.project_name, self.profile_name))
64 return True
65
66
67 def SonarScan(self):
68 result = os.system(self.cmds)
69 if result == 0:
70 return True
71 return False
72
73
74 def run(self):
75 if not self.SearchProject():
76 self.CreateProject()
77 self.UpdateQualityProfiles()
78 return self.SonarScan()
79
80if __name__ == '__main__':
81 lang = sys.argv[1]
82 profile_name = sys.argv[2]
83 CI_PROJECT_NAME, CI_COMMIT_SHA, SONAR_AUTH_TOKEN,CI_PROJECT_TITLE,CI_PROJECT_URL,CI_PIPELINE_URL,CI_COMMIT_REF_NAME,CI_PROJECT_ID,CI_SERVER_URL ,GITLAB_ADMIN_TOKEN = sys.argv[3:]
84 print(CI_PROJECT_NAME)
85 sonarcmds = """
86sonar-scanner \
87-Dsonar.host.url=http://192.168.1.200:9000 \
88-Dsonar.projectKey={0} \
89-Dsonar.projectName={0} \
90-Dsonar.projectVersion={1} \
91-Dsonar.login={2} \
92-Dsonar.ws.timeout=30 \
93-Dsonar.projectDescription={3} \
94-Dsonar.links.homepage={4} \
95-Dsonar.links.ci={5} \
96-Dsonar.sources=src \
97-Dsonar.sourceEncoding=UTF-8 \
98-Dsonar.java.binaries=target/classes \
99-Dsonar.java.test.binaries=target/test-classes \
100-Dsonar.java.surefire.report=target/surefire-reports \
101-Dsonar.core.codeCoveragePlugin=jacoco \
102-Dsonar.jacoco.reportPaths=target/jacoco.exec \
103-Dsonar.gitlab.commit_sha={1} \
104-Dsonar.gitlab.ref_name={6} \
105-Dsonar.gitlab.project_id={7} \
106-Dsonar.dynamicAnalysis=reuseReports \
107-Dsonar.gitlab.failure_notification_mode=nothing \
108-Dsonar.gitlab.url={8} \
109-Dsonar.gitlab.user_token={9} \
110-Dsonar.gitlab.api_version=v4
111""".format(
112CI_PROJECT_NAME,
113CI_COMMIT_SHA,
114SONAR_AUTH_TOKEN,
115CI_PROJECT_TITLE,
116CI_PROJECT_URL,
117CI_PIPELINE_URL,
118CI_COMMIT_REF_NAME,
119CI_PROJECT_ID,
120CI_SERVER_URL,
121GITLAB_ADMIN_TOKEN)
122
123 result = SonarQube(CI_PROJECT_NAME, lang, profile_name, sonarcmds ).run()
124 print(result)1python3 sonarqube.py \
2"java" "devops03" "devops-test" "99d098ef066b79d577a98220a17959465f4dd750" "9e7e39a14a96bc886fdde43388b91e810491b7dc" "devops" "http://192.168.1.200/devops/devops-maven-service" "http://192.168.1.200:8080/job/demo-pipeline-service/" "master" "5" "http://192.168.1.200" "apF1R9s9JJBYJzLF5mYd" 1include:
2 - project: 'devops03/devops03-gitlabci-lib'
3 ref: main
4 file:
5 - '/jobs/CI.yaml'
6
7workflow:
8 rules:
9 - if: $CI_PIPELINE_SOURCE == "web"
10 when: always
11 - if: $CI_COMMIT_BEFORE_SHA == "0000000000000000000000000000000000000000"
12 when: never
13 - when: always
14
15variables:
16 GIT_CHECKOUT: "false" ## 全局关闭作业代码下载
17 BUILD_SHELL: "mvn clean package -DskipTests -s settings.xml" ## 构建命令
18 TEST_SHELL: "mvn test -s settings.xml" ## 测试命令
19 ARTIFACT_PATH: "target/*.jar" ## 制品路径
20 TEST_REPORTS: "target/surefire-reports/TEST-*.xml" ## 测试报告
21
22stages:
23 - build
24 - test
25 - sonarscan
26
27pipelineInit:
28 extends:
29 - .pipelineInit
30
31cibuild:
32 extends:
33 - .cibuild
34
35citest:
36 extends:
37 - .citest
38sonarscan:
39 tags:
40 - build
41 stage: sonarscan
42 script:
43 |-
44 curl "http://192.168.1.200/devops03/devops03-gitlabci-lib/-/raw/main/utils/SonarQube.py" \
45 -o sonarqube.py -s
46 python sonarqube.py "java" ${CI_PROJECT_ROOT_NAMESPACE} ${CI_PROJECT_NAME} ${CI_COMMIT_SHA} \
47 ${SONAR_AUTH_TOKEN} ${CI_PROJECT_TITLE} ${CI_PROJECT_URL} ${CI_PIPELINE_URL} ${CI_COMMIT_REF_NAME} \
48 ${CI_PROJECT_ID} ${CI_SERVER_URL} ${GITLAB_ADMIN_TOKEN}
49 🍀 自己本次使用gitlabci测试
sonar-project.properties文件的一些代码:
devops4-gitlablib-service
就是把jenkins里的代码拿过来就好:

修改jobs/CI.yml:
这里找一下gitlab的变量:
https://docs.gitlab.com/ee/ci/variables/predefined_variables.html



MhEV52bNpbUnnSfNg1nc


1 -Dsonar.branch.name=${CI_COMMIT_BRANCH} \
2 -Dsonar.gitlab.commit_sha=${CI_COMMIT_SHA} \
3 -Dsonar.gitlab.ref_name=${CI_COMMIT_BRANCH} \
4 -Dsonar.gitlab.project_id=${CI_PROJECT_ID} \
5 -Dsonar.dynamicAnalysis=reuseReports \
6 -Dsonar.gitlab.failure_notification_mode=commit-status \
7 -Dsonar.gitlab.url=http://172.29.9.101 \
8 -Dsonar.gitlab.user_token=${GITLAB_TOKEN} \
9 -Dsonar.gitlab.api_version=v4


符合预期,测试结束。😘
我的博客主旨:
🍀 微信二维码 x2675263825 (舍得), qq:2675263825。

🍀 微信公众号 《云原生架构师实战》

🍀 语雀
https://www.yuque.com/xyy-onlyone

🍀 csdn https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421

🍀 知乎 https://www.zhihu.com/people/foryouone

好了,关于本次就到这里了,感谢大家阅读,最后祝大家生活快乐,每天都过的有意义哦,我们下期见!

日历 · 精选 · 友链 · 更多
如果内容对你有帮助,欢迎请我喝杯咖啡 ☕



One的公众号
爱折腾博客的小白