Integrating SonarQube Quality Management Platform with DevOps Pipelines
This guide explains how to integrate SonarQube into a DevOps workflow by using its REST API, creating reusable shared library functions, configuring multi‑branch analysis, and automating quality gate checks within a CI/CD pipeline.
This chapter introduces the integration of the SonarQube quality management platform into a DevOps pipeline, targeting developers interested in continuous integration and quality assurance.
Why use the SonarQube API? When multiple quality gates exist, new projects default to the system‑wide gate, which may not match the desired thresholds. By invoking the API before scanning, you can set a specific quality gate for each project.
API Reference
// Find project
api/projects/search?projects=${projectName}
// Create project
api/projects/create?name=${projectName}&project=${projectName}
// Update language quality profile
api/qualityprofiles/add_project?language=${language}&qualityProfile=${qualityProfile}&project=${projectName}
// Apply project permissions
api/permissions/apply_template?projectKey=${projectKey}&templateName=${templateName}
// Update quality gate
api/qualitygates/select?projectKey=${projectKey}&gateId=${gateId}Shared Library Implementation (Groovy)
package org.devops
// HTTP wrapper
def HttpReq(reqType, reqUrl, reqBody){
def sonarServer = "http://192.168.1.200:30090/api"
result = httpRequest authentication: 'sonar-admin-user',
httpMode: reqType,
contentType: "APPLICATION_JSON",
consoleLogResponseBody: true,
ignoreSslErrors: true,
requestBody: reqBody,
url: "${sonarServer}/${reqUrl}"
return result
}
// Get project quality gate status
def GetProjectStatus(projectName){
apiUrl = "project_branches/list?project=${projectName}"
response = HttpReq("GET", apiUrl, '')
response = readJSON text: "${response.content}"
return response["branches"][0]["status"]["qualityGateStatus"]
}
// Search Sonar project
def SearchProject(projectName){
apiUrl = "projects/search?projects=${projectName}"
response = HttpReq("GET", apiUrl, '')
response = readJSON text: "${response.content}"
return response["paging"]["total"] == "0" ? "false" : "true"
}
// Create Sonar project
def CreateProject(projectName){
apiUrl = "projects/create?name=${projectName}&project=${projectName}"
response = HttpReq("POST", apiUrl, '')
println(response)
}
// Configure quality profile for a project
def ConfigQualityProfiles(projectName, lang, qpName){
apiUrl = "qualityprofiles/add_project?language=${lang}&project=${projectName}&qualityProfile=${qpName}"
response = HttpReq("POST", apiUrl, '')
println(response)
}
// Get quality gate ID by name
def GetQualityGateId(gateName){
apiUrl = "qualitygates/show?name=${gateName}"
response = HttpReq("GET", apiUrl, '')
response = readJSON text: "${response.content}"
return response["id"]
}
// Apply quality gate to a project
def ConfigQualityGates(projectName, gateName){
gateId = GetQualityGateId(gateName)
apiUrl = "qualitygates/select?gateId=${gateId}&projectKey=${projectName}"
response = HttpReq("POST", apiUrl, '')
println(response)
}Pipeline Usage Example
stage("QA"){
steps {
script{
// Search project
result = sonarapi.SearchProject("${JOB_NAME}")
println(result)
// Create if not exists
if (result == "false"){
println("${JOB_NAME}---project not found, creating...")
sonarapi.CreateProject("${JOB_NAME}")
} else {
println("${JOB_NAME}---project already exists!")
}
// Configure quality profile
qpName = "${JOB_NAME}".split("-")[0]
sonarapi.ConfigQualityProfiles("${JOB_NAME}", "java", qpName)
// Apply quality gate
sonarapi.ConfigQualityGates("${JOB_NAME}", qpName)
// Run Sonar scan
sonar.SonarScan("test", "${JOB_NAME}", "${JOB_NAME}", "src")
sleep 30
// Retrieve scan result
result = sonarapi.GetProjectStatus("${JOB_NAME}")
println(result)
if (result.toString() == "ERROR"){
error "Quality gate failed! Please fix issues."
} else {
println(result)
}
}
}
}Multi‑Branch Configuration – Place the SonarQube scanner plugin in the appropriate directories, restart SonarQube, and add the -Dsonar.branch.name= parameter to the scan command to enable branch‑specific analysis. Screenshots in the original document illustrate the plugin placement, parameter addition, and resulting scan reports.
DevOps Cloud Academy
Exploring industry DevOps practices and technical expertise.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.