How to handle inprogress status for SonarQube Quality gate

Overview

Let us start with the scenario. You might have setup CI CD pipeline with Jenkins and SonarQube for code analysis and quality gate. Then noticed that it works well for sometime, then suddenly in one of the successive builds, the pipeline starts getting stuck in the quality gate process with in-progress status.

It gets stuck in IN-PROGRESS status as no status is being returned from SonarQube to Jenkins. The status that should be returned is either PASS or FAIL.

What we typically do to come out of this in-progress state is either wait for the timeout to occur or abort the stage manually, which is not the resolution. In this post, we will discuss why this problem occurs and how to resolve it.

Related post:

Guide to configure a webhook in SonarQube

Click here to view other posts on SonarQube

Problem Description

Let us go through the code first.

Following is the basic code for quality gate configuration which was used in Jenkins when the in-progress issue had occurred : 

stage(“Quality Gate”){

        timeout(time: 10, unit: ‘MINUTES’) {
              def qg= waitForQualityGate()
            if (qg.status!= ‘OK’){
                error “Pipeline aborted due to quality gate failure: ${qg.status}”
            }
        }         
              echo ‘Quality Gate Passed’

    }

Below are the logs that were generated for the quality gate stage on running the job.

”  
[Pipeline] stage[Pipeline] { (Quality Gate) [Pipeline] timeout Timeout set to expire in 10 min [Pipeline] { [Pipeline] waitForQualityGate Checking status of SonarQube task ‘AW0-VlEAbdFtWVenh2fm’ on server ‘SonarQube_Home’ SonarQube task ‘AW0-VlEAbdFtWVenh2fm’ status is ‘IN_PROGRESS’ Aborted by unknown [Pipeline] } [Pipeline] // timeout [Pipeline] } [Pipeline] // stage [Pipeline] step  

Analysis

What is happening here is that the quality gate is unable to read the result of SonarQube analysis. The following step in the code:

    def qg= waitForQualityGate()

will print “IN PROGRESS” unless the waiting time expires or the operation is aborted manually.  

The waitForQualityGate step polls only once (for various reasons) and then pause the pipeline in the infamous in-progess status, waiting for a webhook to be received.  If the webhook never fires (isn’t configured correctly/ or cannot communicate/plugin bug) from sonar to Jenkins, the call stays stuck and hung until the timeout is hit or is aborted manually

Jenkins checks the result from SonarQube while SonarQube is still processing the result. This usually happens just few seconds (at times minutes) before the result of SonarQube analysis is available to quality gate. If the thread is set to sleep [sleep(<time in seconds>)]  for 1-3 minutes or more as per code complexity and system performance, Jenkins will check the result from SonarQube after this delay. Ot means that in the meantime, Jenkins will be able to receive the analysis result from SonarQube.

e.g. Adding below as the last step in the “Quality gate” stage will seem to temporarily resolve the problem:
sleep(n), where n is the duration in seconds.

However, setting sleep time is not a permanent solution to the problem.

Resolution

 The solution that worked for me was quite straight forward. It was more like a step that was missed while designing the pipeline.

As we’ve seen above, the waitForQualityGate step polls only once (for various reasons) and then pause the pipeline in the infamous in-progess status. In this state, it is actually waiting for a webhook to be received.  If the webhook never fires (isn’t configured) from SonarQube to Jenkins, the call stays stuck and hung until the timeout is hit or is aborted manually

Hence, the solution is to create a webhook from SonarQube server and point it to the Jenkins server.

This can be found under  Menu Administration->Configurations->Webhooks as shown in below screenshot.

Global level Webhooks in Sonarqube

This will open the page with a list of configured webhooks. Click on Create button on top right side of this page.

Configured Webhooks

Then provide a name and the url for the webhook and save. The URL should be your Jenkins server address followed by /sonarqube-webhook.

To further understand webhook configuration in detail, you can go through this post Guide to configure a webhook in SonarQube


How it works

This is how the Jenkins will process the stage post webhook implementation:

  • First it will check whether the quality check is already complete. It will immediately return if it is.(This is also why setting the thread to sleep seems to work because SonarQube completes its analysis within that interval.)
  • If not it then it will wait until SonarQube completes the processing and sends the webhook call to Jenkins server.

Let us know if you found this post useful.   

You may also like...

2 Responses

  1. Thanks for sharing: the explanation on the webhook internal functioning was a great helper in narrowing down my particular problem, actually caused by the webhook’s security settings:
    – Go to _Manage Jenkins_ -> _Configure System_ -> _SonarQube servers_ -> _Advanced…_
    – Set _Webhoot Secret_ to _SonarQube webhook secret_

    Hope this may help someone with a similar problem! 😊

Leave a Reply

Your email address will not be published. Required fields are marked *