Skip to content

fix(ci): build with the latest stable Go instead of go.mod's floor - #9

Merged
bcollard merged 1 commit into
mainfrom
fix/ci-toolchain-stable
Sep 1, 2026
Merged

bcollard merged 1 commit into
mainfrom
fix/ci-toolchain-stable

Conversation

@bcollard

@bcollard bcollard commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Problem

The weekly govulncheck run and the CI check on #8 both fail with the same root cause — and it is not the dependencies.

go.mod pinned an exact patch version, go 1.25.12, and all three workflows resolved their toolchain with go-version-file: go.mod. So every build used precisely the one Go release the reported vulnerabilities were filed against. All 7 findings are stdlib-only:

Vulnerability Package Fixed in
GO-2026-6218 net/url go1.25.13
GO-2026-6091 html/template go1.25.13
GO-2026-6090 crypto/tls go1.25.13
GO-2026-6089 net/http go1.25.13
GO-2026-6088 encoding/xml go1.25.13
GO-2026-5972 encoding/asn1 go1.25.13
GO-2026-5026 net/http go1.25.13

Nothing in klimax's own code or its dependencies is implicated.

Why not just bump the pin again

That is what the last two fixes did — dadd559 → 1.25.11, 5bc75ca → 1.25.12 — and it is a treadmill. New stdlib CVEs land every few weeks, so the pin goes red again almost as soon as it is moved. Measured across toolchains:

Toolchain govulncheck result
go1.25.12 (what CI used) 7 stdlib vulns
go1.26.4 10 stdlib vulns
go1.26.7 0
go1.27.0 0

Fix

Decouple the build toolchain from the language floor:

  • go.mod declares the minimum supported Go (go 1.25) — which is what the directive is actually for.
  • ci.yml, security.yml and release.yml resolve go-version: 'stable', so builds pick up stdlib patch releases automatically.

release.yml is the one that mattered

It carried the same pin, which means published release binaries shipped a stdlib with known CVEs. The red CI badge was only the visible symptom; this was the actual user-facing exposure.

Verification

Locally on go1.27.0 (CGO_ENABLED=1):

  • go build ./... — passes
  • go vet ./... — clean
  • go test ./... — all packages pass
  • govulncheck ./... — 0 vulnerabilities (vs. 7 on go1.25.12)
  • go mod tidy — leaves go 1.25 intact, no go.sum churn

Also

Corrects the README prerequisite, which still claimed Go 1.22+ — untrue since the 1.25.x pin landed.

Follow-up

Once this merges, #8 needs only a CI re-run to go green; its failure is this same stdlib issue, not the logrus/x/crypto bump.

🤖 Generated with Claude Code

https://claude.ai/code/session_01298bsrxR44xPnT3qM9fu2D

All 7 govulncheck findings on main (and 10 on newer toolchains) were
stdlib-only. Both CI workflows resolved their toolchain via
`go-version-file: go.mod`, and go.mod pinned an exact patch — `go 1.25.12` —
so every build used precisely the one Go release the vulnerabilities were
reported against.

That pin makes stdlib CVEs a recurring manual chore: this is the third such
bump (dadd559 -> 1.25.11, 5bc75ca -> 1.25.12). Newly-disclosed stdlib CVEs
land every few weeks, so the pin is red again almost as soon as it is moved.

Instead, decouple the build toolchain from the language floor:

  - go.mod declares the *minimum* supported Go (`go 1.25`), which is what the
    directive is for.
  - CI, Security and Release resolve `go-version: 'stable'`, so builds pick up
    stdlib patch releases automatically.

Release is the one that actually mattered: it used the same pin, so published
binaries shipped a stdlib with known CVEs. The red CI badge was only the
symptom.

Verified locally on go1.27.0: build, vet and test pass, and govulncheck
reports 0 vulnerabilities (vs. 7 on go1.25.12).

Also corrects the README prerequisite, which still claimed Go 1.22+.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01298bsrxR44xPnT3qM9fu2D
Signed-off-by: Baptiste Collard <9626829+bcollard@users.noreply.github.com>
@bcollard
bcollard merged commit 69513e1 into main Sep 1, 2026
1 check passed
bcollard added a commit that referenced this pull request Sep 1, 2026
PR #9 set the go.mod directive to `go 1.25` and updated the README to match,
but `go mod tidy` normalises it to `go 1.25.7` — github.com/lima-vm/lima/v2
declares `go 1.25.7`, so the module graph raises klimax's floor to satisfy it.
The committed directive has been 1.25.7 since #9; only the README claim was
wrong, and it understated the floor: go1.25.0 through go1.25.6 cannot build
the module.

This does not affect #9's actual fix. Decoupling the build toolchain lives in
the workflows (`go-version: 'stable'`), which is what stopped govulncheck
flagging stdlib CVEs; CI builds on go1.27.0 with 0 vulnerabilities. And unlike
the old hand-maintained `go 1.25.12` pin, 1.25.7 is derived rather than chosen
— `go mod tidy` reproduces it, and .goreleaser.yaml runs `go mod tidy` as a
before-hook, so a hand-written `go 1.25` could never have survived a release
build anyway.

Point at go.mod as the authoritative source rather than restating a number
that moves with the dependency graph.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01298bsrxR44xPnT3qM9fu2D
bcollard pushed a commit that referenced this pull request Sep 1, 2026
Bumps the go-dependencies group with 2 updates:

  - github.com/sirupsen/logrus 1.9.4 -> 1.10.0
  - golang.org/x/crypto        0.54.0 -> 0.55.0

x/crypto 0.55.0 clears the last remaining finding in an imported package:
govulncheck now reports 0 vulnerabilities in packages we import, down from 1.
It also carries ssh fixes, which internal/guest uses.

logrus 1.10.0's breaking changes do not reach klimax: the TextFormatter
rendering changes, the deprecated MutexWrap, and the generic Log/Logf panic
behaviour are all unused. The hostagent path uses only SetOutput,
SetFormatter, JSONFormatter, SetLevel and GetLevel, so the JSON log contract
Lima parses for VM readiness detection is unaffected.

Originally red on CI for an unrelated reason — the stdlib CVEs fixed in #9 —
and rebased onto that fix. Verified on go1.27.0: build, vet, test and
govulncheck (0 vulnerabilities) all pass.
bcollard added a commit that referenced this pull request Sep 6, 2026
Two newly-disclosed DoS vulnerabilities in golang.org/x/crypto/ssh, both
reachable from klimax's own code:

  GO-2026-6355  deadlocked established channel
  GO-2026-6354  deadlocked undecided channel

  internal/guest/guest.go:187      guest.Client.dial -> ssh.Dial
  internal/cli/hostagent.go:110    cli.runHostagent -> ssh.NewClientConn

Both fixed in v0.55.0 -> v0.56.0.

Unlike the stdlib CVEs that prompted #9, these are in a module we require, so
tracking the latest stable toolchain does not clear them — a dependency bump is
the only fix. This is the case the weekly security.yml scan exists to catch.

Note the floor moved: x/crypto v0.56.0 requires Go 1.26, so `go get` raised the
go directive from 1.25.7 to 1.26.0. README updated to match. That is a real
increase in the minimum Go needed to build from source; the pre-built binaries
are unaffected.

Verified on go1.27.1 in CI: build, vet and test pass, and govulncheck reports 0
vulnerabilities (from 2).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01298bsrxR44xPnT3qM9fu2D
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