How to react on SonarQube Quality Gate within Jenkins Pipeline

Based on Vincent's answer, and using Pipeline utility steps, here's my updated version that worked for me (using sonarscanner report file) :

   withSonarQubeEnv('SONAR 6.4') {
                    sh "${scannerHome}/bin/sonar-scanner"
                    sh "cat .scannerwork/report-task.txt"
                    def props = readProperties  file: '.scannerwork/report-task.txt'
                    echo "properties=${props}"
                    def sonarServerUrl=props['serverUrl']
                    def ceTaskUrl= props['ceTaskUrl']
                    def ceTask
                    timeout(time: 1, unit: 'MINUTES') {
                        waitUntil {
                            def response = httpRequest ceTaskUrl
                            ceTask = readJSON text: response.content
                            echo ceTask.toString()
                            return "SUCCESS".equals(ceTask["task"]["status"])
                        }
                    }
                    def response2 = httpRequest url : sonarServerUrl + "/api/qualitygates/project_status?analysisId=" + ceTask["task"]["analysisId"], authentication: 'jenkins_scanner'
                    def qualitygate =  readJSON text: response2.content
                    echo qualitygate.toString()
                    if ("ERROR".equals(qualitygate["projectStatus"]["status"])) {
                        error  "Quality Gate failure"
                    }
                }

Please note the use of a Jenkins Credentials (authentication: 'jenkins_scanner') to retrieve the quality gate in Sonar being auhtenticated.


Using SonarQube Scanner for Jenkins 2.8.1 the solution is available out of the Box:

stage('SonarQube analysis') {
    withSonarQubeEnv('My SonarQube Server') {
        sh 'mvn clean package sonar:sonar'
    } // SonarQube taskId is automatically attached to the pipeline context
  }
}
stage("Quality Gate"){
    timeout(time: 1, unit: 'HOURS') { // Just in case something goes wrong, pipeline will be killed after a timeout
    def qg = waitForQualityGate() // Reuse taskId previously collected by withSonarQubeEnv
    if (qg.status != 'OK') {
        error "Pipeline aborted due to quality gate failure: ${qg.status}"
    }
  }
}

Scan first:

node("sonar") {
      deleteDir()
      unstash 'sources'
      def scannerHome = tool 'sonar-scanner'; 
      withSonarQubeEnv('sonarqube-rec') {
          withEnv(["JAVA_HOME=${ tool 'JDK_8.0' }", "PATH+MAVEN=${tool 'M325'}/bin:${env.JAVA_HOME}/bin"]) {        
           // requires SonarQube Scanner for Maven 3.2+
           sh '''
             mvn org.sonarsource.scanner.maven:sonar-maven-plugin:3.2:sonar
             echo "SONAR_AUTH_TOKEN=$SONAR_AUTH_TOKEN" >> target/sonar/report-task.txt
           '''
           stash includes: "target/sonar/report-task.txt", name: 'sonar-report-task'
          }
      }
    }

then check the quality gate:

    stage("Quality Gate"){
    node("sonar") {
        deleteDir()
        unstash 'sonar-report-task'
        def props = utils.getProperties("target/sonar/report-task.txt")
        echo "properties=${props}"
        def sonarServerUrl=props.getProperty('serverUrl')
        def ceTaskUrl= props.getProperty('ceTaskUrl')
        def ceTask
        def URL url = new URL(ceTaskUrl)
          timeout(time: 1, unit: 'MINUTES') {
            waitUntil {
              ceTask = utils.jsonParse(url)
              echo ceTask.toString()
              return "SUCCESS".equals(ceTask["task"]["status"])
            }
          }
          url = new URL(sonarServerUrl + "/api/qualitygates/project_status?analysisId=" + ceTask["task"]["analysisId"] )
          def qualitygate =  utils.jsonParse(url)
          echo qualitygate.toString()
          if ("ERROR".equals(qualitygate["projectStatus"]["status"])) {
            error  "Quality Gate failure"
          }
   }
}