本章主要通过SonarSQube API在pipeline第一次执行时就指定自定义的质量配置和质量阈
API 文档:http://192.168.1.134:9000/web_api
一、编写sonar API(sonarapi.groovy)
注意替换代码中sonarserve的地址及认证凭据,凭据创建见上一章节
package org.devops //封装HTTP def HttpReq(reqType,reqUrl,reqBody){ def sonarServer = "http://192.168.1.134:9000/api" result = httpRequest authentication: 'sonar-admin', httpMode: reqType, contentType: "APPLICATION_JSON", consoleLogResponseBody: true, ignoreSslErrors: true, requestBody: reqBody, url: "${sonarServer}/${reqUrl}" //quiet: true return result } //获取Sonar质量阈状态 def GetProjectStatus(projectName){ // http://192.168.1.134:9000/api/project_branches/list?project=demo-maven-service // {"branches":[{"name":"main","isMain":true,"type":"BRANCH","status":{"qualityGateStatus":"OK"},"analysisDate":"2023-03-15T21:54:57+0800","excludedFromPurge":true}]} apiUrl = "project_branches/list?project=${projectName}" response = HttpReq("GET",apiUrl,'') response = readJSON text: """${response.content}""" result = response["branches"][0]["status"]["qualityGateStatus"] //println(response) return result } //获取Sonar质量阈状态(多分支) def GetProjectStatus(projectName,branchName){ apiUrl = "qualitygates/project_status?projectKey=${projectName}&branch=${branchName}" response = HttpReq("GET",apiUrl,'') response = readJSON text: """${response.content}""" result = response["projectStatus"]["status"] //println(response) return result } //搜索Sonar项目 def SerarchProject(projectName){ apiUrl = "projects/search?projects=${projectName}" response = HttpReq("GET",apiUrl,'') response = readJSON text: """${response.content}""" result = response["paging"]["total"] if(result.toString() == "0"){ return "false" } else { return "true" } } //创建Sonar项目 def CreateProject(projectName){ apiUrl = "projects/create?name=${projectName}&project=${projectName}" response = HttpReq("POST",apiUrl,'') println(response) } //配置项目质量规则 def ConfigQualityProfiles(projectName,lang,qpname){ apiUrl = "qualityprofiles/add_project?language=${lang}&project=${projectName}&qualityProfile=${qpname}" response = HttpReq("POST",apiUrl,'') println(response) } //获取质量阈ID def GetQualtyGateId(gateName){ apiUrl= "qualitygates/show?name=${gateName}" response = HttpReq("GET",apiUrl,'') response = readJSON text: """${response.content}""" result = response["id"] return result } //配置项目质量阈 def ConfigQualityGates(projectName,gateName){ gateId = GetQualtyGateId(gateName) apiUrl = "qualitygates/select?gateId=${gateId}&projectKey=${projectName}" response = HttpReq("POST",apiUrl,'') println(response)println(response) }
二、jenkinsfile
qpName为项目质量规则和质量阈的名称,请自行替换
#!groovy @Library('jenkinslibrary@master') _ // shareLibrary 函数 def build = new org.devops.build() def deploy = new org.devops.deploy() def tools = new org.devops.tools() def gitlab = new org.devops.gitlab() def toemail = new org.devops.toemail() def sonar = new org.devops.sonarqube() def sonarapi = new org.devops.sonarapi() // jenkins 配置参数 String srcUrl = "${env.srcUrl}" String branchName = "${env.branchName}" String buildType = "${env.buildType}" String buildShell = "${env.buildShell}" // 判断本次job是gitlab自动提交触发还是jenkins手动触发 branch是eneric Webhook Trigger 定义的参数,值$.ref是 refs/heads/ + 本次提交的分支,所以最后需要删除refs/heads/ // currentBuild是全局环境变量,流水线语法可以查看 if("${runOpts}" == "GitlabPush"){ branchName = branch - "refs/heads/" currentBuild.description = "Trigger by ${userName} ${branch}" gitlab.ChangeCommitStatus(projectId,commitSha,"running") } pipeline { agent any stages { stage("CheckOut"){ steps{ script{ println("${branchName}") tools.PrintMes("获取代码","green") checkout scmGit(branches: [[name: "${branchName}"]], extensions: [], userRemoteConfigs: [[credentialsId: 'e7054d0e-275e-48ca-8188-e69da2faffb8', url: "${srcUrl}"]]) } } } stage("Build"){ steps{ script { tools.PrintMes("编译打包","blue") build.Build(buildType,buildShell) } } } stage("QA"){ steps { script{ tools.PrintMes("搜索项目","green") result = sonarapi.SerarchProject("${JOB_NAME}") println(result) if (result == "false"){ println("${JOB_NAME}---项目不存在,准备创建项目---> ${JOB_NAME}!") sonarapi.CreateProject("${JOB_NAME}") } else { println("${JOB_NAME}---项目已存在!") } tools.PrintMes("配置项目质量规则","green") // qpName="${JOB_NAME}".split("-")[0] //Sonar%20way Sonar/way qpName="demo-java" sonarapi.ConfigQualityProfiles("${JOB_NAME}","java",qpName) tools.PrintMes("配置质量阈","green") sonarapi.ConfigQualityGates("${JOB_NAME}",qpName) tools.PrintMes("代码扫描","green") sonar.SonarScan("test","${JOB_NAME}","${JOB_NAME}","src") sleep 30 tools.PrintMes("获取扫描结果","green") result = sonarapi.GetProjectStatus("${JOB_NAME}") println(result) if (result.toString() == "ERROR"){ toemail.Email("代码质量阈错误!请及时修复!",userEmail) error " 代码质量阈错误!请及时修复!" } else { println(result) } } } } } post { always{ script{ println("一直执行") } } success{ script{ println("成功") gitlab.ChangeCommitStatus(projectId,commitSha,"success") toemail.Email("流水线成功",userEmail) } } aborted{ script{ println("取消") gitlab.ChangeCommitStatus(projectId,commitSha,"canceled") } } failure{ script{ println("失败") gitlab.ChangeCommitStatus(projectId,commitSha,"failed") toemail.Email("流水线失败",userEmail) } } } }
三、验证
如果项目已存在请删除sonar项目后重新运行流水线查看