Skip to content

ci: add coverage check workflow#48

Merged
317787106 merged 3 commits into317787106:developfrom
0xbigapple:feature/migrate_ci_8
Mar 19, 2026
Merged

ci: add coverage check workflow#48
317787106 merged 3 commits into317787106:developfrom
0xbigapple:feature/migrate_ci_8

Conversation

@317787106
Copy link
Owner

@317787106 317787106 commented Mar 16, 2026

Summary

This PR improves the CI pipeline by adding a complete coverage reporting workflow and reorganizing PR checks.

Changes

  • Add PR coverage workflow to generate and upload JaCoCo reports to Codecov
  • Add base coverage upload workflow for develop and release_* branches
  • Add a workflow to wait for Codecov project status to produce a stable PR check result
  • Move multi-platform build checks into a separate workflow
  • Add codecov.yml configuration for project coverage checks
  • Upgrade some action version to use NodeJs 24

Coverage Check Sequence Diagram(s)

sequenceDiagram
    participant GH as GitHub (PR Event)
    participant CGB as Coverage Build<br/>(PR Gen Artifact)
    participant AS as Artifact Storage
    participant CUP as Codecov Upload<br/>(PR Upload)
    participant CV as Codecov API
    participant CPW as Coverage Project<br/>(Waiting)

    GH->>CGB: Trigger on PR to develop/<br/>release_*
    CGB->>CGB: Checkout, setup JDK 8,<br/>build project
    CGB->>CGB: Generate JaCoCo<br/>reports
    CGB->>AS: Upload jacoco-coverage<br/>artifact
    CGB-->>CUP: Workflow complete signal
    
    CUP->>AS: Download jacoco-coverage<br/>artifact
    CUP->>GH: Fetch PR details<br/>(PR number, SHA, branch)
    CUP->>CV: Upload coverage data<br/>with PR context
    CV-->>CUP: Coverage upload<br/>acknowledged

    CPW->>CV: Poll codecov/project<br/>status (every 30s)
    CV-->>CPW: Return status<br/>(pending/success/failure)
    CPW->>CPW: Check legacy commit<br/>statuses & check-runs
    
    alt Status Success
        CPW-->>GH: Job succeeds
    else Status Failure
        CPW-->>GH: Job fails
    else Still Pending
        CPW->>CPW: Wait 30s,<br/>retry (max 120x)
    end
Loading

Notes

The coverage comparison report only take effect starting from the next PR.

Summary by CodeRabbit

  • Chores
    • Enhanced CI/CD infrastructure with new pull request validation workflows supporting multi-platform builds (macOS, Ubuntu, container-based environments)
    • Added automated test coverage generation, tracking, and baseline management with Codecov integration
    • Upgraded GitHub Actions dependencies for improved stability and security

@coderabbitai
Copy link

coderabbitai bot commented Mar 16, 2026

📝 Walkthrough

Walkthrough

GitHub Actions versions upgraded across multiple workflows (v4→v5, v6→v8, v7→v8), with the pr-check workflow significantly simplified by removing build matrix jobs. New CI/CD workflows introduced for coverage generation, baseline upload, coverage upload to Codecov, and coverage status polling. A Codecov configuration file was added to manage PR comments and coverage thresholds.

Changes

Cohort / File(s) Summary
Action Version Upgrades
.github/workflows/codeql.yml, .github/workflows/math-check.yml, .github/workflows/pr-check.yml, .github/workflows/system-test.yml
Updated multiple GitHub Actions to newer versions: checkout v4→v5, upload-artifact v4→v5, setup-java v4→v5, github-script v6→v8 and v7→v8.
PR Build Workflow
.github/workflows/pr-build.yml
New workflow for PR builds with matrix-driven strategy covering macOS (Java 8/x86_64, Java 17/aarch64), Ubuntu, Rocky Linux container, and Debian 11 container, using Gradle builds with caching and daemon management.
PR Check Simplification
.github/workflows/pr-check.yml
Removed entire build matrix and related CI jobs (build, docker-build-rockylinux, docker-build-debian11), while upgrading action versions.
Coverage Workflows
.github/workflows/coverage-gen.yml, .github/workflows/coverage-update-baseline.yml, .github/workflows/coverage-upload.yml, .github/workflows/coverage-waiting.yml
New workflows for JaCoCo coverage generation on Ubuntu 24.04, baseline coverage upload to Codecov, coverage artifact download and upload, and polling Codecov/check-runs status with retry logic and 70-minute timeout.
Codecov Configuration
codecov.yml
New configuration file disabling PR comments, setting CI pass requirement to false, and defining coverage targets (auto with 0.02% threshold for project, 60% for patch).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • PR #46 — Matching CI workflow changes including PR coverage build/upload/wait workflows, base coverage upload, pr-build workflow, and codecov.yml configuration.

Poem

🐰 Workflows hop through branches with grace,
Coverage trails left in every place,
GitHub Actions leap from v4 to v5,
Codecov keeps our tests alive,
CI/CD pipelines dance in delight, 🎭

🚥 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 'ci: add coverage check workflow' accurately describes the main objective of this PR, which is to add coverage reporting workflows and related CI infrastructure for coverage checks.
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
📝 Coding Plan
  • Generate coding plan for human review comments

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

Tip

CodeRabbit can use TruffleHog to scan for secrets in your code with verification capabilities.

Add a TruffleHog config file (e.g. trufflehog-config.yml, trufflehog.yml) to your project to customize detectors and scanning behavior. The tool runs only when a config file is present.

Copy link

@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.

🧹 Nitpick comments (5)
.github/workflows/pr-build.yml (1)

16-16: Consider removing commented-out conditions.

The commented #if: conditions appear on lines 16, 53, 83, and 126. If these are no longer needed, consider removing them to keep the workflow clean. If they're intended for future use, consider adding a brief comment explaining their purpose.

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

In @.github/workflows/pr-build.yml at line 16, Remove the dead commented
conditional lines that begin with "#if: github.event.action != 'edited' &&
!failure() && !cancelled()" (and the other commented "#if:" variants) from the
workflow to keep it clean; if you intend to keep them for future toggling,
replace each commented "#if:" line with a short explanatory comment stating its
intended purpose and retention reason so reviewers know it's intentional (search
for the literal "#if: github.event.action" to locate occurrences and update them
accordingly).
.github/workflows/coverage-pr-upload.yml (1)

64-73: Consider specifying explicit coverage file paths.

The Codecov action will auto-discover coverage files, but explicitly specifying the paths improves reliability and makes the configuration self-documenting. The files are downloaded to the coverage/ directory.

♻️ Proposed enhancement
       - name: Upload to Codecov
         if: ${{ steps.pr.outputs.pr_number != '' }}
         uses: codecov/codecov-action@v5
         with:
           token: ${{ secrets.CODECOV_TOKEN }}
+          files: coverage/**/jacocoTestReport.xml
+          directory: coverage
           override_commit: ${{ steps.pr.outputs.pr_sha }}
           override_branch: ${{ steps.pr.outputs.pr_branch }}
           override_pr: ${{ steps.pr.outputs.pr_number }}
           fail_ci_if_error: true
           verbose: true
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/coverage-pr-upload.yml around lines 64 - 73, The Codecov
upload step (uses: codecov/codecov-action@v5) should explicitly set the coverage
file paths instead of relying on auto-discovery; add the action input (e.g.,
files) pointing to the downloaded artifacts in the coverage/ directory (for
example coverage/** or the specific pattern your runner produces) alongside the
existing inputs (token, override_commit, override_branch, override_pr) so
Codecov reliably picks up the correct coverage files.
.github/workflows/coverage-project-waiting.yml (2)

107-114: Transient errors are logged but could benefit from a retry limit.

Currently, transient API errors trigger a warning and continue to the next iteration, which is good. However, if API errors persist (e.g., rate limiting), the workflow will silently exhaust all attempts without distinguishing between "waiting for status" and "API unavailable."

Consider tracking consecutive transient errors and failing early if they exceed a threshold:

let consecutiveErrors = 0;
const maxConsecutiveErrors = 5;

// Inside the catch block:
consecutiveErrors++;
if (consecutiveErrors >= maxConsecutiveErrors) {
  core.setFailed(`Too many consecutive API errors: ${error.message}`);
  return;
}

// After successful API call, reset:
consecutiveErrors = 0;

This is optional since the current behavior (retry until timeout) is acceptable for most cases.

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

In @.github/workflows/coverage-project-waiting.yml around lines 107 - 114, Add
tracking for consecutive transient API errors so the job fails early if they
exceed a threshold: introduce a let consecutiveErrors = 0 and const
maxConsecutiveErrors = 5 near the retry loop, increment consecutiveErrors inside
the existing catch block that currently calls core.warning, and if
consecutiveErrors >= maxConsecutiveErrors call core.setFailed with the error
message and return to stop further retries; after any successful API call (the
block that currently proceeds when no exception is thrown) reset
consecutiveErrors = 0 so transient streaks are cleared.

44-79: Pagination may cause missed status detection in repos with many CI checks.

Both API calls may not find codecov/project if it appears beyond the first page:

  • getCombinedStatusForRef uses per_page: 100 but doesn't handle pagination
  • listForRef uses the default per_page: 30 and also lacks pagination

If the repository has more than 100 commit statuses or 30 check runs, the target context might not be found, causing unnecessary timeout.

♻️ Proposed fix with pagination support
             try {
               // Check legacy commit statuses
-              const combined = await github.rest.repos.getCombinedStatusForRef({
-                owner,
-                repo,
-                ref,
-                per_page: 100
-              });
-
-              const statuses = combined.data.statuses || [];
+              const statuses = await github.paginate(
+                github.rest.repos.listCommitStatusesForRef,
+                { owner, repo, ref, per_page: 100 }
+              );
+
               const matchedStatus = statuses.find(s => s.context === targetContext);

               if (matchedStatus) {
               // Check check-runs as a fallback
-              const checks = await github.rest.checks.listForRef({
-                owner,
-                repo,
-                ref
-              });
-
-              const checkRuns = checks.data.check_runs || [];
+              const checkRuns = await github.paginate(
+                github.rest.checks.listForRef,
+                { owner, repo, ref, per_page: 100 },
+                (response) => response.data.check_runs
+              );
+
               const matchedCheck = checkRuns.find(c => c.name === targetContext);

Alternatively, if you're confident the repository won't exceed these limits, add a comment documenting this assumption.

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

In @.github/workflows/coverage-project-waiting.yml around lines 44 - 79, The
code can miss the targetContext due to lack of pagination; update the logic
around getCombinedStatusForRef and checks.listForRef to iterate all pages (use
github.paginate or loop with page/per_page) instead of relying on a single page
(per_page: 100 and default 30). Specifically, paginate the responses for
getCombinedStatusForRef (statuses) and checks.listForRef (check_runs), search
each page for matchedStatus or matching check run for targetContext, and only
sleep/continue when all pages have been exhausted without a match; keep existing
handling of matchedStatus.state, intervalMs and sleep unchanged.
.github/workflows/coverage-base-upload.yml (1)

48-60: Consider using a glob pattern for maintainability.

Hardcoding 7 module paths works but requires manual updates when modules are added or renamed.

♻️ Alternative using glob pattern
       - name: Upload coverage artifacts
         uses: actions/upload-artifact@v5
         with:
           name: base-jacoco-xml
-          path: |
-            actuator/build/reports/jacoco/test/jacocoTestReport.xml
-            chainbase/build/reports/jacoco/test/jacocoTestReport.xml
-            common/build/reports/jacoco/test/jacocoTestReport.xml
-            consensus/build/reports/jacoco/test/jacocoTestReport.xml
-            crypto/build/reports/jacoco/test/jacocoTestReport.xml
-            framework/build/reports/jacoco/test/jacocoTestReport.xml
-            plugins/build/reports/jacoco/test/jacocoTestReport.xml
+          path: '**/build/reports/jacoco/test/jacocoTestReport.xml'
           if-no-files-found: error

If explicit control over which modules are included is intentional (e.g., to exclude certain modules), keep the current approach but add a comment explaining the rationale.

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

In @.github/workflows/coverage-base-upload.yml around lines 48 - 60, The Upload
coverage artifacts step (name "Upload coverage artifacts", uses
actions/upload-artifact@v5, artifact "base-jacoco-xml") currently lists each
module path explicitly; replace the hardcoded list with a glob pattern that
captures module jacoco reports (e.g., a repository-wide pattern matching
*/build/reports/jacoco/test/jacocoTestReport.xml) so new modules are
automatically included, and ensure if-no-files-found behavior remains as
desired; if you intentionally want to restrict modules, keep the explicit paths
but add a brief comment above the step explaining why certain modules are
included/excluded.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.github/workflows/coverage-base-upload.yml:
- Around line 48-60: The Upload coverage artifacts step (name "Upload coverage
artifacts", uses actions/upload-artifact@v5, artifact "base-jacoco-xml")
currently lists each module path explicitly; replace the hardcoded list with a
glob pattern that captures module jacoco reports (e.g., a repository-wide
pattern matching */build/reports/jacoco/test/jacocoTestReport.xml) so new
modules are automatically included, and ensure if-no-files-found behavior
remains as desired; if you intentionally want to restrict modules, keep the
explicit paths but add a brief comment above the step explaining why certain
modules are included/excluded.

In @.github/workflows/coverage-pr-upload.yml:
- Around line 64-73: The Codecov upload step (uses: codecov/codecov-action@v5)
should explicitly set the coverage file paths instead of relying on
auto-discovery; add the action input (e.g., files) pointing to the downloaded
artifacts in the coverage/ directory (for example coverage/** or the specific
pattern your runner produces) alongside the existing inputs (token,
override_commit, override_branch, override_pr) so Codecov reliably picks up the
correct coverage files.

In @.github/workflows/coverage-project-waiting.yml:
- Around line 107-114: Add tracking for consecutive transient API errors so the
job fails early if they exceed a threshold: introduce a let consecutiveErrors =
0 and const maxConsecutiveErrors = 5 near the retry loop, increment
consecutiveErrors inside the existing catch block that currently calls
core.warning, and if consecutiveErrors >= maxConsecutiveErrors call
core.setFailed with the error message and return to stop further retries; after
any successful API call (the block that currently proceeds when no exception is
thrown) reset consecutiveErrors = 0 so transient streaks are cleared.
- Around line 44-79: The code can miss the targetContext due to lack of
pagination; update the logic around getCombinedStatusForRef and
checks.listForRef to iterate all pages (use github.paginate or loop with
page/per_page) instead of relying on a single page (per_page: 100 and default
30). Specifically, paginate the responses for getCombinedStatusForRef (statuses)
and checks.listForRef (check_runs), search each page for matchedStatus or
matching check run for targetContext, and only sleep/continue when all pages
have been exhausted without a match; keep existing handling of
matchedStatus.state, intervalMs and sleep unchanged.

In @.github/workflows/pr-build.yml:
- Line 16: Remove the dead commented conditional lines that begin with "#if:
github.event.action != 'edited' && !failure() && !cancelled()" (and the other
commented "#if:" variants) from the workflow to keep it clean; if you intend to
keep them for future toggling, replace each commented "#if:" line with a short
explanatory comment stating its intended purpose and retention reason so
reviewers know it's intentional (search for the literal "#if:
github.event.action" to locate occurrences and update them accordingly).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 18facc5a-8cf4-4b2f-95dc-d90d73c15c13

📥 Commits

Reviewing files that changed from the base of the PR and between 7e5bbbd and ffc82eb.

📒 Files selected for processing (10)
  • .github/workflows/codeql.yml
  • .github/workflows/coverage-base-upload.yml
  • .github/workflows/coverage-pr-gen-artifact.yml
  • .github/workflows/coverage-pr-upload.yml
  • .github/workflows/coverage-project-waiting.yml
  • .github/workflows/math-check.yml
  • .github/workflows/pr-build.yml
  • .github/workflows/pr-check.yml
  • .github/workflows/system-test.yml
  • codecov.yml

Copy link

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

Choose a reason for hiding this comment

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

4 issues found across 10 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name=".github/workflows/coverage-base-upload.yml">

<violation number="1" location=".github/workflows/coverage-base-upload.yml:17">
P2: Runner image mismatch with the PR coverage workflow. The PR build (`coverage-pr-gen-artifact.yml`) pins `ubuntu-24.04`, but this base workflow uses `ubuntu-latest`. Pin to `ubuntu-24.04` to keep base and PR coverage comparable and avoid silent environment drift.</violation>
</file>

<file name="codecov.yml">

<violation number="1" location="codecov.yml:31">
P2: `threshold: 0.02%` allows only a 0.02 percentage-point coverage drop, which is nearly zero tolerance. If the intent was to allow a small but practical tolerance, consider `2%` instead. As-is, trivially small changes to uncovered code will fail the status check.</violation>
</file>

<file name=".github/workflows/coverage-project-waiting.yml">

<violation number="1" location=".github/workflows/coverage-project-waiting.yml:75">
P2: Missing `per_page` parameter on `checks.listForRef`. The commit-status call uses `per_page: 100`, but this check-runs fallback defaults to 30 results. On repos with many check runs the target could be absent from the first page, causing a 60-minute timeout instead of detecting the result.</violation>
</file>

<file name=".github/workflows/coverage-pr-upload.yml">

<violation number="1" location=".github/workflows/coverage-pr-upload.yml:66">
P2: Coverage artifact is downloaded to `coverage/` but the Codecov upload step doesn't specify `directory: ./coverage` to point the action at those files. The base-upload workflow explicitly sets `directory:`. Without it, the action searches the full checkout, risking stale matches and inconsistency with the companion workflow.</violation>
</file>

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

target: auto

# Allow a small coverage drop tolerance
threshold: 0.02%
Copy link

@cubic-dev-ai cubic-dev-ai bot Mar 16, 2026

Choose a reason for hiding this comment

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

P2: threshold: 0.02% allows only a 0.02 percentage-point coverage drop, which is nearly zero tolerance. If the intent was to allow a small but practical tolerance, consider 2% instead. As-is, trivially small changes to uncovered code will fail the status check.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At codecov.yml, line 31:

<comment>`threshold: 0.02%` allows only a 0.02 percentage-point coverage drop, which is nearly zero tolerance. If the intent was to allow a small but practical tolerance, consider `2%` instead. As-is, trivially small changes to uncovered code will fail the status check.</comment>

<file context>
@@ -0,0 +1,36 @@
+        target: auto
+
+        # Allow a small coverage drop tolerance
+        threshold: 0.02%
+    patch: off
+#    patch: # PR coverage/patch UI
</file context>
Fix with Cubic


- name: Upload to Codecov
if: ${{ steps.pr.outputs.pr_number != '' }}
uses: codecov/codecov-action@v5
Copy link

@cubic-dev-ai cubic-dev-ai bot Mar 16, 2026

Choose a reason for hiding this comment

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

P2: Coverage artifact is downloaded to coverage/ but the Codecov upload step doesn't specify directory: ./coverage to point the action at those files. The base-upload workflow explicitly sets directory:. Without it, the action searches the full checkout, risking stale matches and inconsistency with the companion workflow.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/workflows/coverage-pr-upload.yml, line 66:

<comment>Coverage artifact is downloaded to `coverage/` but the Codecov upload step doesn't specify `directory: ./coverage` to point the action at those files. The base-upload workflow explicitly sets `directory:`. Without it, the action searches the full checkout, risking stale matches and inconsistency with the companion workflow.</comment>

<file context>
@@ -0,0 +1,73 @@
+
+      - name: Upload to Codecov
+        if: ${{ steps.pr.outputs.pr_number != '' }}
+        uses: codecov/codecov-action@v5
+        with:
+          token: ${{ secrets.CODECOV_TOKEN }}
</file context>
Fix with Cubic

@317787106 317787106 changed the title ci: init coverage check workflow ci: add coverage check workflow Mar 16, 2026
Copy link

@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: 2

🧹 Nitpick comments (2)
.github/workflows/coverage-update-baseline.yml (1)

3-6: Seed baselines on existing long-lived branches before requiring this check.

This workflow only publishes a baseline after the next push to each target branch. Until that happens, PRs against already-cut release_* branches can still lack a comparison base, so make sure those branches get one baseline upload before codecov/project is enforced.

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

In @.github/workflows/coverage-update-baseline.yml around lines 3 - 6, The
workflow currently only triggers on future pushes to develop and release_**
branches, so existing long-lived branches may never get a baseline; update the
"on:" block in .github/workflows/coverage-update-baseline.yml (the existing on:
push branches: [ 'develop', 'release_**' ] stanza) to also include a manual
trigger and a one-time schedule so you can seed baselines now — add
workflow_dispatch and a cron schedule (or a repository_dispatch) entry alongside
push so maintainers can run the job immediately and/or it will run once on a
schedule to publish baselines for existing branches before codecov/project is
enforced.
.github/workflows/coverage-gen.yml (1)

21-58: Extract the shared Gradle/JaCoCo build into a reusable workflow.

These steps are nearly identical to build-base-coverage and have already started to drift. Pulling the common checkout/JDK/build/report/artifact logic into a reusable workflow or composite action will keep PR and baseline coverage generation aligned.

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

In @.github/workflows/coverage-gen.yml around lines 21 - 58, The
checkout/JDK/build/report/artifact steps ("Checkout code", "Set up JDK 8", "Stop
Gradle daemon", "Build", "Generate JaCoCo report", "Upload JaCoCo artifact")
should be pulled into a reusable workflow (use workflow_call) that accepts
parameters for jacoco artifact name and the list of module report paths; create
a new workflow (e.g., build-base-coverage) containing those steps, replace the
duplicated steps in this workflow and the existing build-base-coverage
invocation with a call to that reusable workflow, pass the module paths and
artifact name as inputs, and ensure the upload step still uses the passed paths
and if-no-files-found behavior so both PR and baseline coverage jobs use the
single shared implementation.
🤖 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/coverage-upload.yml:
- Around line 40-63: Update the "Get PR details" github-script to first inspect
context.payload.workflow_run.pull_requests (use workflow_run.pull_requests) and
if non-empty select the first PR from that array to set outputs (pr_number,
pr_sha, pr_branch, base_sha) using its values; only if that array is empty, fall
back to calling github.rest.pulls.list (the current logic that builds pulls from
headOwner/headBranch and uses pulls[0]). Ensure you still derive
headSha/headOwner/headBranch as needed and preserve setting core.setOutput for
pr_number, pr_sha, pr_branch, and base_sha.

In @.github/workflows/coverage-waiting.yml:
- Around line 3-6: The workflow currently triggers on pull_request and then
polls for the 'codecov/project' status, which can hang if upstream coverage or
upload workflows fail; change the trigger so this waiter runs on the completion
of the upload workflow (use workflow_run with workflows set to the
coverage/upload workflow name and types: [completed]) OR add a pre-poll check
that queries the upstream workflow runs (via the Actions API) to verify their
conclusion is 'success' before entering the long polling loop for
'codecov/project'; update the workflow file (coverage-waiting.yml) and the
polling job that references 'codecov/project' so it either only runs after
workflow_run completion or fails fast when upstream conclusions are non-success
(apply the same fix to the repeated block from lines 25-119).

---

Nitpick comments:
In @.github/workflows/coverage-gen.yml:
- Around line 21-58: The checkout/JDK/build/report/artifact steps ("Checkout
code", "Set up JDK 8", "Stop Gradle daemon", "Build", "Generate JaCoCo report",
"Upload JaCoCo artifact") should be pulled into a reusable workflow (use
workflow_call) that accepts parameters for jacoco artifact name and the list of
module report paths; create a new workflow (e.g., build-base-coverage)
containing those steps, replace the duplicated steps in this workflow and the
existing build-base-coverage invocation with a call to that reusable workflow,
pass the module paths and artifact name as inputs, and ensure the upload step
still uses the passed paths and if-no-files-found behavior so both PR and
baseline coverage jobs use the single shared implementation.

In @.github/workflows/coverage-update-baseline.yml:
- Around line 3-6: The workflow currently only triggers on future pushes to
develop and release_** branches, so existing long-lived branches may never get a
baseline; update the "on:" block in
.github/workflows/coverage-update-baseline.yml (the existing on: push branches:
[ 'develop', 'release_**' ] stanza) to also include a manual trigger and a
one-time schedule so you can seed baselines now — add workflow_dispatch and a
cron schedule (or a repository_dispatch) entry alongside push so maintainers can
run the job immediately and/or it will run once on a schedule to publish
baselines for existing branches before codecov/project is enforced.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3fdca44c-ee8e-47c0-bd7f-27c7c61d828e

📥 Commits

Reviewing files that changed from the base of the PR and between b56a34b and a19812a.

📒 Files selected for processing (5)
  • .github/workflows/coverage-gen.yml
  • .github/workflows/coverage-update-baseline.yml
  • .github/workflows/coverage-upload.yml
  • .github/workflows/coverage-waiting.yml
  • codecov.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • codecov.yml

Comment on lines +40 to +63
- name: Get PR details
id: pr
uses: actions/github-script@v8
with:
script: |
const headSha = context.payload.workflow_run.head_sha;
const headOwner = context.payload.workflow_run.head_repository.owner.login;
const headBranch = context.payload.workflow_run.head_branch;
const { data: pulls } = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
head: `${headOwner}:${headBranch}`
});
if (pulls.length > 0) {
const pr = pulls[0];
core.setOutput('pr_number', pr.number);
core.setOutput('pr_sha', headSha);
core.setOutput('pr_branch', headBranch);
core.setOutput('base_sha', pr.base.sha);
} else {
core.setFailed(`No open pull request found for ${headOwner}:${headBranch}`);
}

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

GitHub Actions documentation for the workflow_run event payload, specifically whether workflow_run.pull_requests is populated for runs triggered by pull_request events and what fields it includes.

💡 Result:

Yes—github.event.workflow_run.pull_requests can be populated when the upstream run (the one referenced by the workflow_run trigger) was triggered by a pull_request event, but it’s not guaranteed to be non-empty. GitHub describes this array as: PRs that are open and whose head_sha or head_branch matches the workflow run, and it explicitly notes these PRs “do not necessarily indicate pull requests that triggered the run.” [1]

When present, each element is a minimal PR object with these fields [1]:

  • id (integer)
  • number (integer)
  • url (string)
  • head:
    • ref (string)
    • sha (string)
    • repo: { id, url, name }
  • base:
    • ref (string)
    • sha (string)
    • repo: { id, url, name }

A GitHub Community thread also confirms that for workflow runs whose event is pull_request, the pull_requests array is included in the workflow_run payload (though it may still be empty in some scenarios). [2]

Sources:
[1] Workflow Run schema (pull_requests description + fields) (opencontextprotocol.io)
[2] GitHub Community discussion noting pull_requests exists for pull_request-originated runs (github.com)

Citations:


Use workflow_run.pull_requests to avoid ambiguous PR selection.

The code currently queries all open PRs matching the branch and takes pulls[0], which is ambiguous when multiple open PRs share the same head branch. Instead, check the pull_requests array already present in the workflow_run event payload—it contains PRs whose head_sha or head_branch matches the workflow run. If that array is non-empty, use the first PR directly; fall back to the current API query only when it is empty.

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

In @.github/workflows/coverage-upload.yml around lines 40 - 63, Update the "Get
PR details" github-script to first inspect
context.payload.workflow_run.pull_requests (use workflow_run.pull_requests) and
if non-empty select the first PR from that array to set outputs (pr_number,
pr_sha, pr_branch, base_sha) using its values; only if that array is empty, fall
back to calling github.rest.pulls.list (the current logic that builds pulls from
headOwner/headBranch and uses pulls[0]). Ensure you still derive
headSha/headOwner/headBranch as needed and preserve setting core.setOutput for
pr_number, pr_sha, pr_branch, and base_sha.

Comment on lines +3 to +6
on:
pull_request:
branches: [ 'develop', 'release_**' ]
types: [ opened, synchronize, reopened ]
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fail fast when the upstream coverage flow never reaches Codecov.

This job starts on every PR update, but it only watches for codecov/project. If Coverage Build or Codecov Upload fails or is canceled, that status is never emitted and this step burns ~60 minutes before timing out, which hides the real failure. Trigger the waiter from the upload workflow’s completion, or check the upstream workflow conclusions before entering the polling loop.

Also applies to: 25-119

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

In @.github/workflows/coverage-waiting.yml around lines 3 - 6, The workflow
currently triggers on pull_request and then polls for the 'codecov/project'
status, which can hang if upstream coverage or upload workflows fail; change the
trigger so this waiter runs on the completion of the upload workflow (use
workflow_run with workflows set to the coverage/upload workflow name and types:
[completed]) OR add a pre-poll check that queries the upstream workflow runs
(via the Actions API) to verify their conclusion is 'success' before entering
the long polling loop for 'codecov/project'; update the workflow file
(coverage-waiting.yml) and the polling job that references 'codecov/project' so
it either only runs after workflow_run completion or fails fast when upstream
conclusions are non-success (apply the same fix to the repeated block from lines
25-119).

@317787106 317787106 merged commit 3a075b9 into 317787106:develop Mar 19, 2026
14 of 15 checks passed
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