This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 7b0ae7051838 CAMEL-23274: Add SonarCloud PR analysis workflows (#22346)
7b0ae7051838 is described below
commit 7b0ae705183852d3055d896ad4b77bb4cd904da6
Author: Guillaume Nodet <[email protected]>
AuthorDate: Thu Apr 2 22:39:57 2026 +0200
CAMEL-23274: Add SonarCloud PR analysis workflows (#22346)
Add two-workflow pattern for secure SonarCloud analysis on pull requests,
including PRs from forks:
- sonar-build.yml: triggered on pull_request, builds the project and
uploads compiled classes + PR metadata as artifacts (no secrets needed)
- sonar-scan.yml: triggered on workflow_run completion, downloads artifacts
and runs sonar:sonar with access to SONAR_TOKEN secret
This follows the same pattern used by Apache Ignite (IGNITE-20466) and
Apache Kvrocks for safe SonarCloud analysis on fork PRs.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
---
.github/workflows/sonar-build.yml | 89 +++++++++++++++++++++
.github/workflows/sonar-scan.yml | 164 ++++++++++++++++++++++++++++++++++++++
2 files changed, 253 insertions(+)
diff --git a/.github/workflows/sonar-build.yml
b/.github/workflows/sonar-build.yml
new file mode 100644
index 000000000000..bbff7b1ebfae
--- /dev/null
+++ b/.github/workflows/sonar-build.yml
@@ -0,0 +1,89 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+name: SonarBuild
+
+on:
+ pull_request:
+ branches:
+ - main
+ paths-ignore:
+ - README.md
+ - SECURITY.md
+ - Jenkinsfile
+ - Jenkinsfile.*
+ - NOTICE.txt
+
+permissions:
+ contents: read
+
+concurrency:
+ group: sonar-pr-${{ github.event.pull_request.head.repo.full_name }}-${{
github.event.pull_request.head.ref }}
+ cancel-in-progress: true
+
+jobs:
+ build:
+ if: github.repository == 'apache/camel'
+ name: Build for Sonar Analysis
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #
v6.0.2
+ with:
+ persist-credentials: false
+
+ - id: install-packages
+ uses: ./.github/actions/install-packages
+
+ - name: Set up JDK 21
+ uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 #
v5.2.0
+ with:
+ distribution: 'temurin'
+ java-version: '21'
+ cache: 'maven'
+
+ - name: Build with Maven
+ run: ./mvnw install -B -Dquickly
+
+ - name: Prepare compiled classes artifact
+ shell: bash
+ run: find . -name "target" -type d | tar -czf target.tar.gz -T -
+
+ - name: Upload compiled classes artifact
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
# v7.0.0
+ id: target-upload
+ with:
+ name: sonar-target
+ path: target.tar.gz
+ if-no-files-found: error
+ retention-days: 1
+
+ - name: Prepare pull request metadata
+ shell: bash
+ run: |
+ echo "${{ github.event.pull_request.number }}" > pr-event.txt
+ echo "${{ github.event.pull_request.head.ref }}" >> pr-event.txt
+ echo "${{ github.event.pull_request.base.ref }}" >> pr-event.txt
+ echo "${{ github.event.pull_request.head.sha }}" >> pr-event.txt
+ echo "${{ steps.target-upload.outputs.artifact-id }}" >> pr-event.txt
+
+ - name: Upload pull request metadata
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
# v7.0.0
+ with:
+ name: sonar-pr-event
+ path: pr-event.txt
+ if-no-files-found: error
+ retention-days: 1
diff --git a/.github/workflows/sonar-scan.yml b/.github/workflows/sonar-scan.yml
new file mode 100644
index 000000000000..8a3d508cfb00
--- /dev/null
+++ b/.github/workflows/sonar-scan.yml
@@ -0,0 +1,164 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+name: Sonar Quality Pull Request Analysis
+
+on:
+ workflow_run:
+ workflows: [SonarBuild]
+ types: [completed]
+
+concurrency:
+ group: sonar-pr-${{ github.event.workflow_run.head_repository.full_name
}}-${{ github.event.workflow_run.head_branch }}
+ cancel-in-progress: true
+
+jobs:
+ sonar:
+ if: >
+ github.event.workflow_run.conclusion == 'success' &&
+ github.repository == 'apache/camel'
+ name: Sonar Analysis
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ actions: write
+ checks: write
+ steps:
+ - name: Download pull request metadata
+ uses:
actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
+ with:
+ name: sonar-pr-event
+ run-id: ${{ github.event.workflow_run.id }}
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Read pull request metadata
+ shell: bash
+ run: |
+ echo "pr_number=$(sed '1q;d' pr-event.txt)" >> "$GITHUB_ENV"
+ echo "pr_head_ref=$(sed '2q;d' pr-event.txt)" >> "$GITHUB_ENV"
+ echo "pr_base_ref=$(sed '3q;d' pr-event.txt)" >> "$GITHUB_ENV"
+ echo "pr_head_sha=$(sed '4q;d' pr-event.txt)" >> "$GITHUB_ENV"
+ echo "target_artifact_id=$(sed '5q;d' pr-event.txt)" >> "$GITHUB_ENV"
+
+ - name: Create PR check
+ uses: actions/github-script@v7
+ id: check
+ with:
+ script: |
+ const jobs_response = await
github.rest.actions.listJobsForWorkflowRunAttempt({
+ ...context.repo,
+ run_id: context.runId,
+ attempt_number: process.env.GITHUB_RUN_ATTEMPT,
+ });
+ const job_url = jobs_response.data.jobs[0].html_url;
+ const check_response = await github.rest.checks.create({
+ ...context.repo,
+ name: 'Sonar Quality Pull Request Analysis',
+ head_sha: process.env.pr_head_sha,
+ status: 'in_progress',
+ output: {
+ title: 'Sonar Quality Pull Request Analysis',
+ summary: '[Details](' + job_url + ')'
+ }
+ });
+ return check_response.data.id;
+ result-encoding: string
+
+ - name: Checkout PR source
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #
v6.0.2
+ with:
+ repository: ${{ github.event.workflow_run.head_repository.full_name
}}
+ ref: ${{ github.event.workflow_run.head_sha }}
+ fetch-depth: 0
+ # fetch-depth: 0 is needed for Sonar's new code detection, blame
information and issue backdating
+
+ - name: Fetch base branch
+ run: |
+ git remote add upstream https://github.com/apache/camel || true
+ git fetch upstream
+ git checkout -B ${{ env.pr_base_ref }} upstream/${{ env.pr_base_ref
}}
+ git checkout ${{ github.event.workflow_run.head_sha }}
+
+ - name: Download compiled classes artifact
+ uses:
actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
+ with:
+ name: sonar-target
+ run-id: ${{ github.event.workflow_run.id }}
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Delete compiled classes artifact
+ if: always()
+ uses: actions/github-script@v7
+ with:
+ script: |
+ await github.rest.actions.deleteArtifact({
+ ...context.repo,
+ artifact_id: process.env.target_artifact_id
+ });
+
+ - name: Extract compiled classes
+ shell: bash
+ run: tar -xzf target.tar.gz
+
+ - name: Set up JDK 21
+ uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 #
v5.2.0
+ with:
+ distribution: 'temurin'
+ java-version: '21'
+ cache: 'maven'
+
+ - name: Cache SonarCloud packages
+ uses: actions/cache@v4
+ with:
+ path: ~/.sonar/cache
+ key: ${{ runner.os }}-sonar
+
+ - id: install-packages
+ uses: ./.github/actions/install-packages
+
+ - name: Run Sonar Analysis
+ shell: bash
+ run: >
+ ./mvnw org.sonarsource.scanner.maven:sonar-maven-plugin:sonar
+ -Dsonar.scm.revision=${{ github.event.workflow_run.head_sha }}
+ -Dsonar.pullrequest.branch=${{ env.pr_head_ref }}
+ -Dsonar.pullrequest.base=${{ env.pr_base_ref }}
+ -Dsonar.pullrequest.key=${{ env.pr_number }}
+ -Dsonar.pullrequest.github.repository=apache/camel
+ -Dsonar.pullrequest.provider=GitHub
+ -Dsonar.pullrequest.github.summary_comment=true
+ -Dsonar.projectKey=apache_camel
+ -Dsonar.organization=apache
+ -Dsonar.token=${{ secrets.SONAR_TOKEN }}
+ -B -V
+ env:
+ MAVEN_OPTS: "-XX:+UseG1GC -XX:InitialHeapSize=2g -XX:MaxHeapSize=6g
-XX:+UseStringDeduplication"
+
+ - name: Update PR check status
+ uses: actions/github-script@v7
+ if: always()
+ env:
+ CHECK_ID: ${{ steps.check.outputs.result }}
+ JOB_STATUS: ${{ job.status }}
+ with:
+ script: |
+ await github.rest.checks.update({
+ ...context.repo,
+ check_run_id: process.env.CHECK_ID,
+ status: 'completed',
+ conclusion: process.env.JOB_STATUS
+ });