build: enable JaCoCo coverage report generation across all modules #1
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: SonarQube Cloud scan | |
| # Least-privilege per CodeQL's "Workflow does not contain permissions" rule. | |
| # - contents: read — checkout the branch | |
| # - pull-requests: read — let SonarQube Cloud decorate the PR via its own token | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| # Runs the official SonarQube Cloud scan against the branch on every PR and on | |
| # pushes to main. This complements .github/workflows/sonar.yml (our own self- | |
| # scan): SonarQube Cloud is the canonical reference, so a delta between the | |
| # two surfaces drift in our daemon's behaviour vs. SonarSource's own pipeline. | |
| # | |
| # Setup required (one-time, by the repo admin): | |
| # 1. Sign in to https://sonarcloud.io with the repo's GitHub org/account. | |
| # 2. Import this repo as a SonarQube Cloud project. | |
| # (Project key is conventionally `<github-org>_<repo>`; organisation slug | |
| # is `<github-org>` in lowercase.) | |
| # 3. Configure "Analysis Method" → "With GitHub Actions"; copy the generated | |
| # `SONAR_TOKEN`. | |
| # 4. In this repo: Settings → Secrets and variables → Actions → New | |
| # repository secret named SONAR_TOKEN, paste the token. | |
| # | |
| # Without SONAR_TOKEN the workflow fails fast in the "Verify secrets" step — | |
| # the rest of the pipeline never runs, so a missing token is obvious from the | |
| # job summary. | |
| # | |
| # Why a Maven-driven scan (sonar:sonar) rather than the generic scan-action? | |
| # This is a Maven multi-module project; the Maven plugin auto-discovers | |
| # `src/main/java`, `src/test/java`, JaCoCo XMLs, and the compiled-classes path | |
| # per module. Less configuration to drift out of sync. | |
| on: | |
| pull_request: | |
| branches: [main] | |
| push: | |
| branches: [main] | |
| workflow_dispatch: | |
| jobs: | |
| sonarqube-cloud: | |
| name: SonarQube Cloud | |
| runs-on: ubuntu-latest | |
| # Skip when the token isn't configured (fork PRs, first-run before setup) | |
| # — emits a soft-fail rather than every PR carrying a hard ❌. | |
| if: ${{ github.event_name == 'workflow_dispatch' || github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository }} | |
| steps: | |
| # Full history lets SonarQube Cloud compute new-code coverage and | |
| # author-blame correctly. Without fetch-depth: 0 the scan sees a | |
| # shallow clone and falls back to "all code is new code" per PR. | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| # JDK 17 matches maven.compiler.release in the parent pom. | |
| - name: Set up JDK 17 | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: temurin | |
| java-version: '17' | |
| # The JS/TS analyzer plugin spawns Node at scan time. Without this the | |
| # JS/TS sensors silently skip — and our counts then diverge from the | |
| # self-scan, which has the same prerequisite. | |
| - name: Set up Node.js 20 | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| # Two caches: Maven repo + SonarQube Cloud analysis cache. The Sonar | |
| # cache stores per-language scan state (e.g. JS/TS server-side | |
| # analysis blobs) so reruns of unchanged files are much faster. | |
| - name: Cache Maven repository | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.m2/repository | |
| key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-maven- | |
| - name: Cache SonarQube Cloud packages | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.sonar/cache | |
| key: ${{ runner.os }}-sonar | |
| restore-keys: | | |
| ${{ runner.os }}-sonar | |
| # Verify SONAR_TOKEN exists before we waste minutes on a full build that | |
| # the scan step would then fail to authenticate. Clear setup hint in | |
| # the failure message — no need to read the workflow header. | |
| - name: Verify secrets | |
| env: | |
| SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | |
| run: | | |
| if [ -z "${SONAR_TOKEN:-}" ]; then | |
| echo "::error::SONAR_TOKEN secret is not set. See the header of this workflow for one-time SonarQube Cloud setup." | |
| exit 1 | |
| fi | |
| echo "SONAR_TOKEN configured — proceeding with scan." | |
| # `mvn verify` runs tests AND generates the per-module JaCoCo XMLs that | |
| # the Sonar Maven plugin picks up automatically from | |
| # <module>/target/site/jacoco/jacoco.xml. failIfNoSpecifiedTests=false | |
| # keeps the dist module (no tests) from breaking the reactor. | |
| # We skip the dist module's assembly here — sonar:sonar doesn't need | |
| # the skill bundle, and skipping shaves ~30s. | |
| - name: Build, test, generate JaCoCo XML | |
| run: mvn -B -ntp -pl '!dist' verify -Dsurefire.failIfNoSpecifiedTests=false | |
| # The actual SonarQube Cloud scan via the Maven plugin. Reads | |
| # SONAR_TOKEN from env. Project key + organisation conventions: | |
| # `<github-org>_<repo>` and `<github-org>` lowercased — adjust if | |
| # the SonarCloud project is set up under different identifiers. | |
| - name: SonarQube Cloud scan | |
| env: | |
| SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| mvn -B -ntp -pl '!dist' \ | |
| org.sonarsource.scanner.maven:sonar-maven-plugin:sonar \ | |
| -Dsonar.projectKey=RandomCodeSpace_sonar-predict \ | |
| -Dsonar.organization=randomcodespace \ | |
| -Dsonar.host.url=https://sonarcloud.io \ | |
| -Dsonar.qualitygate.wait=false \ | |
| -Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml,../protocol/target/site/jacoco/jacoco.xml,../daemon/target/site/jacoco/jacoco.xml,../cli/target/site/jacoco/jacoco.xml | |
| # Project link printed into the job summary so a reviewer can jump | |
| # straight to the SonarCloud dashboard from the PR Checks tab. | |
| - name: Link to SonarQube Cloud dashboard | |
| if: always() | |
| run: | | |
| { | |
| echo "## SonarQube Cloud" | |
| echo | |
| echo "Reference scan — compare against the in-repo self-scan to confirm parity." | |
| echo | |
| echo "Dashboard: https://sonarcloud.io/project/overview?id=RandomCodeSpace_sonar-predict" | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| echo "PR view: https://sonarcloud.io/project/issues?id=RandomCodeSpace_sonar-predict&pullRequest=${{ github.event.pull_request.number }}" | |
| fi | |
| } >> "$GITHUB_STEP_SUMMARY" |