Skip to content

Fix: Honour go.mod toolchain and wire Sonar coverage - #76

Merged
ModeSevenIndustrialSolutions merged 4 commits into
lfreleng-actions:mainfrom
modeseven-lfreleng-actions:feat/sonar-coverage-and-go-toolchain
Aug 31, 2026
Merged

Fix: Honour go.mod toolchain and wire Sonar coverage#76
ModeSevenIndustrialSolutions merged 4 commits into
lfreleng-actions:mainfrom
modeseven-lfreleng-actions:feat/sonar-coverage-and-go-toolchain

Conversation

@ModeSevenIndustrialSolutions

@ModeSevenIndustrialSolutions ModeSevenIndustrialSolutions commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Follows the Phase 1 sequencing in the interim evaluation (#51), taking the two items whose blockers have now cleared. One topic — the lanes consuming their dependencies correctly — and one atomic commit each, plus a commit carrying review feedback.

The Go half did not land where the issue expected. Investigating #43 turned up a live defect in the CLM lane, and showed that implementing #43 as written would have spread it rather than fixed it.

Commits

Fix: Honour the go.mod toolchain directivecloses #43

This is a live bug, not a consistency tidy-up. sonatype-lifecycle.yaml could not scan any Go project that pins a toolchain newer than its go directive.

Three actions/setup-go behaviours combine badly:

Behaviour Verified against
v6+ reads both directives from go-version-file and prefers toolchain parseGoVersionFile in src/installer.ts, identical at v6.5.0 and v7.0.0
go-version beats go-version-file outright resolveVersionInput in src/main.ts
It exports GOTOOLCHAIN=local for the rest of the job setGoToolchain(), src/main.ts:181

The lane passed build-metadata-action's go_go_version — documented as "Minimum Go version declared in go.mod (go directive)" — as go-version. That suppressed the file, so the toolchain directive never applied. And because GOTOOLCHAIN=local stops Go fetching the toolchain the module asks for, the result is a hard stop rather than a build on an older Go:

go: go.mod requires go >= 1.25.3 (running go 1.23.0; GOTOOLCHAIN=local)

The fix is to drop go-version and let setup-go read the file, which is the only form honouring both directives. build-metadata-action does emit go_toolchain alongside go_go_version, so a correct value could be composed — but that restates parsing setup-go already does, including rc toolchains and the GOTOOLCHAIN=local escape.

Go also leaves the Gather build metadata step, since nothing consumed its output on that path any more. That step compiles a Go binary at runtime, so Go scans lose a build they never needed.

Why this closes #43 rather than implementing it. The issue proposed extending build-metadata-action to the Sonar lane's Go path for consistency with the JDK. The Sonar lane turns out to be the one already correct: it reaches setup-go through go-test-action, whose go_version_file defaults to go.mod and yields only to an explicit go_version. The lanes are now aligned — on go-version-file, the opposite direction to the one proposed. The JDK analogy does not carry over, because setup-java cannot read a build file this way.

Feat: Wire build coverage paths into the Sonar scancloses #70

Unblocked: the coverage_report_paths input the issue was waiting on landed in sonarqube-cloud-scan-action v1.5.0 (published today), which this bumps to.

maven-build-action has aggregated reactor coverage since v0.4.0 and the lane consumed neither end. Maven analysis mode derives report paths from the project model and was fine; CLI mode never reads that model, so coverage rested on sonar-project.properties or a default glob — a reactor reporting anywhere else scanned with no coverage, and stale reports from an earlier step scanned with the wrong coverage.

An empty value is a statement rather than an absence, so a Maven build that measured no aggregate now says so in the log and job summary. The message names the benign causes (project-owned coverage data, no JaCoCo agent) so it does not read as a failure.

Adds the CLI-mode self-test leg the issue's Validation section asks for. See the caveat under review feedback below — that leg proves less than it appears to.

Docs: Record the Go toolchain and coverage decisions

D21 and D22 in docs/BRIEF.md, both recording an inversion of what was previously assumed.

Fix: Address Copilot review feedback

Two items, both valid — see the resolved threads.

  1. D21/D22 were anchored on a link reference definition that sits inside D20 rather than at its end, so they spliced into the middle of that section and left D20's closing paragraph stranded after them, still describing the behaviour D21 replaces. The record documented the fixed and the broken implementation at once, with the broken one reading as current because it came last. Sections moved after D20; that paragraph rewritten rather than deleted, so the java_version analogy that motivated the original design is still on record along with why it fails for Go.
  2. The new CLI-mode self-test cannot fail. test-maven-project declares sonar.coverage.jacoco.xmlReportPaths in its own sonar-project.properties, so the Scanner CLI finds reactor coverage whether or not the lane forwards anything. Removing that property is not an option — the fixture's own comment says keeping both analysis modes working is the point of it — and the log assertion Wire coverage_report_paths from the build into the Sonar scan #70 asks for is unreachable, since sonarqube-cloud-scan-action exposes no output carrying the assembled arguments. Raised as CLI-mode coverage self-test cannot fail: the fixture supplies the property #77; the job now states what it does and does not prove.

Issues raised from this work

Both are the same shape as the existing #74, and #77 notes the pattern: three self-tests that exercise a path they cannot see fail, each a silent-failure mode of the kind docs/BRIEF.md D12 warns about. Worth one deliberate pass at fixture coverage rather than three separate patches.

Ready to close without code

The audit recorded in #73 already answers two open issues on their own stated terms; neither needs an implementation:

Happy to close both, or to implement mvn_pom_file as plumbing if you would rather have the input than the decision — say which.

Still blocked or sequenced later

Validation

  • prek run --all-files — passed
  • zizmor --persona auditor .github/workflows/ examples/ — no findings
  • aislop ci — 0 errors, 0 warnings (0 files in scope for this repository)
  • The new job-summary script extracted and run under bash to confirm the heredoc and warning render correctly
  • Action pin c8c342bf621f6e7e8622b12a19fa3539a6237f3c is the commit for v1.5.0, dereferenced from the tag object

Not run: testing.yaml, which is workflow_dispatch-only and needs organisation credentials. Worth dispatching against this branch before release — though note per #77 that the coverage leg will pass either way until a discriminating fixture exists.

go.mod carries two version directives. setup-go v6 onwards reads both
from go-version-file and prefers 'toolchain' over 'go', but the lane
passed build-metadata-action's go_go_version as go-version, and
go-version beats go-version-file outright. The file was therefore
never read and the 'toolchain' directive never applied.

That fails the build rather than quietly degrading it: setup-go
exports GOTOOLCHAIN=local, so Go will not fetch the toolchain the
module asks for and stops with 'go.mod requires go >= X (running
go Y; GOTOOLCHAIN=local)'. Any Go project pinning a toolchain newer
than its go directive could not be scanned.

Drop go-version and let setup-go read the file, which is the only
form honouring both directives. build-metadata-action does expose
go_toolchain alongside go_go_version, but composing the two here
would restate parsing setup-go already does, including its handling
of rc toolchains and of GOTOOLCHAIN=local, against an output
documented as the 'go' directive alone.

Go leaves 'Gather build metadata' with it, since nothing consumed
that step's output on the Go path any more; the step builds a Go
binary at runtime, so Go scans lose a compile they never needed.

The Sonar lane needs no equivalent change: it reaches setup-go
through go-test-action, whose go_version_file already defaults to
go.mod and is only overridden by an explicit go_version.

Closes lfreleng-actions#43

Co-authored-by: Claude <noreply@anthropic.com>
Signed-off-by: Matthew Watkins <mwatkins@linuxfoundation.org>
maven-build-action v0.4.0 aggregates JaCoCo coverage across a
reactor and reports the paths as coverage_report_paths, but the lane
consumed neither that output nor the scan action input that takes
it. The input landed in sonarqube-cloud-scan-action v1.5.0, which
this bumps to, so the wiring is no longer blocked.

Maven analysis mode derives report paths from the project model and
was already fine. CLI mode never reads that model, so coverage rested
on sonar-project.properties or a default glob: a reactor whose
modules report anywhere but the default location scanned with no
coverage at all, and one with stale reports from an earlier step
scanned with the wrong coverage. Naming the paths the build actually
measured makes both modes deterministic for any reactor shape.

An empty value is meaningful rather than absent, so a Maven build
that produced no aggregate now says so in the log and the job
summary. Both outcomes publish a coverage figure and a wrong one
reads exactly like a right one, which is the D12 hazard; the message
names the benign causes so it does not read as a failure.

Closes lfreleng-actions#70

Co-authored-by: Claude <noreply@anthropic.com>
Signed-off-by: Matthew Watkins <mwatkins@linuxfoundation.org>
Two decisions from this cycle, both worth recording because both
invert what was previously assumed.

D21 explains why Go version selection is the one place the lanes do
not reach for build-metadata-action. Issue lfreleng-actions#43 proposed the opposite,
for consistency with how the JDK is resolved, and following it would
have propagated a defect rather than removed it: go.mod's toolchain
directive outranks its go directive, and only setup-go reading the
file honours both. The JDK comparison does not carry over, because
setup-java cannot read a build file the same way.

D22 records that the build now names the coverage it measured, and
why an empty value is reported rather than passed over: both
outcomes publish a coverage figure, and a wrong one reads exactly
like a right one.

Also notes on the Go self-test that no fixture carries a toolchain
directive, so nothing exercises the D21 path (lfreleng-actions#75).

Co-authored-by: Claude <noreply@anthropic.com>
Signed-off-by: Matthew Watkins <mwatkins@linuxfoundation.org>
@ModeSevenIndustrialSolutions
ModeSevenIndustrialSolutions requested review from a team and a balanced review from Copilot August 28, 2026 13:55
@github-actions github-actions Bot added the bug Something isn't working label Aug 28, 2026

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

Fixes Go toolchain selection and forwards Maven JaCoCo coverage paths into Sonar analysis.

Changes:

  • Reads Go versions directly from go.mod.
  • Wires Maven coverage paths into Sonar scans.
  • Adds CLI-mode validation and records design decisions.

Reviewed changes

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

File Description
docs/BRIEF.md Documents toolchain and coverage decisions.
.github/workflows/testing.yaml Adds Maven CLI-analysis coverage.
.github/workflows/sonatype-lifecycle.yaml Honors the toolchain directive.
.github/workflows/sonarqube-cloud.yaml Passes generated coverage paths to Sonar.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread docs/BRIEF.md
Comment thread .github/workflows/testing.yaml
Two items, both correct.

1. D21 and D22 landed mid-D20, because the anchor used was a link
   reference definition sitting inside that section rather than at
   its end. D20's closing paragraph was left stranded after them,
   still describing the behaviour D21 replaces, so the record
   documented the fixed and the broken implementation at once. Move
   the new sections after D20 and rewrite that paragraph to state
   what the lane does now and point forward to D21 for why.

2. The new CLI-mode self-test cannot fail. test-maven-project
   declares sonar.coverage.jacoco.xmlReportPaths in its own
   sonar-project.properties, so the Scanner CLI finds reactor
   coverage whether or not the lane forwards the build's paths;
   deleting the wiring would leave the job green. That property is
   deliberate, per the fixture's own comment, so removing it would
   break the both-modes-work case the fixture exists to prove.
   Discriminating needs a fixture without the property or an
   assertion on the analysis log, neither of which exists yet:
   raised as lfreleng-actions#77 and stated on the job, rather than left implying
   coverage it does not have.

Co-authored-by: Claude <noreply@anthropic.com>
Signed-off-by: Matthew Watkins <mwatkins@linuxfoundation.org>
Copilot AI review requested due to automatic review settings August 28, 2026 14:04

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 4 out of 4 changed files in this pull request and generated no new comments.

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

🤖 Auto-approved by agent: reviewed workflow/code change for security and CI/CD impact, found low risk. Wires Maven coverage_report_paths into Sonar scan; Setup Go reads go.mod via go-version-file to honour toolchain. Additive/compatible; SHA pins retained; no widened permissions.

@ModeSevenIndustrialSolutions
ModeSevenIndustrialSolutions merged commit 8334ce0 into lfreleng-actions:main Aug 31, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Wire coverage_report_paths from the build into the Sonar scan Use build-metadata-action for Go version detection in both scan lanes

3 participants