diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c3fbac1dd..44596b4a8 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 - prepare-sonar-coverage: - name: "Prepare Sonar Coverage Artifacts" + sonarqube-analysis: + name: "SonarQube Analysis" runs-on: ubuntu-24.04 needs: - tests-backend @@ -441,6 +441,10 @@ 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 deleted file mode 100644 index 0b5ca2469..000000000 --- a/.github/workflows/sonar.yml +++ /dev/null @@ -1,128 +0,0 @@ -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 }}