Skip to content

chore(infra): pin golangci-lint for local dev so make lint matches CI #533

Description

@peteski22

Problem

make lint fails locally at the first Go target for anyone whose golangci-lint is older than the one CI uses:

$ make lint
...
Error: can't load config: the Go language version (go1.25) used to build golangci-lint is lower than the targeted Go version (1.26.1)
make[1]: *** [Makefile:42: lint] Error 3
make: *** [Makefile:211: lint-cli] Error 2

golangci-lint refuses to load .golangci.yml when the Go version it was built with is older than the go directive of the module it is linting. Our modules target go 1.26.1, so a golangci-lint built with go1.25.x is rejected outright.

Reproduced with golangci-lint 2.8.0 (built with go1.25.5, installed via go install), local Go 1.27.1, on unmodified main. It hits lint-cli and lint-schema-go identically. Because lint runs lint-cli first and make aborts there, the whole Python/TS half of the target never runs either — so one stale Go tool blocks linting for the entire repo, including contributors touching no Go at all.

Root cause

The version is pinned for CI but not for local development:

Where golangci-lint version Pinned?
.github/workflows/ci-cli.yaml v2.10.1 yes
.github/workflows/ci-schema.yaml v2.10.1 yes
.github/workflows/ci-sdk-go.yaml v2.10.1 yes
.github/workflows/ci-sdk-go-postgres.yaml v2.10.1 yes
Makefile / cli/Makefile / schema/Makefile / sdk/go/Makefile / sdk/go/stores/postgres/Makefile whatever is on PATH no

The Makefiles all call bare golangci-lint run --fix -v, and DEVELOPMENT.md lists Python, uv, pnpm, Docker and Go under Prerequisites but never mentions golangci-lint. So there is nothing telling a contributor which version they need, and nothing that fails with a useful message when they have the wrong one — CI stays green while local lint is broken.

This is not a Go version problem: all five modules are coherent (cli, schema, sdk/go, sdk/go/stores/postgres on go 1.26.1; build/brew on go 1.26), CI derives its Go from go-version-file, and any Go >= 1.26.1 satisfies them. Only the linter is adrift.

Suggested fix

  1. Make local lint use the same version as CI, rather than whatever is installed — either run it through go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION), or add an install/check target that errors with the required version when the binary on PATH is too old.
  2. Give the version a single source of truth. v2.10.1 is currently duplicated across four workflow files plus (after 1) the Makefiles, so the next bump has five places to miss.
  3. Add golangci-lint to the DEVELOPMENT.md prerequisites with its minimum version.

Worth considering alongside: lint aborting on the first Go failure hides unrelated results. Letting the sub-targets all run (or splitting Go from non-Go) would mean a stale Go tool no longer blocks Python and TypeScript linting.

Minor, related

build/brew/go.mod is on go 1.26 while the other four modules are on go 1.26.1. Harmless today, but worth aligning while touching this.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    infraDocker, CI, Makefile

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions