From 10729365def990d1da5c586ac41f7610947c8ba2 Mon Sep 17 00:00:00 2001 From: sneak Date: Sat, 3 Oct 2026 13:38:23 +0000 Subject: [PATCH 1/2] Pin golangci-lint v2.14.0; disable exhaustruct_v5 (closes #65) v2.12.2 is built with go1.26 and refuses to lint a module whose go directive is 1.27 or later. v2.14.0 is built with go1.27. Releases from v2.13.0 deprecate exhaustruct in favour of exhaustruct_v5, which default: all switches on and which reports every partial struct literal, so the canonical config disables it beside exhaustruct for the same reason. REPO_POLICIES now names the new image digest and says that a repo moving to a new version re-vendors .golangci.yml with it. Model: opus-5-5 --- .golangci.yml | 1 + TODO.md | 5 +++++ prompts/REPO_POLICIES.md | 16 ++++++++++------ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index a7a74c2..1b73eb9 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -17,6 +17,7 @@ linters: disable: # Genuinely incompatible with project patterns - exhaustruct # Requires all struct fields + - exhaustruct_v5 # Requires all struct fields (successor to exhaustruct) - godot # Requires comments to end with periods - wrapcheck # Too verbose for internal packages - varnamelen # Short names like db, id are idiomatic Go diff --git a/TODO.md b/TODO.md index f41f0b3..ae1beae 100644 --- a/TODO.md +++ b/TODO.md @@ -21,6 +21,11 @@ fmt-check, and commit. # Completed Steps +- 2026-10-03: Moved the canonical golangci-lint to v2.14.0, built with go1.27, + because v2.12.2 refuses to lint a module whose `go` directive is 1.27 (issue + 65). Releases from v2.13.0 deprecate `exhaustruct` in favour of + `exhaustruct_v5`, which `default: all` switches on, so the canonical + `.golangci.yml` now disables `exhaustruct_v5` beside `exhaustruct`. - 2026-10-03: Brought the canonical `.gitignore` level with `.dockerignore` on secrets (issue 38): it now also ignores `prod.env`-style `*.env` files, `.envrc`, `*.p12`, `*.pfx` and the extensionless SSH private keys, written to diff --git a/prompts/REPO_POLICIES.md b/prompts/REPO_POLICIES.md index ca05cb4..4456a98 100644 --- a/prompts/REPO_POLICIES.md +++ b/prompts/REPO_POLICIES.md @@ -1,6 +1,6 @@ --- title: Repository Policies -last_modified: 2026-10-02 +last_modified: 2026-10-03 --- This document covers repository structure, tooling, and workflow standards. Code @@ -451,12 +451,16 @@ style conventions are in separate documents: `test-support` depguard rule, where a repo names its own test-support packages by full import path. A repo adds entries there and changes nothing else, and a re-vendor carries its entries forward. The canonical golangci-lint version is - v2.12.2 (released 2026-05-06), pinned as the digest of the lint phase's base + v2.14.0 (released 2026-09-24), pinned as the digest of the lint phase's base image - (`golangci/golangci-lint@sha256:5cceeef04e53efe1470638d4b4b4f5ceefd574955ab3941b2d9a68a8c9ad5240`, - which reports `2.12.2 built with go1.26.2 from c0d3ddc9`). That digest is the - only pin, since no repo installs golangci-lint on the host: bumping the - version means changing it and nothing else. + (`golangci/golangci-lint@sha256:ad862ba6b3798cbe0fd9fd7408d498fd74fbd2623a92406b2fd3898faf0bf98f`, + which reports `2.14.0 built with go1.27.0 from 114493f9`). A golangci-lint + built with go1.26 refuses to lint a module whose `go` directive is 1.27 or + later, so a new Go version needs a golangci-lint built with it. That digest is + the only pin, since no repo installs golangci-lint on the host. A repo moving + to a new version changes that digest and re-vendors `.golangci.yml` in the + same commit, because a new release can add linters that `default: all` + switches on until the canonical copy disables them. - **`script/bootstrap` installs a pinned tool by comparing versions, never by testing presence.** An `if ! command -v ; then install; fi` guard tests -- 2.54.0 From bab59b474a96c0a23efb16fcec51192c27fd9349 Mon Sep 17 00:00:00 2001 From: sneak Date: Sat, 3 Oct 2026 14:59:30 +0000 Subject: [PATCH 2/2] Set the lint digest and .golangci.yml together; state the Go version rule The canonical .golangci.yml now names exhaustruct_v5, which v2.12.2 rejects, so a repo that re-vendors the file on the old digest gets a lint phase that fails before checking any code. REPO_POLICIES now says a repo sets the lint phase digest and re-vendors .golangci.yml in one commit, whichever prompted the change, and both repo checklists point to that rule. It also replaces "a new Go version needs a golangci-lint built with it" with the rule golangci-lint applies: the go directive must not name a newer Go minor version than the one it was built with. Model: opus-5-5 --- TODO.md | 4 +++- prompts/EXISTING_REPO_CHECKLIST.md | 6 ++++-- prompts/NEW_REPO_CHECKLIST.md | 6 ++++-- prompts/REPO_POLICIES.md | 16 +++++++++------- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/TODO.md b/TODO.md index ae1beae..1d3ac0e 100644 --- a/TODO.md +++ b/TODO.md @@ -25,7 +25,9 @@ fmt-check, and commit. because v2.12.2 refuses to lint a module whose `go` directive is 1.27 (issue 65). Releases from v2.13.0 deprecate `exhaustruct` in favour of `exhaustruct_v5`, which `default: all` switches on, so the canonical - `.golangci.yml` now disables `exhaustruct_v5` beside `exhaustruct`. + `.golangci.yml` now disables `exhaustruct_v5` beside `exhaustruct`. v2.12.2 + rejects that file, so `REPO_POLICIES.md` and both repo checklists now say a + repo sets the lint phase digest and re-vendors `.golangci.yml` in one commit. - 2026-10-03: Brought the canonical `.gitignore` level with `.dockerignore` on secrets (issue 38): it now also ignores `prod.env`-style `*.env` files, `.envrc`, `*.p12`, `*.pfx` and the extensionless SSH private keys, written to diff --git a/prompts/EXISTING_REPO_CHECKLIST.md b/prompts/EXISTING_REPO_CHECKLIST.md index 369b534..129ccec 100644 --- a/prompts/EXISTING_REPO_CHECKLIST.md +++ b/prompts/EXISTING_REPO_CHECKLIST.md @@ -1,6 +1,6 @@ --- title: Existing Repo Checklist -last_modified: 2026-10-02 +last_modified: 2026-10-03 --- Use this checklist when beginning work in a repo that may not yet conform to our @@ -80,7 +80,9 @@ with your task. `https://git.eeqj.de/sneak/prompts/raw/branch/main/.gitea/workflows/check.yml` - [ ] Language-specific config: - [ ] Go: `go.mod`, `go.sum`, `.golangci.yml` (fetch from - `https://git.eeqj.de/sneak/prompts/raw/branch/main/.golangci.yml`) + `https://git.eeqj.de/sneak/prompts/raw/branch/main/.golangci.yml` and, + in the same commit, set the lint phase digest to the one named in the + `.golangci.yml` paragraph of `REPO_POLICIES.md`) - [ ] JS: `package.json`, `yarn.lock`, `.prettierrc`, `.prettierignore` (fetch from `https://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierrc` and diff --git a/prompts/NEW_REPO_CHECKLIST.md b/prompts/NEW_REPO_CHECKLIST.md index b4d8e5f..d28a79e 100644 --- a/prompts/NEW_REPO_CHECKLIST.md +++ b/prompts/NEW_REPO_CHECKLIST.md @@ -1,6 +1,6 @@ --- title: New Repo Checklist -last_modified: 2026-10-02 +last_modified: 2026-10-03 --- Use this checklist when creating a new repository from scratch. Follow the steps @@ -94,7 +94,9 @@ Template files can be fetched from: `https://git.eeqj.de/sneak/prompts/raw/branch/main/.gitea/workflows/check.yml` - [ ] Language-specific: - [ ] Go: `go mod init sneak.berlin/go/`, `.golangci.yml` (fetch from - `https://git.eeqj.de/sneak/prompts/raw/branch/main/.golangci.yml`) + `https://git.eeqj.de/sneak/prompts/raw/branch/main/.golangci.yml` and, + in the same commit, set the lint phase digest to the one named in the + `.golangci.yml` paragraph of `REPO_POLICIES.md`) - [ ] JS: `yarn init`, `yarn add --dev prettier` - [ ] Python: `pyproject.toml` diff --git a/prompts/REPO_POLICIES.md b/prompts/REPO_POLICIES.md index 4456a98..2d12b70 100644 --- a/prompts/REPO_POLICIES.md +++ b/prompts/REPO_POLICIES.md @@ -454,13 +454,15 @@ style conventions are in separate documents: v2.14.0 (released 2026-09-24), pinned as the digest of the lint phase's base image (`golangci/golangci-lint@sha256:ad862ba6b3798cbe0fd9fd7408d498fd74fbd2623a92406b2fd3898faf0bf98f`, - which reports `2.14.0 built with go1.27.0 from 114493f9`). A golangci-lint - built with go1.26 refuses to lint a module whose `go` directive is 1.27 or - later, so a new Go version needs a golangci-lint built with it. That digest is - the only pin, since no repo installs golangci-lint on the host. A repo moving - to a new version changes that digest and re-vendors `.golangci.yml` in the - same commit, because a new release can add linters that `default: all` - switches on until the canonical copy disables them. + which reports `2.14.0 built with go1.27.0 from 114493f9`). A module's `go` + directive must not name a newer Go minor version than the one golangci-lint + was built with, or golangci-lint refuses to lint it: this release lints + `go 1.27.1` but not `go 1.28`. That digest is the only pin, since no repo + installs golangci-lint on the host. A repo sets the lint phase digest to the + one named here and re-vendors `.golangci.yml` in the same commit, whichever of + the two prompted the change: the canonical copy can name linters that an older + golangci-lint rejects, and a newer golangci-lint can add linters that + `default: all` switches on until the canonical copy disables them. - **`script/bootstrap` installs a pinned tool by comparing versions, never by testing presence.** An `if ! command -v ; then install; fi` guard tests -- 2.54.0