Skip to content

Fork SonarCloud (manual approval) #4

Fork SonarCloud (manual approval)

Fork SonarCloud (manual approval) #4

Workflow file for this run

# SonarCloud analysis for pull requests from forks (manual maintainer gate).
#
# The unprivileged Java CI workflow performs the build, generated-source check,
# and tests before this workflow can run. This workflow restores the resulting
# analysis inputs and publishes them to SonarCloud; it does not rebuild or
# retest fork code with the Sonar token.
#
# It runs on `workflow_run` in the base-repo context (with secrets), and is
# protected by the `fork-ci` GitHub Environment with Required reviewers.
# Do NOT remove that environment gate.
name: Fork SonarCloud (manual approval)
on:
workflow_run:
workflows: ["Java CI with Maven"]
types: [completed]
permissions:
contents: read
actions: read
concurrency:
group: fork-sonar-${{ github.event.workflow_run.id }}
cancel-in-progress: true
jobs:
sonar:
if: >
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.head_repository.full_name != github.event.workflow_run.repository.full_name
runs-on: ubuntu-latest
timeout-minutes: 20
environment: fork-ci
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
steps:
- name: Download successful fork PR analysis inputs
# Store outside the workspace so the later source checkout (which cleans
# the workspace) does not remove these files.
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: sonar-analysis-inputs
path: ${{ runner.temp }}/sonar-analysis-data
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
- name: Read PR metadata
id: meta
# The payload file is produced by the untrusted fork build, so extract
# only the expected keys and validate their format before exposing them
# as step outputs (prevents $GITHUB_OUTPUT injection).
run: |
env_file="$RUNNER_TEMP/sonar-analysis-data/pr-event.env"
pr_number=$(grep -m1 '^pr_number=' "$env_file" | cut -d= -f2-)
pr_head_ref=$(grep -m1 '^pr_head_ref=' "$env_file" | cut -d= -f2-)
pr_base_ref=$(grep -m1 '^pr_base_ref=' "$env_file" | cut -d= -f2-)
[[ "$pr_number" =~ ^[0-9]+$ ]] || { echo "invalid pr_number"; exit 1; }
[[ "$pr_head_ref" =~ ^[A-Za-z0-9._/-]+$ ]] || { echo "invalid pr_head_ref"; exit 1; }
[[ "$pr_base_ref" =~ ^[A-Za-z0-9._/-]+$ ]] || { echo "invalid pr_base_ref"; exit 1; }
{
echo "pr_number=$pr_number"
echo "pr_head_ref=$pr_head_ref"
echo "pr_base_ref=$pr_base_ref"
} >> "$GITHUB_OUTPUT"
- name: Check out fork PR source (from the base repo's PR ref)
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
# The fork head SHA is not present in the base repo, but the PR head
# ref is. Check that out so Sonar can read the analysed source.
ref: refs/pull/${{ steps.meta.outputs.pr_number }}/head
fetch-depth: 0
- name: Set up JDK 17
uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4.8.0
with:
java-version: '17'
distribution: 'zulu'
cache: maven
- name: Cache SonarCloud packages
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-sonar
- name: Restore compiled classes and coverage reports
run: |
src="$RUNNER_TEMP/sonar-analysis-data"
mkdir -p core/target/classes processor/target/classes
cp -a "$src/core-classes/." core/target/classes/ 2>/dev/null || true
cp -a "$src/processor-classes/." processor/target/classes/ 2>/dev/null || true
mkdir -p core/target/site/jacoco processor/target/site/jacoco
cp -a "$src/core-jacoco.xml" core/target/site/jacoco/jacoco.xml 2>/dev/null || true
cp -a "$src/processor-jacoco.xml" processor/target/site/jacoco/jacoco.xml 2>/dev/null || true
- name: Publish fork PR analysis to SonarCloud
if: env.SONAR_TOKEN != ''
env:
PR_KEY: ${{ steps.meta.outputs.pr_number }}
PR_BRANCH: ${{ steps.meta.outputs.pr_head_ref }}
PR_BASE: ${{ steps.meta.outputs.pr_base_ref }}
run: |
mvn -B org.sonarsource.scanner.maven:sonar-maven-plugin:sonar \
--file pom.xml \
-DskipTests \
-Dsonar.pullrequest.key="$PR_KEY" \
-Dsonar.pullrequest.branch="$PR_BRANCH" \
-Dsonar.pullrequest.base="$PR_BASE"