Repository navigation
action: select the baseline by the PR base commit and explain it in the report - #110
Conversation
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The default binary is incompatible with the new flags, and baseline metadata and caution handling still have unresolved correctness issues.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 2
Open (4)
What changed in this PR
Updates baseline coverage selection to prefer the PR base commit and adds diagnostics and baseline metadata to reports.
Changes:
- Adds
baseline-run-idandbaseline-shainputs with fallback behavior. - Adds baseline run logging, warnings, and caution callouts.
- Updates report layout, documentation, changelog, and tests.
| File | Summary |
|---|---|
scripts/github-action.sh |
Implements baseline discovery, diagnostics, and report integration. |
README.md |
Updates baseline behavior and usage documentation. |
cmd/go-coverage-report/report.go |
Renders baseline metadata in reports. |
cmd/go-coverage-report/report_test.go |
Updates and expands report output tests. |
cmd/go-coverage-report/main.go |
Adds baseline CLI flags. |
CHANGELOG.md |
Documents the behavior changes. |
action.yml |
Adds baseline inputs and action configuration. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…nshot This branch serves as base for a demo pull request that shows the coverage report comment of fgrosse/go-coverage-report#110. The code coverage job installs the unreleased binary from that branch.
fank
left a comment
There was a problem hiding this comment.
Thanks for addressing this so quickly. The exact-base-SHA lookup, explicit run override, and diagnostics are all strong improvements, and I verified that the test suite and ShellCheck pass on the current head.
I think one correctness gap remains before the original failure mode is fully covered: the fallback at scripts/github-action.sh:145-147 still uses the same broad gh run list --branch … --status=success --event=… --limit=1 lookup that can return a stale result.
The new default path is correct when the base commit has a completed successful run. But there are ordinary cases where it does not:
- the base commit's run failed or was cancelled;
- it is still running when the report job reaches baseline selection;
- it completed without the expected artifact;
- the exact-SHA listing transiently returns no result.
In those cases the action falls back to find_baseline_run --branch="$TARGET_BRANCH". Because that broad query is the source of the intermittent stale selection, the fallback can still choose a substantially older run. The new caution and run-age diagnostics make the outcome visible, which is valuable, but the resulting delta can still include unrelated changes—or lose the baseline when the stale run's artifact has expired.
Would you consider making the fallback select the nearest usable ancestor of REQUESTED_BASELINE_SHA instead? For example:
- Start at the requested base SHA and inspect a bounded number of first-parent ancestors.
- Look up runs by exact
head_sha/commit. - Re-check SHA, branch, event and conclusion client-side.
- Continue when the run or coverage artifact is unavailable.
- Only use the broad “latest branch run” behavior when
baseline-sha: ""explicitly opts into the legacy semantics.
A smaller alternative would be to retrieve multiple branch candidates and filter/sort them client-side, but that still cannot guarantee the baseline is at or before the tested base. Walking ancestors preserves the intended meaning of the coverage delta and handles gaps from failed/cancelled runs.
I would treat this as a meaningful improvement even without that change: the primary path should solve most occurrences. But I would not consider the stale-baseline failure fully closed while the automatic fallback still depends on the original broad query.
|
I am also coming up against this issue. I found that this CLI request always found the most recent run Vs this which often returns data 14+ days old I agree the PR you have here is a significant improvement. Could the fallback be picked up in a later version? |
…he report Previously, the baseline coverage was always taken from the first result of "gh run list --limit=1" on the target branch. On busy repositories this API can return stale runs, so reports compared against old code or claimed the baseline artifact was unavailable even though a recent one existed. The baseline run is now selected as follows: 1. The run given via the new "baseline-run-id" input, if set. 2. The latest successful run for the new "baseline-sha" input, which defaults to the base commit of the pull request. 3. The latest successful run on the target branch, as before. The selected run is logged with its ID, commit and age. Warnings now distinguish between no baseline run being found and the artifact of the selected run not being downloadable. The pull request comment shows a single line caution callout at the top if the report does not compare against the base commit of the pull request. The new -baseline-commit, -baseline-run-id and -baseline-run-url flags name the baseline at the top of the details section, which is renamed to "Coverage details" and no longer uses headings. Fixes #109
The screenshot shows the new layout of the details section including the baseline commit and run. It was taken from fgrosse/prioqueue#6.
The action script now checks the usage of the installed binary before passing the new -baseline-* flags. This keeps it working with older binaries, e.g. when the "version" input is pinned to an older release or the action is used from main before the default version is bumped. Also label the baseline in the details section as "commit" instead of "base commit", since it is not the base commit of the pull request after a fallback or when using baseline-run-id.
47e5b13 to
15edbba
Compare
|
Thanks @fank and @henry-hived for the thorough feedback and for testing this. You're right that the fallback still relies on the broad In the follow-up I plan to combine both of your suggestions:
This also covers base commits whose run failed, was cancelled or is still in progress. |
Merging this branch will decrease overall coverage
Coverage detailsCompared to commit 6093ed4 (run #36230694596)
Please note that the "Total", "Covered", and "Missed" counts above refer to code statements instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code. Changed unit test files:
|
Bumps [fgrosse/go-coverage-report](https://github.com/fgrosse/go-coverage-report) from 1.4.0 to 1.5.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/fgrosse/go-coverage-report/releases">fgrosse/go-coverage-report's releases</a>.</em></p> <blockquote> <h2>v1.5.0</h2> <ul> <li>If the base commit of the pull request has no usable baseline run (e.g. because it failed, is still running or its artifact expired), the action now uses the nearest commit in the first-parent history of the base commit with a usable run instead of the latest run on the target branch. The runs of each commit are filtered client-side, since the filtered workflow runs API can return stale results, and further candidates are tried if a coverage artifact cannot be downloaded or does not <code>fgrosse/go-coverage-report#113</code></li> <li>Add <code>baseline-search-depth</code> and <code>baseline-max-downloads</code> inputs to configure how far the action searches for a baseline <code>fgrosse/go-coverage-report#113</code></li> <li><code>fgrosse/go-coverage-report#13</code></li> <li><strong>Behavior change:</strong> By default, the baseline coverage is now taken from the latest successful run for the base commit of the pull request (new <code>baseline-sha</code> input, defaults to <code>github.event.pull_request.base.sha</code>) instead of the latest successful run on the target branch. If there is no such run, the action falls back to the latest successful run on the target branch and emits a warning. Set <code>baseline-sha</code> to <code>""</code><code>fgrosse/go-coverage-report#110</code></li> <li>Add <code>baseline-run-id</code><code>fgrosse/go-coverage-report#110</code></li> <li>Improve diagnostics when no baseline coverage is available: warnings and the pull request comment now distinguish between no successful baseline run being found and the coverage artifact of the selected run not being downloadable, and the <code>fgrosse/go-coverage-report#110</code></li> <li>Show a caution callout at the top of the pull request comment if the report does not compare against the base commit <code>fgrosse/go-coverage-report#110</code></li> <li>Name the baseline commit and run in the details section of the report via the new <code>-baseline-commit</code>, <code>-baseline-run-id</code> and <code>-baseline-run-url</code><code>fgrosse/go-coverage-report#110</code></li> <li>Simplify the details section of the report: rename it to "Coverage details" and drop its headings to avoid mixing many <code>fgrosse/go-coverage-report#110</code></li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/fgrosse/go-coverage-report/blob/main/CHANGELOG.md">fgrosse/go-coverage-report's changelog</a>.</em></p> <blockquote> <h1>Changelog</h1> <p>All notable changes to this project will be documented in this file.</p> <p>The format is based on <a href="https://keepachangelog.com/en/1.0.0/">Keep a Changelog</a>, and this project adheres to <a href="https://semver.org/spec/v2.0.0.html">Semantic Versioning</a>.</p> <h2>[Unreleased]</h2> <p><em>Nothing yet</em></p> <h2>[v1.5.0] - 2026-10-02</h2> <ul> <li>If the base commit of the pull request has no usable baseline run (e.g. because it failed, is still running or its artifact expired), the action now uses the nearest commit in the first-parent history of the base commit with a usable run instead of the latest run on the target branch. The runs of each commit are filtered client-side, since the filtered workflow runs API can return stale results, and further candidates are tried if a coverage artifact cannot be downloaded or does not <code>fgrosse/go-coverage-report#113</code></li> <li>Add <code>baseline-search-depth</code> and <code>baseline-max-downloads</code> inputs to configure how far the action searches for a baseline <code>fgrosse/go-coverage-report#113</code></li> <li><code>fgrosse/go-coverage-report#13</code></li> <li><strong>Behavior change:</strong> By default, the baseline coverage is now taken from the latest successful run for the base commit of the pull request (new <code>baseline-sha</code> input, defaults to <code>github.event.pull_request.base.sha</code>) instead of the latest successful run on the target branch. If there is no such run, the action falls back to the latest successful run on the target branch and emits a warning. Set <code>baseline-sha</code> to <code>""</code><code>fgrosse/go-coverage-report#110</code></li> <li>Add <code>baseline-run-id</code><code>fgrosse/go-coverage-report#110</code></li> <li>Improve diagnostics when no baseline coverage is available: warnings and the pull request comment now distinguish between no successful baseline run being found and the coverage artifact of the selected run not being downloadable, and the <code>fgrosse/go-coverage-report#110</code></li> <li>Show a caution callout at the top of the pull request comment if the report does not compare against the base commit <code>fgrosse/go-coverage-report#110</code></li> <li>Name the baseline commit and run in the details section of the report via the new <code>-baseline-commit</code>, <code>-baseline-run-id</code> and <code>-baseline-run-url</code><code>fgrosse/go-coverage-report#110</code></li> <li>Simplify the details section of the report: rename it to "Coverage details" and drop its headings to avoid mixing many <code>fgrosse/go-coverage-report#110</code></li> </ul> <h2>[v1.4.0] - 2026-09-20</h2> <ul> <li>Also report packages whose coverage changed without any of their files being changed, e.g. when running integration tests with <code>go test -coverpkg</code><code>fgrosse/go-coverage-report#102</code></li> <li><code>fgrosse/go-coverage-report#103</code></li> <li>Fix the <code>exclude</code><code>fgrosse/go-coverage-report#104</code></li> </ul> <h2>[v1.3.1] - 2026-07-20</h2> <ul> <li><code>fgrosse/go-coverage-report#82</code></li> <li>Fix the <code>::endgroup::</code><code>fgrosse/go-coverage-report#89</code></li> </ul> <h2>[v1.3.0] - 2026-03-11</h2> <ul> <li>Add <code>event-name</code> and <code>target-branch</code> inputs to support workflows triggered by events other than <code>push</code><code>fgrosse/go-coverage-report#58</code></li> <li><code>fgrosse/go-coverage-report#72</code></li> <li><code>fgrosse/go-coverage-report#71</code></li> <li>Add <code>--exclude</code><code>fgrosse/go-coverage-report#59</code></li> <li>Add structured outputs (<code>total_coverage</code>, <code>coverage_delta</code>, <code>coverage_trend</code>, <code>total_statements</code>, <code>covered_statements</code>, <code>missed_statements</code><code>fgrosse/go-coverage-report#64</code></li> </ul> <h2>[v1.2.0] - 2024-08-28</h2> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/fgrosse/go-coverage-report/commit/c4bf7e78d1379325814b4dd42d80e526082e788b"><code>c4bf7e7</code></a> Release v1.5.0</li> <li><a href="https://github.com/fgrosse/go-coverage-report/commit/2d3d0a9621e933d9849ef63873c88ad1557786be"><code>2d3d0a9</code></a> action: fall back to the nearest ancestor of the base commit (<a href="https://redirect.github.com/fgrosse/go-coverage-report/issues/113">#113</a>)</li> <li><a href="https://github.com/fgrosse/go-coverage-report/commit/7752bdc735305e63c6f2739d47f2c7ceb8c9438d"><code>7752bdc</code></a> action: select the baseline by the PR base commit and explain it in the repor...</li> <li><a href="https://github.com/fgrosse/go-coverage-report/commit/6093ed43b53fa3fbe8efb961b2f79c562425587d"><code>6093ed4</code></a> Bump github/codeql-action from 4.38.0 to 4.38.1 (<a href="https://redirect.github.com/fgrosse/go-coverage-report/issues/112">#112</a>)</li> <li><a href="https://github.com/fgrosse/go-coverage-report/commit/b1b031ac32453fc15581c25a253da610796250f6"><code>b1b031a</code></a> go-coverage-report: drop package name limitation (<a href="https://redirect.github.com/fgrosse/go-coverage-report/issues/111">#111</a>)</li> <li>See full diff in <a href="https://github.com/fgrosse/go-coverage-report/compare/2eb52af4e808426e2d4edd850ff8c9ca14fce029...c4bf7e78d1379325814b4dd42d80e526082e788b">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>


Refs #109 (the remaining fallback issue will be addressed in a follow-up PR)
Problem
The baseline coverage was always taken from the first result of
gh run list --limit=1on the target branch. On busy repositories this API can return stale runs. The report then either compared against old code, or said the baseline artifact was unavailable even though a recent one existed.Changes
Baseline selection (
scripts/github-action.sh,action.yml)The baseline run is now selected in this order:
baseline-run-idinput, if set. An unknown run ID fails the job.baseline-shainput, which defaults togithub.event.pull_request.base.sha.Setting
baseline-sha: ""restores the previous behavior. This is a behavior change: by default, PRs are now compared against their base commit instead of the latest run on the target branch.Diagnostics
PR comment
[!CAUTION]callout at the top explains why.-baseline-commit,-baseline-run-idand-baseline-run-urlname the baseline at the top of the details section.Example with a fallback:
Testing
go test ./...with new tests for the baseline line, and existing tests updated for the new details layout.bash -nandshellcheckon the script.ghfor the base SHA, fallback, missing artifact, no run and explicit run ID cases.Notes
versionof the binary fails on the unknown-baseline-*flags. The defaultversionis bumped on release.screenshot.pngin the README is updated with the new layout, taken from Demo: coverage report comment for the go-coverage-report README prioqueue#6.