Skip to content

build(deps): bump Go to 1.27.0 and the lint contract to golangci-lint 2.13.1 - #310

Open
kyle-sexton wants to merge 4 commits into
build/ci-workflows-v0.17.2from
build/go-1.27.0
Open

build(deps): bump Go to 1.27.0 and the lint contract to golangci-lint 2.13.1#310
kyle-sexton wants to merge 4 commits into
build/ci-workflows-v0.17.2from
build/go-1.27.0

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

No linked issue

Summary

Review-only drain of the go row of #283: Go 1.26.6 → 1.27.0, releasing the hold recorded on 2026-08-21 in release/dependency-drift-review.json.

Stacked on #309 (build/ci-workflows-v0.17.2) and based on that branch, not main. That is not a convenience — #309 is what raises the shared go-quality reusable's GOLANGCI_LINT_VERSION to 2.13.1, and a golangci-lint older than 2.13.0 refuses to lint a go1.27 module outright. Without #309 this PR's lint lane cannot pass.

Merge order for the whole cycle: #309 → this PR → #311. #309 is a hard prerequisite. #311 must come after this one because this PR replaces release/dependency-drift-review.json wholesale; if #311 merged first, that replacement would silently delete #311's merged PowerShell decision and regress it to pending (see #311's "Merge order" section).

Two mechanical notes for whoever merges: #309 squash-merges to a new SHA, so this branch will need "Update branch" afterwards — 6251263 will not be an ancestor of main. GitHub also retargets this PR's base to main at that point; the body is deliberately free of closing keywords so the retarget cannot create a closing link to #283.

This PR carries the do-not-merge label and must not be merged autonomously. docs/releases.md ("Freshness policy"): never auto-merge controller, runner, image, toolchain, Scale Set Client, Action, or release changes.

Problem

The 2026-08-21 hold recorded a specific exit condition, and that condition is now met:

golangci-lint binaries built with go1.26 do not support go1.27 (golangci-lint#6643). go1.27 support landed in golangci-lint v2.13.0, which also carries a large linter delta (errcheck 1.10→1.20, exhaustruct deprecation). A Go bump is therefore a coupled go.mod + AGENTS.md + lint-pin qualification, not a mechanical pin.

golangci-lint v2.13.0 shipped 2026-08-19 and v2.13.1 on 2026-08-20. ci-workflows v0.17.2 absorbs 2.13.1 into go-quality.yml. The blocker is gone; what remains is the qualification the hold asked for, which this PR performs rather than assumes (see Verification).

The freshness clock is closing, and 1.26.7 does not stop it

Worth flagging, because the drift table hides it. scripts/Test-DependencyFreshness.ps1 reports the Go row's "latest" as the newest stable release overall, so the table shows only 1.27.0. But go1.26.7 also exists — a patch on the currently pinned line — and the row's age is computed from the earliest unadopted tag, which is go1.26.7.

Both go1.26.7 (2026-08-19T14:43Z) and go1.27.0 (2026-08-19T16:45Z) published the same day. So:

  • The 14-day hard fail (Enforce 14-day or critical drift gate in dependency-drift.yml) trips on the 2026-09-03 scheduled run. Drift date is 2026-08-19T14:43:46Z, so the 14-day mark falls at 2026-09-02T14:43Z; the job's cron is 17 4 * * *, so the 2026-09-02 morning run still sees ageDays 13 and 2026-09-03 is the first run to see 14.
  • Taking 1.26.7 instead would buy essentially nothing — the drift date would move by two hours, and 1.27.0 would still be unadopted.

There is no cheap partial move here. Either 1.27.0 is adopted or the row hard-fails CI in roughly a week.

Fix

Moves the coupled set together:

  • go.mod: go 1.26.6go 1.27.0, plus the require-block layout go mod tidy produces under go1.27 (second commit). go1.27's tidy consolidates the two indirect blocks into one and moves the five directly-imported go.opentelemetry.io/otel* modules (otel, metric, sdk, sdk/metric, trace) into the direct-require block, where they belong — they had been sitting inside an indirect block without // indirect markers. No version moves and go.sum is byte-identical. CI's tidy check caught this on the first push; go mod tidy is now a no-op under go1.27.0.
  • .github/workflows/release.yml: both setup-go go-version pins (lines 47, 174) → 1.27.0.
  • release/dependencies.json: go.version1.27.0. (scripts/Test-ReleasePins.ps1 enforces that this equals the go.mod directive.) The resolvedAt bump to 2026-08-27T08:00:00Z arrives via build(deps): bump ci-workflows to v0.17.2 #309's branch, which this one merges in.
  • AGENTS.md: the local lint contract — GOTOOLCHAIN=go1.26.6go1.27.0, golangci-lint@v2.6.0@v2.13.1, plus an explicit "v2.13.1 or newer" floor with the upstream issue reference, and a note that the version tracks GOLANGCI_LINT_VERSION in the shared go-quality reusable so local lint matches CI.
  • release/dependency-drift-review.json: rewritten to the 2026-08-27 cycle. held is now empty; go and ci-workflows move to bumped with full rationale; the PowerShell row is listed under pending because it ships as its own PR. A third commit restates the hard-fail date in that record so the committed evidence and this body agree on 2026-09-03.

No Go source changes.

Go 1.27 breaking-change review against this codebase

Go 1.27 change Exposure here Assessment
encoding/json now backed by the v2 implementation; "rejects invalid UTF-8 in JSON strings and rejects duplicate names within a JSON object"; error message text may differ High — 20+ files import encoding/json (compatibility manifests, Docker API responses, runner job JSON, health-watch storage) The real risk of this bump. Full suite passes unchanged, including the internal/control transport fuzz corpus. No test asserts on json error-message text.
HTTP/1 Response.Body now auto-drains unread content on Close Moderate — Docker API and GitHub API clients Improves connection reuse; the documented downside applies only to programs that deliberately leave excess idle connections. No change needed.
asynctimerchan GODEBUG removed; time channels always unbuffered None grep finds no GODEBUG usage anywhere in the repo. This has been the default since Go 1.23.
crypto/tls GODEBUGs removed (tlsunsafeekm, tlsrsakex, tls3des, tls10server, x509keypairleaf); gotypesalias removed None No GODEBUG usage in the repo or its workflows.
net.UnixConn returns io.EOF directly rather than wrapped in net.OpError None Windows runtime target; no Unix-socket consumers.
Compiler generates simpler function-literal names None No test compares closure symbol names or function code pointers.
macOS 13+ required; ppc64 ELFv2 ABI None Targets are windows/amd64 and linux/amd64.
go command drops bzr support None All modules are Git-hosted.
~60 KB binary growth from size-specialized malloc Negligible Release archive size only.

Verification

Every gate below was run locally on this branch with GOTOOLCHAIN=auto resolving go1.27.0 from the new go.mod directive.

Gate Command Result
Build go build ./... pass
Vet go vet ./... pass
Tests go test ./... 15/15 packages ok, 0 failures
Windows cross-compile (go-windows-build lane) CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -trimpath ./cmd/... pass
Module verification go mod verify all modules verified
Vulnerabilities govulncheck@v1.7.0 ./... No vulnerabilities found.
Lint (the coupled qualification) golangci-lint v2.13.1 built via GOTOOLCHAIN=go1.27.0 GOFLAGS=-mod=mod go install .../golangci-lint@v2.13.1, then golangci-lint run ./... 0 issues
Release pin consistency ./scripts/Test-ReleasePins.ps1 Release and workflow pins are internally consistent.
Workflow pin metadata node --test .github/scripts/workflow-pin-metadata.test.cjs 5/5 pass
JSON validity JSON.parse on both release/*.json pass

Linter-delta baseline. The hold's specific worry was the errcheck 1.10→1.20 / exhaustruct-deprecation delta. Measured directly on this tree: golangci-lint v2.12.2 (the pre-#309 CI version) reports 0 issues, and v2.13.1 also reports 0 issues — both against go1.26.6 and, for v2.13.1, against go1.27.0. The delta surfaces no new findings on this codebase.

Not run locally: go test -race. -race requires cgo, and this workstation is CGO_ENABLED=0 Windows without a C toolchain (go: -race requires cgo). The race lane runs on Linux in the reusable go-quality workflow and must be green in CI before this merges.

Related

Fleet rollout

Required. release/dependencies.json go.version is a compatibility-pair input that flows into compatibility.json. Merging this PR does not promote anything: per docs/releases.md, publication and promotion of a new compatibility pair go through the release workflow and the provisioning rolling-upgrade runbook, which is a separate operator procedure. This lane did not touch any runner host.


This PR was prepared by an automated agent lane. It is review-only: the agent did not merge it and will not, and deliberately left issue 283 open.

… 2.13.1

Releases the 2026-08-21 Go hold. Its recorded exit condition is met:
golangci-lint v2.13.0 shipped go1.27 support (golangci/golangci-lint#6643)
on 2026-08-19, v2.13.1 followed on 2026-08-20, and ci-workflows v0.17.2
absorbs 2.13.1 into the shared go-quality reusable this repo calls.

Moves the coupled set together: go.mod's go directive, both setup-go
pins in release.yml, release/dependencies.json go.version, and the
AGENTS.md local lint contract (GOTOOLCHAIN go1.26.6 -> go1.27.0,
golangci-lint v2.6.0 -> v2.13.1, with the >= 2.13.0 floor stated).

The hold asked for a qualification rather than a mechanical pin, so it
was performed: build, vet, and the full test suite (15/15 packages) pass
under go1.27.0; the CGO_ENABLED=0 GOOS=windows cross-compile of ./cmd/...
succeeds; go mod verify and govulncheck v1.7.0 are clean; and
golangci-lint v2.13.1 built with GOTOOLCHAIN=go1.27.0 reports 0 issues,
matching the v2.12.2/go1.26.6 baseline. The feared errcheck 1.10->1.20
and exhaustruct-deprecation delta surfaces no findings here.

Go 1.27 switches encoding/json to the v2 implementation, which rejects
invalid UTF-8 and duplicate object names; that is the one behavior change
with real exposure in this module, and the existing suite (including the
internal/control transport fuzz corpus) passes unchanged.

Stacked on the ci-workflows v0.17.2 bump, which is what makes CI's lint
lane able to lint a go1.27 module at all.

Review-only per the docs/releases.md freshness policy; carries the
do-not-merge label. Promotion additionally needs a new reviewed
compatibility pair and a rolling-host rollout.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kyle-sexton kyle-sexton added dependencies Dependency updates (Dependabot / Renovate). do-not-merge Hard merge gate: do not merge while applied. labels Aug 27, 2026
kyle-sexton and others added 2 commits August 27, 2026 05:29
The go-quality lane's `go mod tidy` check failed on the previous commit:
go1.27's tidy lays the require blocks out differently from go1.26.6.

Pure reorganization, no dependency change. tidy consolidates the two
indirect blocks into one and moves the five directly-imported
go.opentelemetry.io/otel* modules (otel, metric, sdk, sdk/metric, trace)
into the direct-require block, where they belong — they had been sitting
in an indirect block without `// indirect` markers. No version moves and
go.sum is byte-identical.

`go mod tidy` is now idempotent under go1.27.0, and build, vet, tests
(15/15), the Windows cross-compile, go mod verify, govulncheck, and
golangci-lint v2.13.1 all remain clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The reviewed-decision record still said the 14-day hard-fail window
"closes on 2026-09-02" after the PR body was corrected to the 2026-09-03
scheduled run, so the committed evidence and the body disagreed on the
one number the correction was about.

Restates it with the arithmetic visible: go1.26.7 (2026-08-19T14:43:46Z)
and go1.27.0 (2026-08-19T16:45:14Z) published the same day, the freshness
check dates the row from the earliest unadopted tag, so ageDays first
reaches 14 on the 2026-09-03 run.

Raised in re-verification of #310.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Dependency updates (Dependabot / Renovate). do-not-merge Hard merge gate: do not merge while applied.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant