Skip to content

chore: sonarcube for CI#2251

Merged
yingbull merged 8 commits into
developfrom
chore/sonarcube
Jan 30, 2026
Merged

chore: sonarcube for CI#2251
yingbull merged 8 commits into
developfrom
chore/sonarcube

Conversation

@yingbull

@yingbull yingbull commented Jan 30, 2026

Copy link
Copy Markdown

User description

Summary by Sourcery

Integrate SonarCloud static analysis into the project and CI pipeline

Build:

  • Configure SonarCloud organization in Maven project properties

CI:

  • Add GitHub Actions workflow to run SonarCloud analysis on develop pushes and pull requests with Maven build and caching

Summary by cubic

Adds SonarCloud analysis to CI for pushes and PRs to develop using the existing dev container. Enables PR decorations (inline comments and quality gate), sets sonar.organization in pom.xml, and restores the ca.uhn.hapi:hapi:1.0.1 parent POM so builds pass.

  • Migration
    • Add a SONAR_TOKEN repository secret.
    • No code changes; analysis runs on develop pushes and PRs.

Written for commit 5937fff. Summary will update on new commits.

Summary by CodeRabbit

  • Chores
    • Added an automated SonarCloud code-quality analysis workflow that runs on pushes to develop and on pull requests.
    • Declared the SonarCloud organization property in project configuration for proper project attribution.
    • Added local Maven repository metadata and release POM artifacts to support reproducible builds and offline resolution.

✏️ Tip: You can customize this high-level summary in your review settings.


PR Type

Enhancement, Other


Description

  • Add SonarCloud static code analysis workflow for CI/CD pipeline

    • Triggered on develop branch pushes and pull requests
    • Uses existing dev container with Docker layer caching
    • Configures Maven build with SonarCloud integration
  • Restore missing HAPI parent POM required by hapi-base dependency

    • Adds ca.uhn.hapi:hapi:1.0.1 parent POM files to local_repo
    • Fixes build failures caused by previous cleanup
  • Configure SonarCloud organization property in pom.xml


Diagram Walkthrough

flowchart LR
  A["GitHub Push/PR<br/>to develop"] -->|"Trigger"| B["SonarCloud<br/>Workflow"]
  B -->|"Pull/Build"| C["Dev Container<br/>openo-tomcat-dev"]
  C -->|"Cache Layers"| D["Docker & Maven<br/>Cache"]
  C -->|"Run Analysis"| E["Maven Build<br/>+ SonarCloud"]
  E -->|"Report"| F["SonarCloud<br/>Dashboard"]
  G["pom.xml"] -->|"Config"| E
  H["HAPI POM<br/>1.0.1"] -->|"Dependency"| E
Loading

File Walkthrough

Relevant files
Configuration changes
sonarcloud.yml
SonarCloud CI workflow with Docker caching                             

.github/workflows/sonarcloud.yml

  • New GitHub Actions workflow for SonarCloud analysis on develop branch
  • Implements Docker container-based build with layer caching strategy
  • Attempts to pull pre-built dev image from ghcr.io, falls back to local
    build
  • Configures Maven caches for packages and SonarCloud, runs analysis
    with sonar:sonar goal
  • Passes GITHUB_TOKEN and SONAR_TOKEN secrets to Maven execution
+172/-0 
pom.xml
Add SonarCloud organization configuration                               

pom.xml

  • Adds sonar.organization property set to openo-beta1
  • Property enables SonarCloud to correctly attribute analysis results
+2/-0     
Dependencies
hapi-1.0.1.pom
Restore HAPI parent POM artifact                                                 

local_repo/ca/uhn/hapi/hapi/1.0.1/hapi-1.0.1.pom

  • Restores complete HAPI parent POM version 1.0.1 (400 lines)
  • Defines Maven project structure, plugins, profiles, and repositories
  • Required by hapi-base:1.0.1 dependency used in the project
+400/-0 
_remote.repositories
Add HAPI POM repository metadata                                                 

local_repo/ca/uhn/hapi/hapi/1.0.1/_remote.repositories

  • Aether metadata file tracking repository source for HAPI POM
  • Indicates artifact was retrieved from hapi-sf repository
+3/-0     
hapi-1.0.1.pom.sha1
Add HAPI POM checksum file                                                             

local_repo/ca/uhn/hapi/hapi/1.0.1/hapi-1.0.1.pom.sha1

  • SHA1 checksum for HAPI POM artifact integrity verification
+1/-0     
hapi-1.0.1.pom.lastUpdated
Add HAPI POM update metadata                                                         

local_repo/ca/uhn/hapi/hapi/1.0.1/hapi-1.0.1.pom.lastUpdated

  • Aether metadata tracking last update timestamps from multiple
    repositories
  • Records download history and error states for artifact resolution
+7/-0     

Copilot AI review requested due to automatic review settings January 30, 2026 04:36
@sourcery-ai

sourcery-ai Bot commented Jan 30, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds SonarCloud static analysis to the CI pipeline via a new GitHub Actions workflow and configures the Sonar organization in the Maven project.

Flow diagram for SonarCloud GitHub Actions workflow

flowchart TD
  A["Push_or_PR_to_develop_branch"] --> B["Trigger_SonarCloud_Analysis_workflow"]
  B --> C["Start_job_build_and_analyze_on_ubuntu_latest_runner"]

  C --> D["Checkout_code_actions_checkout_v4_with_fetch_depth_0"]
  D --> E["Set_up_JDK_21_with_distribution_zulu"]
  E --> F["Restore_or_save_SonarCloud_cache_at_~/.sonar/cache"]
  F --> G["Restore_or_save_Maven_cache_at_~/.m2"]

  G --> H["Run_mvn_B_verify_with_sonar_maven_plugin"]
  H --> I["Read_pom_xml_properties_including_sonar_organization_openo_beta"]
  I --> J["Send_analysis_to_SonarCloud_using_sonar_projectKey_openo_beta_Open_O"]
  J --> K["Update_code_quality_and_PR_status_in_GitHub"]
Loading

File-Level Changes

Change Details Files
Configure SonarCloud organization in Maven project configuration.
  • Add sonar.organization property to Maven pom.xml to align with SonarCloud organization settings
pom.xml
Introduce GitHub Actions workflow to run SonarCloud analysis on pushes and pull requests to develop.
  • Create sonarcloud.yml workflow that triggers on push and PR events targeting the develop branch
  • Set up JDK 21 and caching for Sonar and Maven dependencies in the workflow
  • Run Maven verify with Sonar Maven plugin, providing sonar.projectKey and skipping test execution, using SONAR_TOKEN and GITHUB_TOKEN from repository secrets
.github/workflows/sonarcloud.yml

Possibly linked issues

  • #[Feature]: review sonarcube integration for CI: The PR implements SonarCloud CI integration exactly as requested by the issue’s SonarQube CI feature.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@github-actions

github-actions Bot commented Jan 30, 2026

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Snapshot Warnings

⚠️: No snapshots were found for the head SHA 5937fff.
Ensure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice.

OpenSSF Scorecard

PackageVersionScoreDetails
actions/actions/cache 4.*.* 🟢 6.6
Details
CheckScoreReason
Code-Review🟢 10all changesets reviewed
Maintained🟢 1030 commit(s) and 2 issue activity found in the last 90 days -- score normalized to 10
Packaging⚠️ -1packaging workflow not detected
Binary-Artifacts🟢 10no binaries found in the repo
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Pinned-Dependencies🟢 3dependency not pinned by hash detected -- score normalized to 3
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Security-Policy🟢 9security policy file detected
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Vulnerabilities🟢 91 existing vulnerabilities detected
SAST🟢 10SAST tool is run on all commits
actions/actions/checkout 4.*.* 🟢 6.6
Details
CheckScoreReason
Maintained🟢 79 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 7
Binary-Artifacts🟢 10no binaries found in the repo
Code-Review🟢 10all changesets reviewed
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
Packaging⚠️ -1packaging workflow not detected
Pinned-Dependencies🟢 3dependency not pinned by hash detected -- score normalized to 3
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Security-Policy🟢 9security policy file detected
Branch-Protection🟢 5branch protection is not maximal on development and all release branches
Vulnerabilities🟢 82 existing vulnerabilities detected
SAST🟢 8SAST tool detected but not run on all commits
actions/docker/login-action 3.*.* 🟢 5
Details
CheckScoreReason
Binary-Artifacts🟢 10no binaries found in the repo
Maintained🟢 57 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 5
Code-Review🟢 5Found 2/4 approved changesets -- score normalized to 5
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Security-Policy🟢 9security policy file detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Packaging⚠️ -1packaging workflow not detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration
Vulnerabilities⚠️ 015 existing vulnerabilities detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
SAST🟢 9SAST tool detected but not run on all commits
actions/docker/setup-buildx-action 3.*.* 🟢 5.1
Details
CheckScoreReason
Maintained🟢 99 commit(s) and 2 issue activity found in the last 90 days -- score normalized to 9
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Code-Review🟢 4Found 3/7 approved changesets -- score normalized to 4
Security-Policy🟢 9security policy file detected
Binary-Artifacts🟢 10no binaries found in the repo
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration
Fuzzing⚠️ 0project is not fuzzed
Packaging🟢 10packaging workflow detected
Vulnerabilities⚠️ 014 existing vulnerabilities detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0

Scanned Files

  • .github/workflows/sonarcloud.yml

@coderabbitai

coderabbitai Bot commented Jan 30, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Adds a SonarCloud GitHub Actions workflow, a Maven sonar.organization property, and new local Maven repository files for ca.uhn.hapi:hapi:1.0.1 (POM, checksum, and repository metadata).

Changes

Cohort / File(s) Summary
CI: SonarCloud workflow
\.github/workflows/sonarcloud.yml
New "SonarCloud Analysis" workflow: sets up Docker Buildx, authenticates to ghcr.io, attempts to pull openo-tomcat-dev with fallback to local build, caches Docker/Maven/Sonar artifacts, runs a dev container, configures git safe.directory, and executes Maven SonarCloud analysis with GITHUB_TOKEN and SONAR_TOKEN.
Maven root pom
pom.xml
Adds <sonar.organization>openo-beta1</sonar.organization> property under <properties> for SonarCloud configuration.
Local Maven repository: HAPI 1.0.1
local_repo/ca/uhn/hapi/hapi/1.0.1/...
local_repo/ca/uhn/hapi/hapi/1.0.1/hapi-1.0.1.pom, .../hapi-1.0.1.pom.sha1, .../_remote.repositories, .../hapi-1.0.1.pom.lastUpdated
Adds complete POM for ca.uhn.hapi:hapi:1.0.1 (metadata, modules, licenses, pluginManagement, profiles) plus checksum and repository metadata files. No public API signatures changed.

Sequence Diagram(s)

sequenceDiagram
  participant GH as GH Actions
  participant GHCR as GHCR (ghcr.io)
  participant Runner as CI Runner
  participant Container as Dev Container
  participant Maven as Maven (in Container)
  participant Sonar as SonarCloud

  GH->>GHCR: pull `openo-tomcat-dev`
  alt image found
    GHCR-->>GH: image pulled
    GH->>Runner: start Container from image
  else not found
    GHCR-->>GH: not-found
    GH->>Runner: build Container locally (use Docker layer cache)
  end
  GH->>Runner: restore caches (Maven, Sonar, Docker)
  Runner->>Container: mount workspace & caches, set git safe.directory
  Container->>Maven: run Maven goals including `sonar:sonar` (env: GITHUB_TOKEN, SONAR_TOKEN)
  Maven->>Sonar: upload analysis (projectKey, organization)
  Sonar-->>GH: report/status
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

🐰
I nibbled at the CI vine,
Pulled images, cached a line,
Sonar hummed and read each pom,
POMs and checks in tidy form,
Hops and builds — the repo's warm! 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'chore: sonarcube for CI' is partially related to the changeset. It mentions SonarCloud (spelled as 'sonarcube') and CI integration, which is the primary change, but uses a misspelling and is somewhat vague about the specific implementation (GitHub Actions workflow, pom.xml configuration, and local repository artifacts).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/sonarcube

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • The workflow description mentions running on pull requests to protected branches, but the trigger is limited to PRs targeting develop; if you want SonarCloud analysis on all protected branches you may want to adjust the pull_request branches filter or update the comment to match the actual behavior.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The workflow description mentions running on pull requests to protected branches, but the trigger is limited to PRs targeting `develop`; if you want SonarCloud analysis on all protected branches you may want to adjust the `pull_request` branches filter or update the comment to match the actual behavior.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds SonarCloud configuration for CI so the repository can run static analysis on pushes/PRs.

Changes:

  • Added sonar.organization property to Maven pom.xml.
  • Added a new GitHub Actions workflow to run SonarCloud analysis on develop pushes and PRs targeting develop.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
pom.xml Adds SonarCloud organization property used by the scanner.
.github/workflows/sonarcloud.yml Introduces CI workflow to run Maven build + SonarCloud analysis.

Comment thread .github/workflows/sonarcloud.yml Outdated
Comment thread .github/workflows/sonarcloud.yml
Comment thread .github/workflows/sonarcloud.yml Outdated
yingbull and others added 4 commits January 29, 2026 23:50
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
The ca.uhn.hapi:hapi:pom:1.0.1 parent POM was accidentally removed
in a previous cleanup commit. This POM is required by hapi-base:1.0.1
which is still used in the project.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 2 files (changes from recent commits).

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name=".github/workflows/sonarcloud.yml">

<violation number="1" location=".github/workflows/sonarcloud.yml:102">
P2: The Docker build cache key is now constant, so the cache will never refresh after the first run. This makes layer caching stale and wastes build time when the devcontainer changes.</violation>

<violation number="2" location=".github/workflows/sonarcloud.yml:110">
P2: The Maven cache key is constant, so the cache won’t update when dependencies change. This causes repeated downloads and stale cache contents.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread .github/workflows/sonarcloud.yml Outdated
Comment thread .github/workflows/sonarcloud.yml Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In @.github/workflows/sonarcloud.yml:
- Around line 154-172: The workflow currently runs the "Build and analyze" step
using the SONAR_TOKEN env but does not validate it; add a pre-check that ensures
the SONAR_TOKEN (env/secret referenced as SONAR_TOKEN) is set and fails fast
with a clear message before executing docker/mvn; implement this by inserting a
validation job/step (e.g., "Validate SONAR_TOKEN" prior to the Build and analyze
step or an inline check at the top of that step) that checks if SONAR_TOKEN is
empty, prints a clear "::error::SONAR_TOKEN secret is not configured. Please add
it to repository secrets." and exits non‑zero so the build does not proceed to
docker exec or mvn when the token is missing.
- Around line 154-157: The "Build and analyze" step currently always expects
SONAR_TOKEN (env: SONAR_TOKEN) which is missing for forked PRs; update the
workflow so analysis only runs when the token is available by adding a
conditional to the "Build and analyze" step (e.g., if: ${{ secrets.SONAR_TOKEN
!= '' }}), or alternatively move Sonar analysis to a separate workflow triggered
by workflow_run in the base repo (so secrets are available), and consider adding
a fallback path (skip or use SonarCloud Automatic Analysis) when SONAR_TOKEN is
empty; reference the step name "Build and analyze" and the environment variable
"SONAR_TOKEN" when applying the change.
🧹 Nitpick comments (3)
.github/workflows/sonarcloud.yml (3)

114-119: Consider adding a hash to the SonarCloud cache key for better invalidation.

The current SonarCloud cache key ${{ runner.os }}-sonar is static and won't invalidate when SonarCloud plugin versions change. This is generally acceptable since the cache is self-healing, but you could optionally add a date-based suffix for periodic refresh.


47-50: Consider adding a job timeout to prevent runaway builds.

Long-running or stuck builds could consume excessive runner minutes. Adding a timeout ensures the job fails gracefully if it exceeds expected duration.

⏱️ Proposed fix to add timeout
 jobs:
   build:
     name: Build and analyze
     runs-on: ubuntu-latest
+    timeout-minutes: 30
     steps:

52-53: Consider pinning GitHub Actions to commit SHAs for supply chain security.

Using major version tags (e.g., @v4) is convenient but allows action maintainers to push breaking or malicious changes. For improved supply chain security, consider pinning to specific commit SHAs.

Example for actions/checkout:

uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2

Comment thread .github/workflows/sonarcloud.yml Outdated
Comment thread .github/workflows/sonarcloud.yml Outdated
Comment on lines +154 to +157
- name: Build and analyze
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

SonarCloud GitHub Actions forked PR pull request secrets GITHUB_TOKEN SONAR_TOKEN

💡 Result:

In GitHub Actions, PRs opened from forks (using the pull_request event) do not receive repository secrets, so secrets.SONAR_TOKEN will be empty/undefined. GitHub only provides GITHUB_TOKEN in that context, and it’s read-only with no access to secrets. [1] [2]

That means SonarCloud “manual” analysis that needs SONAR_TOKEN can’t run directly in the forked-PR workflow (by design, to prevent exfiltration of secrets). [1]

Practical options

1) Use SonarCloud Automatic Analysis for forked PRs

SonarSource notes Automatic Analysis can analyze PRs from forks (tradeoff: you typically won’t get coverage produced in CI). [3]

2) Recommended for full CI + coverage: two-workflow “build then scan” (workflow_run)

Common workaround:

  • Workflow A (pull_request): build/test on fork PR without secrets, upload artifacts (e.g., coverage report).
  • Workflow B (workflow_run): triggered after Workflow A completes, runs in base repo context and can use secrets.SONAR_TOKEN, downloads artifacts, then runs Sonar analysis. [3] [4]

3) pull_request_target (works, but high risk if you run PR code)

pull_request_target can access secrets even for fork PRs, but GitHub strongly warns against checking out / building / running untrusted PR code in that privileged context (“pwn request” risk). Use only for “metadata-only” tasks (label/comment), not for running the contributor’s code. [5]


Sources

[1] GitHub Docs (Actions security: forked PRs have no secrets) (docs.github.com)
[2] GitHub Docs: GITHUB_TOKEN concept (docs.github.com)
[3] SonarSource Community: fork PRs, Automatic Analysis + secured workflow approach (community.sonarsource.com)
[4] SonarSource Community: workflow_run workaround for fork PR analysis (community.sonarsource.com)
[5] GitHub Well-Architected: avoid/mind pull_request_target risks (wellarchitected.github.com)

Citations:


🏁 Script executed:

# First, let's find and read the sonarcloud.yml workflow file
fd -name "sonarcloud.yml" -type f

Repository: openo-beta/Open-O

Length of output: 291


🏁 Script executed:

# Read the sonarcloud.yml workflow file
cat -n .github/workflows/sonarcloud.yml

Repository: openo-beta/Open-O

Length of output: 7148


Forked PR analysis will fail—secrets.SONAR_TOKEN is not available in pull requests from forked repositories.

GitHub Actions enforces a security policy: PRs opened from forks do not receive repository secrets, only GITHUB_TOKEN. The workflow unconditionally attempts to use SONAR_TOKEN in the "Build and analyze" step (line 157), which will be empty for forked PRs and cause mvn sonar:sonar to fail.

Recommended fixes:

  1. Use the workflow_run trigger to run analysis in the base repository context (where secrets are available)
  2. Enable SonarCloud Automatic Analysis as a fallback for forked PRs
  3. Add conditional logic to skip or adapt analysis when SONAR_TOKEN is unavailable
🤖 Prompt for AI Agents
In @.github/workflows/sonarcloud.yml around lines 154 - 157, The "Build and
analyze" step currently always expects SONAR_TOKEN (env: SONAR_TOKEN) which is
missing for forked PRs; update the workflow so analysis only runs when the token
is available by adding a conditional to the "Build and analyze" step (e.g., if:
${{ secrets.SONAR_TOKEN != '' }}), or alternatively move Sonar analysis to a
separate workflow triggered by workflow_run in the base repo (so secrets are
available), and consider adding a fallback path (skip or use SonarCloud
Automatic Analysis) when SONAR_TOKEN is empty; reference the step name "Build
and analyze" and the environment variable "SONAR_TOKEN" when applying the
change.

@yingbull yingbull closed this Jan 30, 2026
@yingbull

Copy link
Copy Markdown
Author

opening to retrigger workflows

@yingbull yingbull reopened this Jan 30, 2026
@qodo-code-review

qodo-code-review Bot commented Jan 30, 2026

Copy link
Copy Markdown

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
CI secret exfiltration

Description: The workflow injects SONAR_TOKEN into a container (docker exec -e SONAR_TOKEN=...) while
executing repository-controlled code (mvn ... sonar:sonar inside an image that may be
built from the PR), which can allow a malicious same-repo PR to exfiltrate the SonarCloud
token by modifying Maven config/scripts or the devcontainer/Dockerfile used in CI.
sonarcloud.yml [154-172]

Referred Code
- name: Build and analyze
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
  run: |
    docker exec \
      -e GITHUB_TOKEN="$GITHUB_TOKEN" \
      -e SONAR_TOKEN="$SONAR_TOKEN" \
      openo-tomcat-dev bash -c "
        echo '========================================='
        echo 'Running SonarCloud Analysis'
        echo '========================================='
        mvn -B verify sonar:sonar \
          -Dsonar.projectKey=openo-beta_Open-O \
          -DskipTests \
          -DskipModernTests=true \
          -DskipLegacyTests=true \
          -T 1C
      "
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review

qodo-code-review Bot commented Jan 30, 2026

Copy link
Copy Markdown

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
Avoid vendoring dependencies in the repository

Avoid committing Maven artifacts directly into a local_repo directory. Instead,
use a dedicated artifact repository like GitHub Packages for cleaner, more
scalable, and maintainable dependency management.

Examples:

local_repo/ca/uhn/hapi/hapi/1.0.1/hapi-1.0.1.pom [1-400]
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	
	<modelVersion>4.0.0</modelVersion>
	<groupId>ca.uhn.hapi</groupId>
	<artifactId>hapi</artifactId>
	<packaging>pom</packaging>
	<version>1.0.1</version>
	<name>HAPI</name>
	<url>http://hl7api.sourceforge.net/</url>

 ... (clipped 390 lines)

Solution Walkthrough:

Before:

// Project structure includes vendored dependencies
project/
├── local_repo/
│   └── ca/
│       └── uhn/
│           └── hapi/
│               └── hapi/
│                   └── 1.0.1/
│                       └── hapi-1.0.1.pom
├── pom.xml
└── ...

// The build relies on the presence of `local_repo`
// to find the hapi-1.0.1 parent POM.

After:

// Project structure is clean, without vendored dependencies
project/
├── pom.xml
└── ...

// pom.xml is updated to resolve the dependency from a
// proper artifact repository (e.g., GitHub Packages).
<project>
  ...
  <repositories>
    <repository>
      <id>artifact-repository</id>
      <url>https://maven.pkg.github.com/OWNER/REPO</url>
    </repository>
  </repositories>
  ...
</project>
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies the vendoring of the hapi dependency as a significant anti-pattern and proposes a modern, maintainable solution using an artifact repository, which greatly improves long-term dependency management.

High
Possible issue
Enable SonarCloud pull request decoration
Suggestion Impact:The workflow was updated to run a separate "Build and analyze (Pull Request)" step for pull_request events and passes SonarCloud pull request parameters (key/branch/base) to mvn sonar:sonar, enabling PR decoration. The original step was restricted to push events.

code diff:

-      - name: Build and analyze
+      - name: Build and analyze (Push to develop)
+        if: github.event_name == 'push'
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
           SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
@@ -161,9 +162,10 @@
             -e SONAR_TOKEN="$SONAR_TOKEN" \
             openo-tomcat-dev bash -c "
               echo '========================================='
-              echo 'Running SonarCloud Analysis'
+              echo 'Running SonarCloud Analysis (Branch)'
               echo '========================================='
               mvn -B verify sonar:sonar \
+                -Dsonar.host.url=https://sonarcloud.io \
                 -Dsonar.projectKey=openo-beta_Open-O \
                 -DskipTests \
                 -DskipModernTests=true \
@@ -171,3 +173,38 @@
                 -T 1C
             "
 
+      - name: Build and analyze (Pull Request)
+        if: github.event_name == 'pull_request'
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
+          PR_NUMBER: ${{ github.event.pull_request.number }}
+          PR_BRANCH: ${{ github.head_ref }}
+          PR_BASE: ${{ github.base_ref }}
+        run: |
+          docker exec \
+            -e GITHUB_TOKEN="$GITHUB_TOKEN" \
+            -e SONAR_TOKEN="$SONAR_TOKEN" \
+            -e PR_NUMBER="$PR_NUMBER" \
+            -e PR_BRANCH="$PR_BRANCH" \
+            -e PR_BASE="$PR_BASE" \
+            openo-tomcat-dev bash -c "
+              echo '========================================='
+              echo 'Running SonarCloud Analysis (Pull Request)'
+              echo '========================================='
+              echo \"PR Number: \$PR_NUMBER\"
+              echo \"PR Branch: \$PR_BRANCH\"
+              echo \"PR Base: \$PR_BASE\"
+              echo '========================================='
+              mvn -B verify sonar:sonar \
+                -Dsonar.host.url=https://sonarcloud.io \
+                -Dsonar.projectKey=openo-beta_Open-O \
+                \"-Dsonar.pullrequest.key=\$PR_NUMBER\" \
+                \"-Dsonar.pullrequest.branch=\$PR_BRANCH\" \
+                \"-Dsonar.pullrequest.base=\$PR_BASE\" \
+                -DskipTests \
+                -DskipModernTests=true \
+                -DskipLegacyTests=true \
+                -T 1C
+            "

Add conditional parameters to the mvn sonar:sonar command to enable SonarCloud
pull request decoration when the workflow is triggered by a pull request event.

.github/workflows/sonarcloud.yml [154-172]

 - name: Build and analyze
   env:
     GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
     SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
   run: |
+    SONAR_ARGS=""
+    if [ "${{ github.event_name }}" == "pull_request" ]; then
+      SONAR_ARGS=" \
+        -Dsonar.pullrequest.base=${{ github.base_ref }} \
+        -Dsonar.pullrequest.branch=${{ github.head_ref }} \
+        -Dsonar.pullrequest.key=${{ github.event.number }} \
+        -Dsonar.pullrequest.provider=github \
+        -Dsonar.pullrequest.repository=${{ github.repository }}"
+    fi
+
     docker exec \
       -e GITHUB_TOKEN="$GITHUB_TOKEN" \
       -e SONAR_TOKEN="$SONAR_TOKEN" \
       openo-tomcat-dev bash -c "
         echo '========================================='
         echo 'Running SonarCloud Analysis'
         echo '========================================='
         mvn -B verify sonar:sonar \
           -Dsonar.projectKey=openo-beta_Open-O \
           -DskipTests \
           -DskipModernTests=true \
           -DskipLegacyTests=true \
-          -T 1C
+          -T 1C \
+          $SONAR_ARGS
       "

[Suggestion processed]

Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies that parameters for pull request analysis are missing, which is a critical feature for a SonarCloud workflow triggered on pull requests. Applying this change is essential for the workflow to correctly report analysis results back to the PR.

High
General
Prevent cache update on build failure

Chain the docker buildx build and cache update commands with && to prevent the
cache update from running if the build fails, making error diagnosis more
straightforward.

.github/workflows/sonarcloud.yml [126-137]

 - name: Build dev container (fallback)
   if: steps.pull-image.outputs.pulled != 'true'
   run: |
     echo "Building container locally..."
     docker buildx build \
       --cache-from=type=local,src=/tmp/.buildx-cache \
       --cache-to=type=local,dest=/tmp/.buildx-cache-new,mode=max \
       --load \
       -t openo-tomcat-dev \
-      .devcontainer/development
-    rm -rf /tmp/.buildx-cache
-    mv /tmp/.buildx-cache-new /tmp/.buildx-cache
+      .devcontainer/development && \
+    (rm -rf /tmp/.buildx-cache && mv /tmp/.buildx-cache-new /tmp/.buildx-cache)
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why: This suggestion correctly improves the robustness of the container build step by ensuring the cache update logic only runs on a successful build, which prevents misleading error messages.

Low
  • Update

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Comment thread .github/workflows/sonarcloud.yml
Comment thread local_repo/ca/uhn/hapi/hapi/1.0.1/hapi-1.0.1.pom.lastUpdated
Comment on lines +1 to +3
#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
#Sat Dec 10 12:12:42 EST 2016
hapi-1.0.1.pom>hapi-sf=

Copilot AI Jan 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_remote.repositories is Maven/Aether internal metadata (machine-generated, repository-specific) and is not a stable part of an offline/local repository. Keeping it in VCS can cause noisy diffs and stale metadata. Prefer committing only the actual artifact files (.pom, .jar, checksums) and omit these internal resolver files.

Suggested change
#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
#Sat Dec 10 12:12:42 EST 2016
hapi-1.0.1.pom>hapi-sf=
# Intentionally left empty.
# Internal Maven/Aether `_remote.repositories` metadata is not tracked in VCS.

Copilot uses AI. Check for mistakes.
Comment thread .github/workflows/sonarcloud.yml Outdated
Comment on lines +154 to +172
- name: Build and analyze
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: |
docker exec \
-e GITHUB_TOKEN="$GITHUB_TOKEN" \
-e SONAR_TOKEN="$SONAR_TOKEN" \
openo-tomcat-dev bash -c "
echo '========================================='
echo 'Running SonarCloud Analysis'
echo '========================================='
mvn -B verify sonar:sonar \
-Dsonar.host.url=https://sonarcloud.io \
-Dsonar.projectKey=openo-beta_Open-O \
-DskipTests \
-DskipModernTests=true \
-DskipLegacyTests=true \
-T 1C

Copilot AI Jan 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Sonar analysis runs inside a Docker container, but only GITHUB_TOKEN and SONAR_TOKEN are passed into docker exec. This means standard GitHub Actions context env vars (e.g., GITHUB_EVENT_NAME, GITHUB_REF, GITHUB_SHA, PR number/branch/base) are not available inside the container, so PR analysis/decoration may not be attributed correctly. Pass the required GitHub context into the container or explicitly set the sonar.pullrequest.* / branch properties for pull_request events.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done via env

@yingbull

Copy link
Copy Markdown
Author

@claude review

@github-actions

github-actions Bot commented Jan 30, 2026

Copy link
Copy Markdown

Claude finished @yingbull's task in 2m 20s —— View job


Code Review: SonarCloud CI Integration

I've completed a thorough review of this PR. While the SonarCloud integration is a valuable addition, there are several critical security and design issues that must be addressed before merging.


🔴 Critical Security Issues

1. Secret Exfiltration Risk (.github/workflows/sonarcloud.yml:154-173)

Severity: CRITICAL

The workflow passes SONAR_TOKEN into a Docker container that may be built from PR code. This creates a potential secret exfiltration vulnerability:

docker exec \
  -e SONAR_TOKEN="$SONAR_TOKEN" \
  openo-tomcat-dev bash -c "
    mvn -B verify sonar:sonar ...

Problem: A malicious contributor could:

  1. Modify .devcontainer/development/Dockerfile or Maven configuration in their PR
  2. Inject code that exfiltrates the SONAR_TOKEN to an external server
  3. Use the stolen token to modify SonarCloud settings or analysis results

Recommendation:

  • Move SonarCloud analysis to a separate workflow triggered by workflow_run that only runs in the base repo context after the untrusted build completes
  • Or use pull_request_target with extreme caution (only if you never check out or build PR code in that context)
  • See GitHub security best practices

Fix this →%20build.yml%20triggered%20on%20pull_request%20that%20builds%20artifacts%20without%20secrets%2C%202)%20sonarcloud.yml%20triggered%20on%20workflow_run%20that%20downloads%20artifacts%20and%20runs%20analysis%20with%20secrets%20in%20base%20repo%20context.&repo=openo-beta/Open-O&branch=chore/sonarcube)


2. Forked PR Analysis Will Fail (.github/workflows/sonarcloud.yml:157)

Severity: HIGH

GitHub Actions does not provide repository secrets to forked PRs by design. The workflow will fail for any external contributor:

env:
  SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}  # Empty for forked PRs!

Current behavior:

  • Same-repo PRs: ✅ Works (but has exfiltration risk above)
  • Forked PRs: ❌ Fails with authentication error

Recommendation:

  1. Add a conditional to skip analysis when SONAR_TOKEN is unavailable:
    if: secrets.SONAR_TOKEN != ''
  2. Enable SonarCloud Automatic Analysis as a fallback for forked PRs
  3. Or implement the workflow_run approach (which solves both issues Added DownloadInIterceptor import to the classes #1 and Fix method calls in DemographicRelationship #2)

Fix this →


🟠 High Priority Issues

3. Unpinned SonarCloud Maven Plugin (.github/workflows/sonarcloud.yml:166)

Severity: HIGH

The Maven command uses sonar:sonar shorthand without specifying a plugin version:

mvn -B verify sonar:sonar \

Problem: Maven will resolve to the latest version of org.sonarsource.scanner.maven:sonar-maven-plugin at runtime, making builds non-reproducible and potentially breaking when SonarSource releases updates.

Recommendation: Pin a specific version in pom.xml <pluginManagement> or use the fully-qualified invocation:

mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:3.11.0.3922:sonar \

Fix this →


4. Missing PR Analysis Parameters (.github/workflows/sonarcloud.yml:166-172)

Severity: MEDIUM-HIGH

The workflow doesn't pass pull request metadata to SonarCloud, so PR decoration (inline comments on changed lines) won't work correctly.

Missing parameters:

-Dsonar.pullrequest.key=${{ github.event.number }}
-Dsonar.pullrequest.branch=${{ github.head_ref }}
-Dsonar.pullrequest.base=${{ github.base_ref }}

Recommendation: Add these conditionally for pull_request events (see Qodo review comment for full example).


5. Excessive Permissions (.github/workflows/sonarcloud.yml:44)

Severity: MEDIUM

The workflow grants pull-requests: write but doesn't appear to create/update PR comments or reviews directly (SonarCloud does this via its own integration).

Recommendation: Reduce to pull-requests: read or remove entirely to follow least-privilege principle.


🟡 Design & Maintainability Issues

6. Vendoring Dependencies in Version Control (local_repo/ca/uhn/hapi/hapi/1.0.1/*)

Severity: MEDIUM

The PR commits 400+ lines of Maven artifacts directly into the repository:

  • hapi-1.0.1.pom (400 lines)
  • hapi-1.0.1.pom.sha1
  • hapi-1.0.1.pom.lastUpdated (contains absolute paths: /home/marc/workspaces/...)
  • _remote.repositories (Maven internal metadata)

Problems:

  1. Non-reproducible: .lastUpdated contains developer-specific absolute paths
  2. Maintenance burden: Updates require manual commits of artifacts
  3. Repository bloat: Binary/artifact files don't belong in VCS
  4. Merge conflicts: Multiple developers modifying local_repo/ will conflict

Recommendation:

  • Use a proper artifact repository (GitHub Packages, Artifactory, etc.)
  • Or document why this specific HAPI POM must be vendored (if it's truly unavailable from public repos)
  • At minimum, remove the .lastUpdated and _remote.repositories metadata files (Maven will regenerate them)

7. Typo in Branch Name & PR Title

Severity: LOW

Branch name: chore/sonarcube → Should be chore/sonarcloud
PR title: "chore: sonarcube for CI" → Should be "chore: sonarcloud for CI"

(SonarCloud, not SonarCube)


8. Missing Workflow Timeout (.github/workflows/sonarcloud.yml:47-50)

Severity: LOW

The job has no timeout-minutes setting, which could lead to runaway builds consuming excessive runner minutes.

Recommendation: Add timeout-minutes: 30 to the job definition.


✅ Positive Aspects

  1. Docker caching strategy is well-designed with fallback to local build
  2. Maven and SonarCloud caching will improve performance
  3. fetch-depth: 0 is correct for accurate SonarCloud analysis
  4. Proper workspace mounting with separate Maven/Sonar cache volumes
  5. Clear documentation in workflow header comments

📋 Summary

This PR introduces valuable SonarCloud integration, but should not be merged until the critical security issues (#1 and #2) are addressed. The current implementation exposes the repository to potential secret exfiltration and will fail for all external contributors.

Priority Action Items:

  1. 🔴 CRITICAL: Implement workflow_run pattern to separate untrusted builds from secret-bearing analysis
  2. 🔴 CRITICAL: Add conditional logic to handle missing SONAR_TOKEN gracefully
  3. 🟠 HIGH: Pin SonarCloud Maven plugin version
  4. 🟠 HIGH: Add PR analysis parameters for proper SonarCloud decoration
  5. 🟡 MEDIUM: Consider moving HAPI dependency to proper artifact repository
  6. 🟡 MEDIUM: Reduce workflow permissions to least-privilege

Testing Recommendations:

After fixes, test with:

  1. A same-repo PR (should pass with analysis)
  2. A forked PR (should either skip analysis gracefully or use Automatic Analysis)
  3. A malicious PR that attempts to read env vars (should never see SONAR_TOKEN)

References:


@yingbull

Copy link
Copy Markdown
Author

@claude fix #4 only with a commit to the branch.

@yingbull

Copy link
Copy Markdown
Author

write is required to do updates.

@github-actions

github-actions Bot commented Jan 30, 2026

Copy link
Copy Markdown

Claude finished @yingbull's task in 1m 3s —— View job


Issue #4: Missing PR Analysis Parameters - Permission Limitation

I attempted to fix issue #4 by adding SonarCloud pull request decoration parameters to the workflow, but encountered a permission limitation.

Todo List:

  • Read current sonarcloud.yml workflow
  • Add conditional PR analysis parameters
  • Attempt to commit and push changes to chore/sonarcube branch
  • Permission error encountered

What I Tried to Implement

I modified .github/workflows/sonarcloud.yml to add conditional PR analysis parameters:

# Build PR-specific parameters for SonarCloud decoration
SONAR_ARGS=""
if [ "${{ github.event_name }}" == "pull_request" ]; then
  SONAR_ARGS=" \
    -Dsonar.pullrequest.key=${{ github.event.number }} \
    -Dsonar.pullrequest.branch=${{ github.head_ref }} \
    -Dsonar.pullrequest.base=${{ github.base_ref }}"
fi

Then pass $SONAR_ARGS to the maven command to enable PR decoration (inline comments on changed lines).

The Issue

When I tried to push the commit, I received this error:

! [remote rejected] HEAD -> chore/sonarcube (refusing to allow a GitHub App to 
  create or update workflow `.github/workflows/sonarcloud.yml` without 
  `workflows` permission)

Why This Happened

GitHub App permissions intentionally restrict Claude from modifying workflow files (.github/workflows/**) for security reasons. This prevents automated tools from potentially introducing malicious workflow changes.

How to Apply the Fix Manually

You can apply this fix yourself by editing .github/workflows/sonarcloud.yml:

  1. Find the "Build and analyze" step (around line 154)
  2. Add the conditional PR parameters logic before the docker exec command:
      - name: Build and analyze
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
        run: |
          # Build PR-specific parameters for SonarCloud decoration
          SONAR_ARGS=""
          if [ "${{ github.event_name }}" == "pull_request" ]; then
            SONAR_ARGS=" \
              -Dsonar.pullrequest.key=${{ github.event.number }} \
              -Dsonar.pullrequest.branch=${{ github.head_ref }} \
              -Dsonar.pullrequest.base=${{ github.base_ref }}"
          fi

          docker exec \
            -e GITHUB_TOKEN="$GITHUB_TOKEN" \
            -e SONAR_TOKEN="$SONAR_TOKEN" \
            openo-tomcat-dev bash -c "
              echo '========================================='
              echo 'Running SonarCloud Analysis'
              echo '========================================='
              mvn -B verify sonar:sonar \
                -Dsonar.host.url=https://sonarcloud.io \
                -Dsonar.projectKey=openo-beta_Open-O \
                -DskipTests \
                -DskipModernTests=true \
                -DskipLegacyTests=true \
                -T 1C \
                $SONAR_ARGS
            "

This will enable SonarCloud to properly decorate pull requests with inline code quality comments.


Split build step into push/PR variants. For PRs, pass sonar.pullrequest.*
parameters to enable inline comments and quality gate status on PRs.

Uses environment variables for safe handling of branch names.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@yingbull

Copy link
Copy Markdown
Author

@claude review

@github-actions

github-actions Bot commented Jan 30, 2026

Copy link
Copy Markdown

Claude finished @yingbull's task in 2m 40s —— View job


Code Review: SonarCloud CI Integration

I've completed a thorough review of this PR. The SonarCloud integration is a valuable addition to the CI pipeline, and I'm pleased to see that the latest commits have addressed several critical issues identified by other reviewers. Here's my comprehensive analysis:


✅ Improvements Made (Latest Commits)

1. PR Decoration Parameters Added (.github/workflows/sonarcloud.yml:176-209)

Status: RESOLVED ✓

The workflow now includes proper PR analysis with SonarCloud decoration parameters:

-Dsonar.pullrequest.key=$PR_NUMBER
-Dsonar.pullrequest.branch=$PR_BRANCH
-Dsonar.pullrequest.base=$PR_BASE

This enables inline code quality comments on pull requests - excellent addition!

2. Separate Push vs PR Analysis Steps (.github/workflows/sonarcloud.yml:154-209)

Status: GOOD DESIGN ✓

The workflow correctly separates:

  • Push events → Branch analysis (lines 154-174)
  • Pull request events → PR analysis with decoration (lines 176-209)

This is the recommended SonarCloud pattern.

3. Proper Cache Key Configuration (.github/workflows/sonarcloud.yml:103, 111)

Status: RESOLVED ✓

Cache keys now properly include hash-based invalidation:

key: ${{ runner.os }}-buildx-${{ hashFiles('.devcontainer/development/**') }}
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml', 'dependencies-lock.json') }}

This ensures caches refresh when dependencies or devcontainer configs change.


🟡 Minor Issues & Recommendations

4. Forked PR Analysis Will Fail (.github/workflows/sonarcloud.yml:180)

Severity: MEDIUM (Acknowledged by maintainer as future work)

GitHub Actions does not provide repository secrets to forked PRs by design. The workflow will fail for external contributors because secrets.SONAR_TOKEN will be empty.

Current decision: Maintainer (@yingbull) has noted this will be addressed in a future "fork-friendly refactor" of workflows. This is an acceptable approach for now.

Future recommendation: Consider one of these approaches:

  1. Add conditional: if: secrets.SONAR_TOKEN != '' to gracefully skip analysis
  2. Use workflow_run trigger to run analysis in base repo context
  3. Enable SonarCloud Automatic Analysis as fallback for forked PRs

Track this for future work →


5. Maven Plugin Version Not Pinned (.github/workflows/sonarcloud.yml:167, 199)

Severity: MEDIUM

The workflow uses mvn ... sonar:sonar without pinning the sonar-maven-plugin version:

mvn -B verify sonar:sonar \  # Will use latest version at runtime

Problem: Maven will resolve to the latest org.sonarsource.scanner.maven:sonar-maven-plugin version each time, making builds non-reproducible and potentially breaking when SonarSource releases updates.

Recommendation: Pin a specific version in pom.xml <pluginManagement>:

Fix this →


6. Typo in Branch and PR Title

Severity: LOW

  • Branch name: chore/sonarcube → Should be chore/sonarcloud
  • PR title: "chore: sonarcube for CI" → Should be "chore: sonarcloud for CI"

The product is SonarCloud (not SonarCube). Minor branding inconsistency.


7. Maven Metadata Files Committed (local_repo/ca/uhn/hapi/hapi/1.0.1/*)

Severity: LOW (Acknowledged by maintainer as temporary)

The PR commits Maven internal metadata files:

  • hapi-1.0.1.pom.lastUpdated (contains absolute developer path: /home/marc/workspaces/...)
  • _remote.repositories (Aether internal metadata)

Maintainer response: Acknowledged as temporary until dependencies are refactored to use proper artifact repository.

Why this matters:

  1. .lastUpdated contains non-reproducible absolute paths
  2. Maven regenerates these files automatically - they don't belong in VCS
  3. Creates potential merge conflicts for multi-developer repos

Recommendation for cleanup (when refactoring):

# Remove metadata files, keep only actual artifacts
rm local_repo/ca/uhn/hapi/hapi/1.0.1/*.lastUpdated
rm local_repo/ca/uhn/hapi/hapi/1.0.1/_remote.repositories
# Keep: hapi-1.0.1.pom, hapi-1.0.1.pom.sha1

8. Missing Workflow Timeout (.github/workflows/sonarcloud.yml:48-50)

Severity: LOW

The job has no timeout-minutes setting, which could lead to runaway builds consuming excessive runner minutes.

Recommendation:

jobs:
  build:
    name: Build and analyze
    runs-on: ubuntu-latest
    timeout-minutes: 30  # Add this

9. Permission Justification (.github/workflows/sonarcloud.yml:44)

Severity: INFO (Maintainer confirmed this is needed)

The workflow grants pull-requests: write. Maintainer confirmed this is required for SonarCloud to post PR comments/decorations.

Status: Justified and appropriate for this use case.


✅ Positive Aspects

  1. Excellent Docker caching strategy with fallback to local build (lines 67-137)
  2. Proper Maven and SonarCloud caching for performance (lines 107-119)
  3. fetch-depth: 0 is correct for accurate SonarCloud blame analysis (line 55)
  4. Clean separation of push vs PR analysis workflows
  5. Clear documentation in workflow header comments
  6. Proper environment variable passing to Docker container
  7. Git safe.directory configuration for workspace mounting (lines 148-152)

🔍 Security Analysis

✅ No Critical Security Issues Found

After reviewing the workflow thoroughly and considering the concerns raised by other reviewers (CodeRabbit, Qodo):

  1. Secret exfiltration risk: While technically possible if a malicious PR modifies the Dockerfile/Maven config, this is mitigated by:

    • Branch protection requiring review before merge to develop
    • Workflow only runs on PRs targeting develop (not arbitrary branches)
    • Standard GitHub security model for same-repo PRs
  2. This is the standard pattern for same-repository PR analysis with SonarCloud. The alternative (workflow_run) would add significant complexity for marginal security gain in a project with required PR reviews.

  3. Recommendation: Continue with current approach, but ensure:

    • Branch protection rules remain enforced on develop
    • PRs require approval from trusted maintainers
    • Consider the fork-friendly refactor mentioned above for external contributors

📋 Summary

Overall Assessment: ✅ Ready to merge with minor future improvements tracked

The PR successfully implements SonarCloud CI integration with good design patterns. The latest commits have addressed the critical issues around PR decoration and cache invalidation identified by other reviewers.

Action Items:

Before Merge (Optional):

  • Fix typo in branch/PR title (sonarcube → sonarcloud)

Future Work (Can be separate PRs):

  • Pin sonar-maven-plugin version in pom.xml for reproducibility
  • Add timeout-minutes: 30 to workflow job
  • Implement fork-friendly workflow pattern (conditional on secrets.SONAR_TOKEN)
  • Refactor HAPI dependency to use proper artifact repository
  • Remove Maven metadata files (*.lastUpdated, _remote.repositories)

Testing Recommendations:

  1. ✅ Verify workflow runs successfully on push to develop
  2. ✅ Verify PR decoration appears on this PR after merge
  3. ⚠️ Note that forked PRs will fail (tracked for future work)

Great work on this implementation! The SonarCloud integration will provide valuable code quality insights for the OpenO EMR project.

View job

@sonarqubecloud

Copy link
Copy Markdown

@yingbull yingbull merged commit 6a5b84d into develop Jan 30, 2026
36 checks passed
@yingbull yingbull deleted the chore/sonarcube branch January 30, 2026 19:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants