From d15985157687bd0686a828d955051e0a2aa0a337 Mon Sep 17 00:00:00 2001 From: John Kerl Date: Tue, 7 Jul 2026 14:57:40 -0400 Subject: [PATCH] Note that CI lint cache can go stale independent of local make lint Discovered while debugging a lint-CI failure on #2166: golangci-lint-action's persistent cross-commit cache can serve stale staticcheck (SA5011) results unrelated to a given diff, even when a fresh local run is clean. The job is continue-on-error so it doesn't block merges, but it's worth documenting so contributors don't chase a phantom local repro. Co-Authored-By: Claude Sonnet 5 --- CLAUDE.md | 15 ++++++++++++--- README-dev.md | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 7915c83b7..33edfd736 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -70,9 +70,18 @@ make lint # Run golangci-lint, same invocation as CI (see Initial Setu ``` `make lint` runs `golangci-lint run ./cmd/mlr ./pkg/...`, matching -`.github/workflows/golangci-lint.yml` exactly, so a clean local run means CI's -lint job will pass too. It is not part of `make check` or `make dev`, so run -it explicitly before pushing. +`.github/workflows/golangci-lint.yml` exactly, so a clean local run usually +means CI's lint job will pass too. It is not part of `make check` or +`make dev`, so run it explicitly before pushing. + +**Note:** CI's lint job restores a persistent `golangci-lint` results cache +shared across commits and PRs (via `golangci-lint-action`), which can +occasionally serve stale `staticcheck` results (e.g. spurious `SA5011` +nil-check warnings) unrelated to your diff. The job is `continue-on-error: +true` for this reason, so it won't block merging. If CI lint fails but +`make lint` is clean locally, it's likely a stale cache — rerun the job, or a +maintainer can clear it: `gh cache list --key golangci-lint` then +`gh cache delete `. ### Full Developer Workflow ```bash diff --git a/README-dev.md b/README-dev.md index 6c5e3c663..b5aad4b32 100644 --- a/README-dev.md +++ b/README-dev.md @@ -1,7 +1,7 @@ # Quickstart for developers * `make`, `make check`, `make docs`, etc: see [Makefile](Makefile) in the repo base directory. -* Linting: `make lint` runs [golangci-lint](https://golangci-lint.run/) (config in [.golangci.yml](.golangci.yml)) with the same invocation used by [.github/workflows/golangci-lint.yml](.github/workflows/golangci-lint.yml), so a clean local run means CI's lint job will pass too. Install golangci-lint locally per the [official instructions](https://golangci-lint.run/welcome/install/#local-installation) (match the CI version, currently v2.12.2). It's a separate step from `make dev`/`make check` -- run it explicitly before pushing. `make staticcheck` (requires [staticcheck](https://staticcheck.io)) is a second, independent static-analysis pass. +* Linting: `make lint` runs [golangci-lint](https://golangci-lint.run/) (config in [.golangci.yml](.golangci.yml)) with the same invocation used by [.github/workflows/golangci-lint.yml](.github/workflows/golangci-lint.yml), so a clean local run usually means CI's lint job will pass too. Install golangci-lint locally per the [official instructions](https://golangci-lint.run/welcome/install/#local-installation) (match the CI version, currently v2.12.2). It's a separate step from `make dev`/`make check` -- run it explicitly before pushing. `make staticcheck` (requires [staticcheck](https://staticcheck.io)) is a second, independent static-analysis pass. Note: CI's lint job caches `staticcheck` results across commits/PRs and can occasionally fail on a stale cache (spurious warnings unrelated to your diff) even when `make lint` is clean locally; the job is `continue-on-error: true` so this won't block merging, and a maintainer can clear the cache with `gh cache delete` if needed. * Software-testing methodology: see [./test/README.md](./test/README.md). * Source-code indexing: please see [https://sourcegraph.com/github.com/johnkerl/miller](https://sourcegraph.com/github.com/johnkerl/miller) * Godoc As of September 2021, `godoc` support is minimal: package-level synopses exist; most `func`/`const`/etc content lacks `godoc`-style comments. To view doc material, you can: