Bumping Go
This document describes how to bump the Go version across the project. It is
primarily intended to be consumed by an AI coding agent (e.g. via
/bump-go 1.26), but the steps can also be followed manually.
Convention
godirective ingo.mod: useX.Y.0(the minor version with patch0)GO_VERSIONin Makefile: useX.Y.Zwhere Z is the latest available patch (e.g.1.26.4)
Step 1: Research
Perform these lookups before making any changes.
1a. Latest patch version
Find the latest Go X.Y.x patch release at https://go.dev/doc/devel/release.
Determine the full version string (e.g. 1.26.4). Call this FULL_VERSION.
1b. Upstream cluster-api references
Look up what kubernetes-sigs/cluster-api uses at the latest release tag on the
main CAPI minor version this project depends on (check go.mod for
sigs.k8s.io/cluster-api to find the CAPI minor, then find the latest tag for
that minor):
# GCB image digest + tag comment
curl -sL https://raw.githubusercontent.com/kubernetes-sigs/cluster-api/<TAG>/cloudbuild.yaml
# golangci-lint version
curl -sL https://raw.githubusercontent.com/kubernetes-sigs/cluster-api/<TAG>/.github/workflows/pr-golangci-lint.yaml \
| grep 'version:'
Call these GCB_DIGEST, GCB_TAG_COMMENT, and CAPI_GOLANGCI_VER.
1c. golangci-lint compatibility
The golangci-lint version must be built with the target Go version or newer. Versions built with an older Go will refuse to lint. Test candidate versions:
go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@<VERSION> version
Look for built with goX.Y in the output. Pick the latest stable version that
reports the target Go minor or newer. Call this GOLANGCI_VERSION (e.g.
v2.12.2).
Step 2: Update files
go.mod (root) and hack/tools/go.mod
Update the go directive:
go X.Y.0
Makefile
GO_VERSION ?= FULL_VERSION
GO_DIRECTIVE_VERSION ?= X.Y.0
.golangci-kal.yml
Update the go: field under run::
run:
go: "X.Y"
hack/tools/Makefile
Update GOLANGCI_LINT_VERSION and the comment:
# Use a golangci-lint built with Go >= X.Y to match repo go.mod
GOLANGCI_LINT_VERSION := GOLANGCI_VERSION
hack/tools/.custom-gcl.yaml
Update the version: field used to build the custom KAL linter:
version: GOLANGCI_VERSION
.github/workflows/pr-golangci-lint.yaml
Update the golangci-lint version::
version: GOLANGCI_VERSION
(The go-version in this workflow is already derived dynamically via
make go-version, so it does not need a manual update.)
.github/workflows/dependabot.yml
Update the go-version: field:
go-version: 'X.Y'
.github/workflows/release.yaml
Update the go-version: field:
go-version: 'X.Y'
netlify.toml
GO_VERSION = "FULL_VERSION"
cloudbuild.yaml and cloudbuild-nightly.yaml
Only update if the upstream CAPI release tag uses a different GCB image digest than what this repo already has. If they match, skip this file.
- name: 'gcr.io/k8s-staging-test-infra/gcb-docker-gcloud@sha256:GCB_DIGEST' # GCB_TAG_COMMENT
Step 3: go mod tidy
Run in both module directories:
go mod tidy
cd hack/tools && go mod tidy
Step 4: Lint and test
make lint
make lint-api
make test
If make lint or make lint-api fails:
- If the failure is
the Go language version used to build golangci-lint is lower than the targeted Go version, the chosenGOLANGCI_VERSIONis wrong. Go back to Step 1c. Formake lint-api, also checkhack/tools/.custom-gcl.yaml. - If the failure shows new lint findings, fix them. These are pre-existing issues surfaced by the newer linter version, not caused by the Go bump itself.
- If a new linter version produces noisy false positives (e.g.
preallocon idiomaticvar allErrs field.ErrorListpatterns), add targeted exclusion rules in.golangci.ymlrather than suppressing the linter entirely.
Step 5: Verify build
go build ./...
Step 6: Commit
Create three separate commits in this order:
- Lint fixes (if any):
fix(lint): resolve <linter-names> lint issues- Only the source files with lint fixes
- Linter bump (if version changed):
chore(bump): bump golangci-lint from <old> to <new>hack/tools/Makefile,hack/tools/.custom-gcl.yaml,.github/workflows/pr-golangci-lint.yaml, and.golangci.ymlif exclusion rules were added
- Go version bump:
chore(bump): bump Go to FULL_VERSION- All remaining files:
go.mod,hack/tools/go.mod,Makefile,.golangci-kal.yml,.github/workflows/dependabot.yml,.github/workflows/release.yaml,netlify.toml,cloudbuild.yaml,cloudbuild-nightly.yaml
- All remaining files:
If there are no lint fixes or no linter version change, skip that commit.
All commits must be signed off (git commit -s).
Do NOT push or create a PR unless the user asks. If a PR is created, use the
pull request template defined in .github/PULL_REQUEST_TEMPLATE.md.