jenkins学习笔记之十五:SonarSQube API使用
本章主要通过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项目后重新运行流水线查看
"一劳永逸" 的话,有是有的,而 "一劳永逸" 的事却极少