14
votes

Version of SonarQube = 5.2

So I noticed that my application was failing a quality gate in sonar but the build was still going green.

I googled how to make sonar fail the build and got results for a plugin called "build breaker" which has been depreciated for the version I'm using (http://docs.sonarqube.org/display/PLUG/Build+Breaker+Plugin). I cant find information on how to achieve the same build breaking behaviour in this version.

I cant seen any Jenkins plugin options that achieve this build breaking functionality ether.

Any help with this would be greatly appreciated!

Could I also suggest that someone with reputation over 1500 create a new tag for this version of sonarqube (sonarqube5.2).

6

6 Answers

5
votes

There is no direct functionality in 5.2, either built-in or via plugins, to allow this, but it can be accomplished via web serivces, but

  1. You'll have to implement your own Jenkins plugin (or a complicated scripting step) to do it.
  2. In 5.2 the security implications are unattractive. They're better in 5.3

To roll your own

Take a look at the end of your analysis log. You'll see it includes a line like

[INFO] More about the report processing at http://your.sonarqube.server/api/ce/task?id=[guid]

Check the "sonar" directory created during analysis for a report-task.txt file to pick up that guid; it's the ceTaskId value.

In 5.2 If you have global admin perms you can click-through on that link to get the current processing status of the analysis report. In 5.3 you only need execute analysis perms. A "done" report looks like this:

{"task":{"id":"AVExRaJddM_jFJ3_Fp09","type":"REPORT","componentId":"c81cfb77-7bb8-4ea6-ac84-dfee43b43b99","componentKey":"org.apache.asyncweb:asyncweb-parent","componentName":"Apache Asyncweb Parent","componentQualifier":"TRK","status":"SUCCESS","submittedAt":"2015-11-22T23:17:05+0100","submitterLogin":"XXXX","startedAt":"2015-11-22T23:17:07+0100","executedAt":"2015-11-22T23:17:15+0100","executionTimeMs":7677,"logs":true}}

Once you get to status SUCCESS, you could then use web services to query the project's quality gate status.

So it's doable, but in 5.2 only if you want to configure a global-admin-level user's credentials to do it with. In 5.3 it gets better.

Edit for 6.2

6.2 adds webhooks. You can configure up to 10 global and up to 10 project-level URLs to be POSTed to after analysis report processing is complete. The post body is a JSON payload that includes project identifiers, and quality gate status.

4
votes

A quick workaround, add a post step Execute shell script :

if [ "\`curl -sL -w %{http_code} http://sonar_host/api/qualitygates/project_status?projectKey=project_key -o /dev/null -S --quiet 2>&1 | jsawk -a 'return this.status'\`" == "ERROR" ]; 
then 
  exit 1; 
fi;
4
votes

You can use Jenkins' Quality Gates plugin for it.

It will provide you 'Quality Gates' as a post-build option. You should then just fill in your project key from SonarQube. Remember, it will fail your Jenkins job both in cases of warning or failure on your quality gate.

1
votes

An even quicker workaround, with only the native shell tools (jsawk must be installed extra)

#!/bin/bash                                                                                                                                                                                     
CURL='/usr/bin/curl'
RVMHTTP="http://sonar:9000/sonar/api/qualitygates/project_status?projectKey=PROJECTKEY"
CURLARGS="-u mysonaruser:mysonarpass"

# you can store the result in a variable
raw="$($CURL $CURLARGS $RVMHTTP)"

if [[ $raw = *"\"status\":\"ERROR\""* ]]; then
  exit 1
else
  exit 0
fi 

The PROJECTKEY your can find out via curl -u mysonaruser:mysonarpass http://sonar:9000/sonar/api/projects/index"

1
votes

I'm using pipeline and I'm checking sonar in a separate stage as follows:

import groovy.json.JsonSlurperClassic

pipeline {
....
stage('Check Sonar') {
            steps {
                withMaven(maven: 'maven-3.3.9') {
                    withSonarQubeEnv('SonarQube') {
                        sh 'mvn clean install sonar:sonar -Dsonar.scm.disabled=true -Dsonar.host.url=$SONAR_HOST_URL'
                    }
                }
                timeout(1) {
                    waitUntil {
                        script {
                            fileExists('target/sonar/report-task.txt')
                        }
                    }
                    waitUntil {
                        script {
                            def taskId = readFile('target/sonar/report-task.txt').split("\n")[3].split("=")[1]
                            def task_response = httpRequest "https://sonarUrl.com/api/ce/task?id=${taskId}"
                            def task_data = new JsonSlurperClassic().parseText(task_response.content)
                            return (task_data.task.status.equals("SUCCESS"))
                        }
                    }
                }
                script {
                    def response = httpRequest "https://sonarUrl.com/api/qualitygates/project_status?projectKey=XXX"
                    def data = new JsonSlurperClassic().parseText(response.content)
                    if (data.projectStatus.status == "ERROR") {
                        error("Sonar Quality Gate not met. Check https://sonarUrl.com/overview?id=XXX")
                    }
                }
            }
        }
0
votes

I was also facing this issue, we dont use Jenkins Pipeline jobs so using below stage was not an option for me

stage("Quality gate") {
            steps {
                waitForQualityGate abortPipeline: true
            }
        }

And I didn't want to use some custom shell script execution to check using Sonar WEB APIs as its not standard, plus I then had to configure this in multiple jobs and in future for any new Job this has to be remembered so kind of not scalable solution in my opinion.

So, I explored Jenkins plugins to solve the problem. There are few like below however both have known vulnerability of Credentials Transmitting in plain text.

enter image description here

So, further more analysis and I found the right way of doing it. There is a BuildBreaker plugin from SonarQube itself. Read more about this @ https://github.com/adnovum/sonar-build-breaker

This can be installed from the SonarQube market place enter image description here

Once you opt to install, it will be downloaded and shown as Installation Pending as the installation would reflect on the restart of SonarQube Server

So, you have to connect to SonarQube Server and Restart the Server.

Once done it will by default break the Jenkins build with errors similar to below

10:43:54 INFO: Executing post-job 'Forbidden Configuration Breaker'
10:43:54 INFO: Executing post-job 'Quality Gate Breaker'
10:43:54 INFO: Waiting for report processing to complete...
10:44:04 INFO: Quality gate status: ERROR
10:44:04 ERROR: Reliability Rating on New Code: 3 > 1
10:44:04 ERROR: [BUILD BREAKER] Project did not meet 1 conditions
10:44:05 INFO: ------------------------------------------------------------------------
10:44:05 INFO: EXECUTION FAILURE
10:44:05 INFO: ------------------------------------------------------------------------
10:44:05 INFO: Total time: 59.701s
10:44:05 INFO: Final Memory: 86M/2627M
10:44:05 INFO: ------------------------------------------------------------------------
10:44:05 ERROR: Error during SonarQube Scanner execution
10:44:05 java.lang.IllegalStateException: Project does not pass the quality gate.

Good part is, this behaviour can be controlled by a config which goes in sonar-project.properties. If this is set to true then the build will not break. By default the build will break

sonar.buildbreaker.skip=true

So, this way is more configurable, generic and useful.