Surfaced by the review of #10 (golang:1.24-alpine → 1.26-alpine, now merged).
Four places pin a Go version, and nothing keeps them in step:
| Where |
Value |
After #10 |
go.mod |
go 1.24 |
unchanged — and should stay |
.github/workflows/ci.yml |
GO_VERSION: 1.24 |
unchanged |
.github/workflows/coverage-badge.yml |
go-version: 1.24 (hardcoded, not the env var) |
unchanged |
Dockerfile |
golang:1.24-alpine |
now 1.26 |
So the shipped image is built by a toolchain that gofmt, go vet and go test -race never run under.
How bad is it actually
Less bad than it sounds, because of how this repo tests. The compose stack job builds through the Dockerfile and then runs six behavioural assertions against the resulting binaries, so the 1.26 output is exercised end to end rather than merely compiled. Only the static checks and the race detector run at 1.24.
go.mod should not be bumped. 14e8e09 set go 1.24 deliberately, and it is a minimum rather than a pin — with no toolchain directive, golang:1.26-alpine builds it directly. Raising the floor would push every consumer of a public teaching repo onto 1.26 for no gain.
Proposed
- Bump
GO_VERSION in ci.yml and go-version in coverage-badge.yml to 1.26, so the race detector runs under the toolchain that ships.
- Or, better: a
strategy.matrix of [1.24, 1.26] on the test job — keeps the declared floor honest and tests what ships.
- Either way, make
coverage-badge.yml reference a single source rather than hardcoding its own copy.
Adjacent
GOTOOLCHAIN=local appears in the CI environment but this repo never sets it — actions/setup-go injects it. Benign today, but it is an invisible pin someone will trip over while debugging toolchain selection, and worth a comment wherever the version is declared.
Surfaced by the review of #10 (
golang:1.24-alpine→1.26-alpine, now merged).Four places pin a Go version, and nothing keeps them in step:
go.modgo 1.24.github/workflows/ci.ymlGO_VERSION: 1.24.github/workflows/coverage-badge.ymlgo-version: 1.24(hardcoded, not the env var)Dockerfilegolang:1.24-alpineSo the shipped image is built by a toolchain that
gofmt,go vetandgo test -racenever run under.How bad is it actually
Less bad than it sounds, because of how this repo tests. The
compose stackjob builds through the Dockerfile and then runs six behavioural assertions against the resulting binaries, so the 1.26 output is exercised end to end rather than merely compiled. Only the static checks and the race detector run at 1.24.go.modshould not be bumped.14e8e09setgo 1.24deliberately, and it is a minimum rather than a pin — with notoolchaindirective,golang:1.26-alpinebuilds it directly. Raising the floor would push every consumer of a public teaching repo onto 1.26 for no gain.Proposed
GO_VERSIONinci.ymlandgo-versionincoverage-badge.ymlto1.26, so the race detector runs under the toolchain that ships.strategy.matrixof[1.24, 1.26]on thetestjob — keeps the declared floor honest and tests what ships.coverage-badge.ymlreference a single source rather than hardcoding its own copy.Adjacent
GOTOOLCHAIN=localappears in the CI environment but this repo never sets it —actions/setup-goinjects it. Benign today, but it is an invisible pin someone will trip over while debugging toolchain selection, and worth a comment wherever the version is declared.