How to integrate Sonar Quality Gates with Gitlab-CI

Viewed 9568

I have a gitlab-ci integration that require a sonar analysis and if the quality gates pass, to build a docker image.

Is this possible using gitlab-ci ?

5 Answers

To break the CI build for a failed Quality Gate,

1.Search in /report-task.txt the values of the CE Task URL (ceTaskUrl) and CE Task Id (ceTaskId)

2.Call /api/ce/task?id=XXX where XXX is the CE Task Id retrieved from step 1 Ex:- https:///api/ce/task?id=Your ceTaskId

3.Wait for sometime until the status is SUCCESS, CANCELED or FAILED from Step 2

4.If it is FAILED, break the build (Here failure is unable to generate sonar report)

5.If successful,then Use the analysisId from the JSON returned by /api/ce/task? id=XXX(step2)and Immediately call /api/qualitygates/project_status?analysisId=YYY to check the status of the quality gate. Ex:- https:///api/qualitygates/project_status?analysisId=Your analysisId

6.Step 5 gives the status of the critical, major and minor error threshold limit

7.Based on the limit break the build.

8. Follow proper indentation while using the script

build:
  stage: build
  before_script:
   - yum -y install epel-release
   - yum -y install jq
   - yum install -y coreutils
  script:
    - mvn sonar:sonar -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.login=$SONAR_LOGIN_TOKEN -Dsonar.working.directory=../target/.sonar
    - export url=$(cat ../target/.sonar/report-task.txt | grep ceTaskUrl | cut -c11- ) #URL where report gets stored
    - sleep 15s #Wait time for the report
    - curl -k -u "$SONAR_LOGIN_TOKEN":"" $url -o analysis.txt
    - export status=$(cat analysis.txt | jq -r '.task.status') #Status as SUCCESS, CANCELED or FAILED
    - export analysisId=$(cat analysis.txt | jq -r '.task.analysisId') #Get the analysis Id
    - |
      if [ "$status" == "SUCCESS" ];then 
        echo -e "SONAR ANALYSIS SUCCESSFUL...ANALYSING RESULTS";
        curl -k -u "$SONAR_LOGIN_TOKEN":"" https://yourSonarURI/api/qualitygates/project_status?analysisId=$analysisId -o result.txt; #Analysis result like critical, major and minor issues
        export result=$(cat result.txt | jq -r '.projectStatus.status');

        if [ "$result" == "ERROR" ];then
          echo -e "91mSONAR RESULTS FAILED";
          echo "$(cat result.txt | jq -r '.projectStatus.conditions')"; #prints the critical, major and minor violations
          exit 1 #breaks the build for violations
        else
          echo -e "SONAR RESULTS SUCCESSFUL";
          echo "$(cat result.txt | jq -r '.projectStatus.conditions')";
          exit 0 
        fi
    else 
        echo -e "\e[91mSONAR ANALYSIS FAILED\e[0m";
        exit 1 #breaks the build for failure in Step2
     fi

Starting from SonarQube 8.1 this is possible with a parameter in the build command. See https://docs.sonarqube.org/latest/analysis/gitlab-integration/, "Failing the pipeline job when the Quality Gate fails":

Failing the pipeline job when the Quality Gate fails In order for the Quality Gate to fail on the GitLab side when it fails on the SonarQube side, the scanner needs to wait for the SonarQube Quality Gate status. To enable this, set the sonar.qualitygate.wait=true parameter in the .gitlab-ci.yml file. You can set the sonar.qualitygate.timeout property to an amount of time (in seconds) that the scanner should wait for a report to be processed. The default is 300 seconds.

Example:

mvn verify sonar:sonar -Dsonar.qualitygate.wait=true

Thanks Sahit for the answer. It seems the solution is for Linux. I wanted it to be Windows compatible.

- $url = (findstr "ceTaskUrl" "<report-task.txt location>").Substring(10) 
- sleep 10 #Need some buffer time to get the report updated from sonarqube analyzer
- $response = &"<Curl exe location>" -u <SonarAdminUserName>:<Password> $url #using curl to login to sonarqube to check analysis ran properly or not. Using sonar admin credentials/token
- $sonardata = $response | ConvertFrom-Json #converting returned data to json 
- $sonarBuildStatus=$sonardata.task.status
- |
      if ("$sonarBuildStatus" -eq "SUCCESS"){ 
          echo "SONARQUBE ANALYSIS IS SUCCESSFUL"
          $sonarAnalysisId= $sonardata.task.analysisId
          $projurl = (findstr "serverUrl" "<report-task.txt location>").Substring(10)
          $projNewUrl = $projurl+"/api/qualitygates/project_status?analysisId="+$sonarAnalysisId
          $projresponse = &"<Curl exe location>" -u <SonarAdminUserName>:<Password> $projNewUrl
          $sonarprojdata = $projresponse | ConvertFrom-Json
          $sonarProjStatus=$sonarprojdata.projectStatus.status
          if ("$sonarProjStatus" -eq "ERROR"){ #Checks if the project has meet all the quality gates specified
              echo  "SONARQUBE QUALITY GATES FAILED FOR $CI_PROJECT_NAME"
              echo $sonarprojdata.projectStatus.conditions
              exit 1 #breaks the build for violations
          }
          else{
              echo "SONARQUBE QUALITY GATES SUCCESSFUL FOR $CI_PROJECT_NAME"
              echo $sonarprojdata.projectStatus.conditions
              exit 0
          }
          
      }
      else{
          echo "SONARQUBE ANALYSIS FAILED"
          exit 1 #breaks the build for violations
      }

Refer the link for more information https://www.codeproject.com/Tips/5165909/Gated-Check-in-in-Git-repository

There is a simple standalone tool written in Go, that can be used with SQ 5.*-8.2 to simply check SQ QG of the specific project. It needs an URL to SQ instance, project key, and token or login & password to run.

It does one additional trick, to wait if there are pending tasks on the project. And now there also is a lightweight Docker image for it apriorit/go-check-sonar. Used like that:

$ docker run --rm -it apriorit/go-check-sonar -project=PROJ -server=http://sonar.dev.local -token=dead**beef
Running SonarQube Quality Gate checker!
Checking if any tasks are running for the provided project...

Waiting for pending tasks to finish...

1 pending tasks remaining for PROJ component...
1 pending tasks remaining for PROJ component...
1 pending tasks remaining for PROJ component...
0 pending tasks remaining for PROJ component...
All tasks on project PROJ are finished!

Checking Quality Gate status of the project...

==============================================
Project Status: OK
==============================================
Related