【问题标题】:How to integrate Sonar Quality Gates with Gitlab-CI如何将 Sonar Quality Gates 与 Gitlab-CI 集成
【发布时间】:2017-10-20 13:15:13
【问题描述】:

我有一个 gitlab-ci 集成,需要进行声纳分析,如果质量门通过,则构建 docker 映像。

这可以使用 gitlab-ci 吗?

【问题讨论】:

    标签: sonarqube gitlab gitlab-ci sonar-runner gitlab-ci-runner


    【解决方案1】:

    要中断质量门失败的 CI 构建,

    1.在 /report-task.txt 中搜索 CE 任务 URL (ceTaskUrl) 和 CE 的值 任务 ID (ceTaskId)

    2.Call /api/ce/task?id=XXX 其中 XXX 是从步骤 1 中检索到的 CE 任务 ID 例如:- https:///api/ce/task?id=Your ceTaskId

    3.等待一段时间,直到第 2 步的状态为 SUCCESS、CANCELED 或 FAILED

    4.如果失败,则中断构建(此处失败无法生成声纳报告)

    5.如果成功,则使用 /api/ce/task 返回的 JSON 中的 analysisId? id=XXX(step2)并立即调用/api/qualitygates/project_status?analysisId=YYY 检查质量门的状态。 例如:- https:///api/qualitygates/project_status?analysisId=Your 分析ID

    6.Step 5给出关键、主要和次要错误阈值限制的状态

    7.基于极限破建。

    8. 使用脚本时遵循适当的缩进

    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
    

    【讨论】:

    • 你能分享这个脚本示例吗?谢谢!
    • 添加了脚本。请检查一下。如果有效,请将其标记为答案,以便任何人都可以使用它。
    【解决方案2】:

    感谢萨希特的回答。似乎解决方案适用于 Linux。我希望它与 Windows 兼容。

    - $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
          }

    更多信息请参考链接https://www.codeproject.com/Tips/5165909/Gated-Check-in-in-Git-repository

    【讨论】:

      【解决方案3】:

      从 SonarQube 8.1 开始,这可以通过构建命令中的参数来实现。请参阅https://docs.sonarqube.org/latest/analysis/gitlab-integration/,“质量门失败时管道作业失败”:

      质量门失败时流水线作业失败 为了让质量门在 SonarQube 端失败时在 GitLab 端失败,扫描仪需要等待 SonarQube 质量门状态。要启用此功能,请在 .gitlab-ci.yml 文件中设置 sonar.qualitygate.wait=true 参数。 您可以将sonar.qualitygate.timeout 属性设置为扫描仪应等待处理报告的时间量(以秒为单位)。默认值为 300 秒。

      例子:

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

      【讨论】:

        【解决方案4】:

        您应该试试Sonar Build Breaker plugin。它可以返回非零值,这会破坏 Gitlab CI Runner 的构建,而不是执行下一步(构建 Docker 映像)。

        在项目的根目录中创建一个 .gitlab-ci.yml 文件:

        stages:
          - sonarqube
          - docker_build
        image: maven:3-jdk-8
        sonarqube:
          stage: sonarqube
          script:
            - # sonarqube running command (plugin installed), mvn blabla
        docker_build
           stage: docker_build
           script:
             - docker build .
        

        仅当 sonarqube 通过质量门时,对 Gitlab 的提交将运行 sonarqube 阶段并继续 docker_build

        【讨论】:

        • 你试过了吗?我问了 Sonarqube 的一位官员,他们没有给我任何答案。
        • 是的..使用它。 SonarQube 运行器(带有 Build Breaker 插件)只是抛出一个异常......停止进一步的构建。您的 .gitlab-ci.yml 中应该有 2 个阶段(例如:testbuild)。
        • 所以第二次构建将等待质量门,而跑步者任务将处于空闲状态?你能分享一些细节吗?
        • 它不会“等待”它会在第一步失败并且永远不会构建。一个新的提交(例如修复质量门问题)将触发一个新的构建。
        • 不幸的是,BuildBreaker 与 SonarQube 7.3+ 不兼容
        【解决方案5】:

        有一个用Go编写的simple standalone tool,可以和SQ 5.*-8.2一起使用,简单的查看具体项目的SQ QG。它需要 SQ 实例的 URL、项目密钥和令牌或登录名和密码才能运行。

        它还有一个额外的技巧,如果项目中有待处理的任务,则等待。现在还有一个轻量级的Docker imageapriorit/go-check-sonar。像这样使用:

        $ 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
        ==============================================
        

        【讨论】: