From 68e055905365c77e423d2a0fb33b1fbbf500d6b1 Mon Sep 17 00:00:00 2001 From: shamoon <4887959+shamoon@users.noreply.github.com> Date: Wed, 24 Sep 2025 14:26:05 -0700 Subject: [PATCH] Development: try separating sonar scan --- .github/workflows/ci.yml | 8 +-- .github/workflows/sonar.yml | 128 ++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/sonar.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 44596b4a8..c3fbac1dd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -377,8 +377,8 @@ jobs: env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} run: cd src-ui && pnpm run build --configuration=production - sonarqube-analysis: - name: "SonarQube Analysis" + prepare-sonar-coverage: + name: "Prepare Sonar Coverage Artifacts" runs-on: ubuntu-24.04 needs: - tests-backend @@ -441,10 +441,6 @@ jobs: retention-days: 7 if-no-files-found: error include-hidden-files: true - - name: SonarQube Analysis - uses: SonarSource/sonarqube-scan-action@v5 - env: - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} build-docker-image: name: Build Docker image for ${{ github.ref_name }} runs-on: ubuntu-24.04 diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml new file mode 100644 index 000000000..0b5ca2469 --- /dev/null +++ b/.github/workflows/sonar.yml @@ -0,0 +1,128 @@ +name: sonar +on: + workflow_run: + workflows: + - ci + types: + - completed +permissions: + contents: read + actions: read + pull-requests: read + checks: write + statuses: write +jobs: + sonar: + if: | + github.event.workflow_run.conclusion == 'success' && + (github.event.workflow_run.event == 'pull_request' || github.event.workflow_run.event == 'push') + runs-on: ubuntu-24.04 + steps: + - name: Collect workflow context + id: metadata + uses: actions/github-script@v7 + with: + script: | + const run = context.payload.workflow_run; + const result = { + event: run.event, + should_run: 'false', + is_pr: 'false', + pr_number: '', + head_branch: run.head_branch || '', + base_branch: '', + head_sha: run.head_sha, + checkout_repo: (run.head_repository && run.head_repository.full_name) || `${context.repo.owner}/${context.repo.repo}`, + }; + + if (run.event === 'pull_request' && run.pull_requests && run.pull_requests.length > 0) { + const pr = run.pull_requests[0]; + result.should_run = 'true'; + result.is_pr = 'true'; + result.pr_number = pr.number.toString(); + result.head_branch = pr.head.ref; + result.base_branch = pr.base.ref; + } else if (run.event === 'push' && result.head_branch) { + result.should_run = 'true'; + } + + Object.entries(result).forEach(([key, value]) => core.setOutput(key, value)); + - name: Checkout repository + if: steps.metadata.outputs.should_run == 'true' + uses: actions/checkout@v5 + with: + repository: ${{ steps.metadata.outputs.checkout_repo }} + ref: ${{ steps.metadata.outputs.head_sha }} + fetch-depth: 0 + - name: Align GitHub context with upstream run + if: steps.metadata.outputs.should_run == 'true' + run: | + echo "GITHUB_SHA=${{ steps.metadata.outputs.head_sha }}" >> $GITHUB_ENV + if [ -n "${{ steps.metadata.outputs.head_branch }}" ]; then + echo "GITHUB_REF_NAME=${{ steps.metadata.outputs.head_branch }}" >> $GITHUB_ENV + fi + if [ "${{ steps.metadata.outputs.is_pr }}" = "true" ]; then + echo "GITHUB_HEAD_REF=${{ steps.metadata.outputs.head_branch }}" >> $GITHUB_ENV + echo "GITHUB_BASE_REF=${{ steps.metadata.outputs.base_branch }}" >> $GITHUB_ENV + fi + - name: Download merged coverage artifact + if: steps.metadata.outputs.should_run == 'true' + id: download-coverage + uses: actions/github-script@v7 + with: + result-encoding: string + script: | + const { owner, repo } = context.repo; + const runId = context.payload.workflow_run.id; + const artifactName = 'merged-coverage'; + + const artifacts = await github.paginate(github.rest.actions.listWorkflowRunArtifacts, { + owner, + repo, + run_id: runId, + per_page: 100, + }); + + const artifact = artifacts.find((entry) => entry.name === artifactName); + if (!artifact) { + core.setFailed(`Unable to locate artifact '${artifactName}' for workflow run ${runId}.`); + return; + } + + const download = await github.rest.actions.downloadArtifact({ + owner, + repo, + artifact_id: artifact.id, + archive_format: 'zip', + }); + + const fs = require('fs'); + const path = require('path'); + + const artifactDir = path.join(process.cwd(), 'coverage-artifacts'); + fs.mkdirSync(artifactDir, { recursive: true }); + + const filePath = path.join(artifactDir, `${artifactName}.zip`); + fs.writeFileSync(filePath, Buffer.from(download.data)); + core.setOutput('zip-path', filePath); + - name: Extract coverage files + if: steps.metadata.outputs.should_run == 'true' + run: | + unzip -o "${{ steps.download-coverage.outputs.zip-path }}" -d coverage-artifacts/unpacked + shopt -s dotglob + cp -r coverage-artifacts/unpacked/* ./ + - name: Configure Sonar scanner parameters + if: steps.metadata.outputs.should_run == 'true' + run: | + if [ "${{ steps.metadata.outputs.is_pr }}" = "true" ]; then + echo "SONAR_SCANNER_ARGS=-Dsonar.pullrequest.key=${{ steps.metadata.outputs.pr_number }} -Dsonar.pullrequest.branch=${{ steps.metadata.outputs.head_branch }} -Dsonar.pullrequest.base=${{ steps.metadata.outputs.base_branch }}" >> $GITHUB_ENV + else + echo "SONAR_SCANNER_ARGS=-Dsonar.branch.name=${{ steps.metadata.outputs.head_branch }}" >> $GITHUB_ENV + fi + - name: SonarQube Analysis + if: steps.metadata.outputs.should_run == 'true' + uses: SonarSource/sonarqube-scan-action@v5 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + with: + args: ${{ env.SONAR_SCANNER_ARGS }}