Skip to content

fix: split CI to run Sonar analysis via workflow_run#324

Merged
driessamyn merged 1 commit into
mainfrom
fix/ci-fork-pr-analysis
Mar 26, 2026
Merged

fix: split CI to run Sonar analysis via workflow_run#324
driessamyn merged 1 commit into
mainfrom
fix/ci-fork-pr-analysis

Conversation

@driessamyn
Copy link
Copy Markdown
Owner

@driessamyn driessamyn commented Mar 26, 2026

Summary

  • Split build-and-test.yml so it no longer depends on SONAR_TOKEN — fork PRs can now build and test without failing
  • Added analysis.yml triggered by workflow_run which runs in the base repo context with access to secrets
  • Sonar analysis and coverage PR comments now run as a separate workflow after the build succeeds
  • Handles fork PRs by resolving PR number via API fallback when workflow_run.pull_requests is empty

Context

PR #323 (from a fork) fails because the :sonar Gradle task cannot access the SONAR_TOKEN secret. This is a known GitHub Actions limitation — fork PRs don't receive repository secrets.

Changes

build-and-test.yml:

  • Removed sonar from ./gradlew check sonar./gradlew check
  • Removed SonarQube cache step and SONAR_TOKEN env var
  • Removed mi-kas/kover-report PR comment step
  • Dropped pull-requests: write permission

analysis.yml (new):

  • workflow_run trigger on "Build and Test" completion
  • sonar job: checks out PR head SHA, downloads coverage/test artifacts, runs Sonar with PR-specific parameters
  • coverage-comment job: parses Kover XML report and posts/updates a coverage comment on the PR

Test plan

Summary by CodeRabbit

  • Chores

    • Reorganized CI: separated code quality analysis and coverage reporting into a dedicated post-build workflow.
    • Removed SonarQube steps from the main build-and-test pipeline.
  • New Features

    • New Code Analysis workflow runs SonarQube scans and posts formatted coverage summaries to pull requests, including a coverage table and PR-specific parameters when available.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 26, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4e24b01d-925d-4ecf-83ea-b5343023ee71

📥 Commits

Reviewing files that changed from the base of the PR and between 6e6496e and cbfc316.

📒 Files selected for processing (2)
  • .github/workflows/analysis.yml
  • .github/workflows/build-and-test.yml
🚧 Files skipped from review as they are similar to previous changes (2)
  • .github/workflows/build-and-test.yml
  • .github/workflows/analysis.yml

📝 Walkthrough

Walkthrough

Extracts SonarQube analysis and coverage PR-commenting out of the build workflow into a new .github/workflows/analysis.yml workflow that runs after the build-and-test workflow, with conditional jobs for SonarQube scanning and posting coverage comments to PRs.

Changes

Cohort / File(s) Summary
Build and Test Workflow Cleanup
\.github/workflows/build-and-test.yml
Removed SonarQube cache and SONAR_TOKEN usage, removed Kover coverage PR-comment step, and simplified Gradle invocation to ./gradlew check.
New Analysis Workflow
\.github/workflows/analysis.yml
Added workflow triggered on workflow_run of build-and-test with two jobs: SonarQube Analysis (JDK17, Gradle cache, downloads artifacts, runs ./gradlew sonar, resolves PR number for PR-specific params) and Coverage PR Comment (downloads coverage-report, parses Kover XML for LINE/BRANCH/INSTRUCTION coverage, formats Markdown table, and PATCH/POSTs PR comment via gh api).

Sequence Diagram

sequenceDiagram
    participant Build as "Build & Test\nWorkflow"
    participant Artifacts as "Artifact\nStorage"
    participant Trigger as "Workflow\nRun Trigger"
    participant Analysis as "Analysis\nWorkflow"
    participant Sonar as "SonarQube"
    participant GHAPI as "GitHub\nPR API"

    Build->>Artifacts: upload coverage-report & junit-test-results
    Build->>Trigger: workflow_run (completed)
    Trigger->>Analysis: start on workflow_run

    rect rgba(100,150,200,0.5)
    Note over Analysis,Sonar: SonarQube Analysis Job
    Analysis->>Artifacts: download artifacts
    Analysis->>Sonar: run ./gradlew sonar (with PR props if resolved)
    Sonar-->>Analysis: analysis results
    end

    rect rgba(150,200,100,0.5)
    Note over Analysis,GHAPI: Coverage PR Comment Job
    Analysis->>Artifacts: download coverage-report
    Analysis->>Analysis: parse Kover XML -> compute LINE/BRANCH/INSTRUCTION
    Analysis->>GHAPI: PATCH existing comment or POST new comment with table
    GHAPI-->>Analysis: comment updated/created
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I hopped through CI, nose all a-twitch,

pulled analysis out from the build's busy stitch.
Sonar now hums on its own little stage,
while coverage comments find their neat page—
a carrot for pipelines, tidy and rich! 🥕

🚥 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 directly describes the main change: splitting CI to run Sonar analysis via workflow_run, which is the core objective of the PR.
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
  • Commit unit tests in branch fix/ci-fork-pr-analysis

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
.github/workflows/analysis.yml (1)

111-125: PR resolution logic is duplicated across jobs.

The PR number resolution logic (lines 111-125) is nearly identical to the one in the sonar job (lines 64-78). While acceptable for now, consider extracting this into a reusable composite action or a shared script if maintenance becomes burdensome.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/analysis.yml around lines 111 - 125, The "Resolve PR
number" step duplicates PR resolution logic used in the sonar job; extract that
shell block into a reusable unit (either a composite GitHub Action or a shared
script) and replace both occurrences with a single call. Locate the step named
"Resolve PR number" and the similar block in the sonar job, move the logic into
a composite action (or a script checked into the repo) that accepts GH_TOKEN and
returns number via outputs, then update both jobs to call that action (or
execute the script) and consume its output.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/analysis.yml:
- Line 77: The hardcoded fallback to 'main' when
github.event.workflow_run.pull_requests[0].base.ref is empty can pick the wrong
base branch; change the step that sets "base=..." to detect an empty base ref
and query the GitHub API (via gh pr view) for the real baseRefName using the PR
number, then write that value to GITHUB_OUTPUT (e.g., obtain PR_NUMBER from
github.event.workflow_run.pull_requests[0].number or the workflow context, call
gh pr view "$PR_NUMBER" --json baseRefName and use its baseRefName if present,
otherwise fallback to main). Ensure the step references the same output variable
name (base) and that gh is available/authenticated in the job.

---

Nitpick comments:
In @.github/workflows/analysis.yml:
- Around line 111-125: The "Resolve PR number" step duplicates PR resolution
logic used in the sonar job; extract that shell block into a reusable unit
(either a composite GitHub Action or a shared script) and replace both
occurrences with a single call. Locate the step named "Resolve PR number" and
the similar block in the sonar job, move the logic into a composite action (or a
script checked into the repo) that accepts GH_TOKEN and returns number via
outputs, then update both jobs to call that action (or execute the script) and
consume its output.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: be5b70fa-d153-424a-815a-45e46677c286

📥 Commits

Reviewing files that changed from the base of the PR and between 452b33d and 6e6496e.

📒 Files selected for processing (2)
  • .github/workflows/analysis.yml
  • .github/workflows/build-and-test.yml

Comment thread .github/workflows/analysis.yml
Fork PRs cannot access repository secrets, causing the SonarQube
analysis step to fail. Split the build workflow so that secret-dependent
steps (Sonar, coverage PR comment) run in a separate workflow_run-
triggered workflow that executes in the base repo context.
@driessamyn driessamyn force-pushed the fix/ci-fork-pr-analysis branch from 62c6809 to cbfc316 Compare March 26, 2026 21:08
@github-actions
Copy link
Copy Markdown

Unit Tests

 61 files  ±0   61 suites  ±0   2m 56s ⏱️ -4s
545 tests ±0  545 ✅ ±0  0 💤 ±0  0 ❌ ±0 
561 runs  ±0  561 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit cbfc316. ± Comparison against base commit 452b33d.

This pull request removes 39 and adds 39 tests. Note that renamed tests count towards both.
net.samyn.kapper.internal.automapper.SQLTypesConverterTest ‑ [10] LONGVARCHAR, "LONGVARCHAR", net.samyn.kapper.internal.automapper.SQLTypesConverterTest$Companion$$Lambda$1114/0x00007ff03c586ee0@b110df7
net.samyn.kapper.internal.automapper.SQLTypesConverterTest ‑ [11] NCHAR, "NCHAR", net.samyn.kapper.internal.automapper.SQLTypesConverterTest$Companion$$Lambda$1115/0x00007ff03c587100@1b6918b6
net.samyn.kapper.internal.automapper.SQLTypesConverterTest ‑ [12] INSTANT, net.samyn.kapper.internal.automapper.SQLTypesConverterTest$Companion$$Lambda$957/0x00007ff03c54fca8@4b2ea3d5
net.samyn.kapper.internal.automapper.SQLTypesConverterTest ‑ [12] NCLOB, "NCLOB", net.samyn.kapper.internal.automapper.SQLTypesConverterTest$Companion$$Lambda$1116/0x00007ff03c587320@30150182
net.samyn.kapper.internal.automapper.SQLTypesConverterTest ‑ [13] DATE, net.samyn.kapper.internal.automapper.SQLTypesConverterTest$Companion$$Lambda$958/0x00007ff03c5543b8@6d8703fe
net.samyn.kapper.internal.automapper.SQLTypesConverterTest ‑ [13] NVARCHAR, "NVARCHAR", net.samyn.kapper.internal.automapper.SQLTypesConverterTest$Companion$$Lambda$1117/0x00007ff03c587540@3570332a
net.samyn.kapper.internal.automapper.SQLTypesConverterTest ‑ [14] LOCALDATE, net.samyn.kapper.internal.automapper.SQLTypesConverterTest$Companion$$Lambda$959/0x00007ff03c5545d8@33ac8b86
net.samyn.kapper.internal.automapper.SQLTypesConverterTest ‑ [14] ROWID, "ROWID", net.samyn.kapper.internal.automapper.SQLTypesConverterTest$Companion$$Lambda$1118/0x00007ff03c587760@618dd025
net.samyn.kapper.internal.automapper.SQLTypesConverterTest ‑ [15] LOCALDATETIME, net.samyn.kapper.internal.automapper.SQLTypesConverterTest$Companion$$Lambda$960/0x00007ff03c5547f8@7eeedf4e
net.samyn.kapper.internal.automapper.SQLTypesConverterTest ‑ [15] SQLXML, "SQLXML", net.samyn.kapper.internal.automapper.SQLTypesConverterTest$Companion$$Lambda$1119/0x00007ff03c587980@d6e6eab
…
net.samyn.kapper.internal.automapper.SQLTypesConverterTest ‑ [10] LONGVARCHAR, "LONGVARCHAR", net.samyn.kapper.internal.automapper.SQLTypesConverterTest$Companion$$Lambda$1120/0x00007f1e50587a28@66eccf62
net.samyn.kapper.internal.automapper.SQLTypesConverterTest ‑ [11] NCHAR, "NCHAR", net.samyn.kapper.internal.automapper.SQLTypesConverterTest$Companion$$Lambda$1121/0x00007f1e50587c48@a2ae025
net.samyn.kapper.internal.automapper.SQLTypesConverterTest ‑ [12] INSTANT, net.samyn.kapper.internal.automapper.SQLTypesConverterTest$Companion$$Lambda$970/0x00007f1e505565c0@236bc122
net.samyn.kapper.internal.automapper.SQLTypesConverterTest ‑ [12] NCLOB, "NCLOB", net.samyn.kapper.internal.automapper.SQLTypesConverterTest$Companion$$Lambda$1122/0x00007f1e5058c000@4ecace98
net.samyn.kapper.internal.automapper.SQLTypesConverterTest ‑ [13] DATE, net.samyn.kapper.internal.automapper.SQLTypesConverterTest$Companion$$Lambda$971/0x00007f1e505567e0@4dd069d7
net.samyn.kapper.internal.automapper.SQLTypesConverterTest ‑ [13] NVARCHAR, "NVARCHAR", net.samyn.kapper.internal.automapper.SQLTypesConverterTest$Companion$$Lambda$1123/0x00007f1e5058c220@3bc77524
net.samyn.kapper.internal.automapper.SQLTypesConverterTest ‑ [14] LOCALDATE, net.samyn.kapper.internal.automapper.SQLTypesConverterTest$Companion$$Lambda$972/0x00007f1e50556a00@70c04c7d
net.samyn.kapper.internal.automapper.SQLTypesConverterTest ‑ [14] ROWID, "ROWID", net.samyn.kapper.internal.automapper.SQLTypesConverterTest$Companion$$Lambda$1124/0x00007f1e5058c440@7f0b674f
net.samyn.kapper.internal.automapper.SQLTypesConverterTest ‑ [15] LOCALDATETIME, net.samyn.kapper.internal.automapper.SQLTypesConverterTest$Companion$$Lambda$973/0x00007f1e50556c20@56452cc1
net.samyn.kapper.internal.automapper.SQLTypesConverterTest ‑ [15] SQLXML, "SQLXML", net.samyn.kapper.internal.automapper.SQLTypesConverterTest$Companion$$Lambda$1125/0x00007f1e5058c660@82df3ed
…

@github-actions
Copy link
Copy Markdown

SQLITE Integration Tests

11 files  ±0  11 suites  ±0   25s ⏱️ +3s
51 tests ±0  46 ✅ ±0  5 💤 ±0  0 ❌ ±0 
81 runs  ±0  76 ✅ ±0  5 💤 ±0  0 ❌ ±0 

Results for commit cbfc316. ± Comparison against base commit 452b33d.

@github-actions
Copy link
Copy Markdown

DUCKDB Integration Tests

11 files  ±0  11 suites  ±0   22s ⏱️ -5s
51 tests ±0  51 ✅ ±0  0 💤 ±0  0 ❌ ±0 
81 runs  ±0  81 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit cbfc316. ± Comparison against base commit 452b33d.

@github-actions
Copy link
Copy Markdown

POSTGRESQL Integration Tests

11 files  ±0  11 suites  ±0   27s ⏱️ +2s
51 tests ±0  51 ✅ ±0  0 💤 ±0  0 ❌ ±0 
81 runs  ±0  81 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit cbfc316. ± Comparison against base commit 452b33d.

@github-actions
Copy link
Copy Markdown

MYSQL Integration Tests

11 files  ±0  11 suites  ±0   46s ⏱️ -1s
51 tests ±0  46 ✅ ±0  5 💤 ±0  0 ❌ ±0 
81 runs  ±0  76 ✅ ±0  5 💤 ±0  0 ❌ ±0 

Results for commit cbfc316. ± Comparison against base commit 452b33d.

@github-actions
Copy link
Copy Markdown

MSSQLSERVER Integration Tests

11 files  ±0  11 suites  ±0   44s ⏱️ -1s
51 tests ±0  46 ✅ ±0  5 💤 ±0  0 ❌ ±0 
81 runs  ±0  76 ✅ ±0  5 💤 ±0  0 ❌ ±0 

Results for commit cbfc316. ± Comparison against base commit 452b33d.

@github-actions
Copy link
Copy Markdown

ORACLE Integration Tests

11 files  ±0  11 suites  ±0   1m 15s ⏱️ -2s
51 tests ±0  46 ✅ ±0  5 💤 ±0  0 ❌ ±0 
81 runs  ±0  76 ✅ ±0  5 💤 ±0  0 ❌ ±0 

Results for commit cbfc316. ± Comparison against base commit 452b33d.

@driessamyn driessamyn merged commit dd05d0b into main Mar 26, 2026
18 checks passed
@driessamyn driessamyn deleted the fix/ci-fork-pr-analysis branch March 26, 2026 21:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant