name: Sonar on: workflow_run: workflows: ["Build/Test"] types: [completed] jobs: sonar: name: Sonar runs-on: ubuntu-latest if: github.event.workflow_run.conclusion == 'success' permissions: checks: write contents: read actions: read steps: - uses: LouisBrunner/checks-action@v2.0.0 if: always() with: token: ${{ secrets.GITHUB_TOKEN }} name: Quality Gate status: in_progress sha: ${{ github.event.workflow_run.head_sha }} - uses: actions/checkout@v4 with: repository: ${{ github.event.workflow_run.head_repository.full_name }} ref: ${{ github.event.workflow_run.head_branch }} fetch-depth: 0 - name: Download coverage artifacts uses: actions/download-artifact@v4 with: name: code-coverage run-id: ${{ github.event.workflow_run.id }} github-token: ${{ github.token }} path: pr-artifact - name: Validate Coverage Vars id: validate-vars if: github.event.workflow_run.head_branch != 'develop' shell: bash run: | # check the PR number pr_content=$(cat pr-artifact/pr_num.txt | tr -d '\n' | tr -d ' ') # Check if the content matches a single number if [[ "$pr_content" =~ ^[0-9]+$ ]]; then echo "The file 'pr_num.txt' contains a single number: $pr_content" else echo "The file 'pr_num.txt' does not contain a single number." exit 1 fi base_content=$(cat pr-artifact/base.txt | tr -d '\n' | tr -d ' ') if git check-ref-format --allow-onelevel "$base_content"; then echo "The file 'base.txt' contains a valid git ref: $base_content" else echo "The file 'base.txt' does not contain a valid git ref: $base_content" exit 1 fi head_content=$(cat pr-artifact/head.txt | tr -d '\n' | tr -d ' ') if git check-ref-format --allow-onelevel "$head_content"; then echo "The file 'head.txt' contains a valid git ref: $head_content" else echo "The file 'head.txt' does not contain a valid git ref: $head_content" exit 1 fi - name: set vars id: set-vars run: | echo "SONAR_PR_NUM=$(cat pr-artifact/pr_num.txt | tr -d '\n' | tr -d ' ')" >> $GITHUB_OUTPUT echo "SONAR_BASE=$(cat pr-artifact/base.txt | tr -d '\n' | tr -d ' ')" >> $GITHUB_OUTPUT echo "SONAR_HEAD=$(cat pr-artifact/head.txt | tr -d '\n' | tr -d ' ')" >> $GITHUB_OUTPUT # move coverage file to root where sonar properties file is expecting it cp pr-artifact/coverage.out coverage.out # on develop branch, only run a baseline scan - name: SonarCloud Scan (Baseline) uses: sonarsource/sonarcloud-github-action@master if: github.event.workflow_run.head_branch == 'develop' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} with: args: > -Dsonar.scm.revision=${{ github.event.workflow_run.head_sha }} -Dsonar.projectKey=opencost_opencost -Dsonar.organization=opencost -Dsonar.branch.name=develop - name: SonarCloud Scan (PR) uses: sonarsource/sonarcloud-github-action@master if: github.event.workflow_run.head_branch != 'develop' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} with: args: > -Dsonar.scm.revision=${{ github.event.workflow_run.head_sha }} -Dsonar.pullrequest.key=${{ steps.set-vars.outputs.SONAR_PR_NUM }} -Dsonar.pullrequest.branch="${{ steps.set-vars.outputs.SONAR_HEAD }}" -Dsonar.pullrequest.base="${{ steps.set-vars.outputs.SONAR_BASE }}" -Dsonar.projectKey=opencost_opencost -Dsonar.organization=opencost - name: SonarQube Quality Gate check id: sonarqube-quality-gate-check continue-on-error: true uses: sonarsource/sonarqube-quality-gate-action@master # fail step after specific time. timeout-minutes: 5 env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} SONAR_HOST_URL: "https://sonarcloud.io" - uses: LouisBrunner/checks-action@v2.0.0 id: fail-quality-gate if: steps.sonarqube-quality-gate-check.outputs.quality-gate-status != 'PASSED' with: token: ${{ secrets.GITHUB_TOKEN }} name: Quality Gate status: completed conclusion: failure sha: ${{ github.event.workflow_run.head_sha }} output: | {"summary":"Failed - see https://sonarcloud.io/summary/new_code?id=opencost_opencostl&pullRequest=${{ steps.set-vars.outputs.SONAR_PR_NUM }}","text_description":"Quality Gate failed. Check the [SonarCloud Dashboard](https://sonarcloud.io/dashboard?id=opencost_opencost&pullRequest=${{ steps.set-vars.outputs.SONAR_PR_NUM }}) for more details."} - uses: LouisBrunner/checks-action@v2.0.0 id: pass-quality-gate if: steps.sonarqube-quality-gate-check.outputs.quality-gate-status == 'PASSED' with: token: ${{ secrets.GITHUB_TOKEN }} name: Quality Gate status: completed conclusion: success sha: ${{ github.event.workflow_run.head_sha }} output: | {"summary":"Passed","text_description":"Quality Gate passed. Check the [SonarCloud Dashboard](https://sonarcloud.io/dashboard?id=opencost_opencost&pullRequest=${{ steps.set-vars.outputs.SONAR_PR_NUM }}) for more details."}