Fix: Honour go.mod toolchain and wire Sonar coverage - #76
Merged
ModeSevenIndustrialSolutions merged 4 commits intoAug 31, 2026
Conversation
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
requested review from
a team
and
a balanced review from Copilot
August 28, 2026 13:55
Copilot started reviewing on behalf of
ModeSevenIndustrialSolutions
August 28, 2026 13:56
View session
There was a problem hiding this comment.
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.
2 tasks
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 started reviewing on behalf of
ModeSevenIndustrialSolutions
August 28, 2026 14:04
View session
zxiiro
approved these changes
Aug 29, 2026
zxiiro
left a comment
There was a problem hiding this comment.
🤖 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
merged commit Aug 31, 2026
8334ce0
into
lfreleng-actions:main
11 checks passed
This was referenced Sep 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 directive— closes #43This is a live bug, not a consistency tidy-up.
sonatype-lifecycle.yamlcould not scan any Go project that pins atoolchainnewer than itsgodirective.Three
actions/setup-gobehaviours combine badly:go-version-fileand preferstoolchainparseGoVersionFileinsrc/installer.ts, identical at v6.5.0 and v7.0.0go-versionbeatsgo-version-fileoutrightresolveVersionInputinsrc/main.tsGOTOOLCHAIN=localfor the rest of the jobsetGoToolchain(),src/main.ts:181The lane passed
build-metadata-action'sgo_go_version— documented as "Minimum Go version declared in go.mod (go directive)" — asgo-version. That suppressed the file, so thetoolchaindirective never applied. And becauseGOTOOLCHAIN=localstops Go fetching the toolchain the module asks for, the result is a hard stop rather than a build on an older Go:The fix is to drop
go-versionand let setup-go read the file, which is the only form honouring both directives.build-metadata-actiondoes emitgo_toolchainalongsidego_go_version, so a correct value could be composed — but that restates parsing setup-go already does, including rc toolchains and theGOTOOLCHAIN=localescape.Go also leaves the
Gather build metadatastep, 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-actionto 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 throughgo-test-action, whosego_version_filedefaults togo.modand yields only to an explicitgo_version. The lanes are now aligned — ongo-version-file, the opposite direction to the one proposed. The JDK analogy does not carry over, becausesetup-javacannot read a build file this way.Feat: Wire build coverage paths into the Sonar scan— closes #70Unblocked: the
coverage_report_pathsinput the issue was waiting on landed insonarqube-cloud-scan-actionv1.5.0 (published today), which this bumps to.maven-build-actionhas 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 onsonar-project.propertiesor 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 decisionsD21 and D22 in
docs/BRIEF.md, both recording an inversion of what was previously assumed.Fix: Address Copilot review feedbackTwo items, both valid — see the resolved threads.
java_versionanalogy that motivated the original design is still on record along with why it fails for Go.test-maven-projectdeclaressonar.coverage.jacoco.xmlReportPathsin its ownsonar-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, sincesonarqube-cloud-scan-actionexposes 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
toolchaindirective, so nothing in CI exercises the D21 path. The CLM defect fixed here shipped in Feat: Add a Go build_type to the Sonatype Lifecycle lane #38 and passed every Go self-test throughout, becausetest-go-project'sgo.modhas nothing to get wrong.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.mdD12 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:
ENV_SECRETSis the literal"{}"in every in-scope caller, andENV_VARScarries onlyMAVEN_OPTS(covered bymvn_opts) or two Sonar-shaped keys whose effect on that code path is doubtful. The issue's step 2 says record and close.MVN_POM_FILEhas four callers and every value names a file calledpom.xml; only the directory varies, whichpath_prefixalready selects. The issue says closing with a note indocs/BRIEF.mdis the right outcome, and that note is inmain.Happy to close both, or to implement
mvn_pom_fileas plumbing if you would rather have the input than the decision — say which.Still blocked or sequenced later
cyclonedx-gomodcomparison; it gates all of Cluster A (Generalise the Nexus IQ SBOM upload path beyond Go #40, Add a Python build_type to the Sonatype Lifecycle lane #42's SBOM half).policy-opa-pdpcutover, per the PR Feat: Add a Go build_type to the Sonatype Lifecycle lane #38 review agreement.Validation
prek run --all-files— passedzizmor --persona auditor .github/workflows/ examples/— no findingsaislop ci— 0 errors, 0 warnings (0 files in scope for this repository)bashto confirm the heredoc and warning render correctlyc8c342bf621f6e7e8622b12a19fa3539a6237f3cis the commit for v1.5.0, dereferenced from the tag objectNot run:
testing.yaml, which isworkflow_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.