Bump golangci-lint to v2.13.2 so it can read Go 1.27 export data #17

Merged
geusebio merged 1 commit from fix/golangci-lint-reads-go-1-27 into main 2026-09-02 10:20:52 +00:00
Owner

Why

Renovate's Go 1.27 bump in the agent repo (run 178, PR #34) turned the Lint step red without reporting a single finding:

internal/forward/forward.go:6:8: could not import strings (… could not import internal/goarch
(-: could not load export data: internal error in importing "internal/goarch"
(cannot decode "internal/goarch", export data version 4 is greater than maximum supported
version 2))) (typecheck)

golangci-lint typechecks through whichever golang.org/x/tools it was built against, and the pinned v2.6.1 carries v0.38.0 — too old to decode the export data Go 1.27's compiler emits. The linter could not import the standard library, so it linted nothing and exited 1. Nothing was wrong with the code.

v2.13.2 (x/tools v0.49.0) reads it. Measured on Go 1.27.1:

golangci-lint x/tools Result
v2.6.1 (old pin) v0.38.0 typecheck failure on every package
v2.12.2 v0.44.0 typechecks
v2.13.2 (new pin) v0.49.0 typechecks

So the pin has a floor as well as the ceiling it was introduced for: a Go bump needs the linter bumped alongside it, or the gate stops running rather than going red. hack/lint.sh now says so where the pin lives.

.github/workflows/ci.yaml also grew a note that its go install version must equal hack/lint.sh's VERSION — on a mismatch the script ignores the installed binary and falls back to the container, whose -v "$PWD":/app in a job step mounts an empty directory, i.e. a green Lint step that read no code.

Carried across all four Go repos

The pin and .golangci.yaml are duplicated on purpose and are meant to stay identical, so this lands as the same change in each: someones.computer_agent, someones.computer_scclient, someones.computer_tray, someones.computer_terraform. Both file headers still said "three repos" and did not mention the terraform provider; they name four now.

The tail: gosec got stricter too

The newer ruleset flags four sites here, all of them false, each now carrying a #nosec naming the rule and why:

  • internal/tray/tray.goG204 on openBrowser; one directive on the switch covering open/rundll32/xdg-open. The binary is a literal, the URL is one argv element, and there is no shell to re-split it.
  • internal/tray/notify.goG204 on notify-send. Same shape; the osascript branch beside it already had one.
  • cmd/menudump/main.goG602 (slice index out of range) on args[0], args[1], which the len(args) == 2 case expression directly above guards. gosec reads the index without the branch that reached it.

Older gosec flagged only a variable command name for G204; the ruleset shipping from v2.12 flags variable arguments too, which is what turned these into findings. Keeping the rule enabled and annotating the legitimate sites, rather than excluding G204 wholesale, keeps it live for a future exec call that is genuinely unsafe.

Verified

  • ./hack/lint.sh0 issues on Go 1.27.1 and on Go 1.26.7 (what main builds today), so the branch is green before and after a Go bump lands here.
  • go vet ./... clean, go test ./... passes, on Go 1.27.1.
  • shellcheck -x -S warning hack/lint.sh clean. actionlint clean apart from the pre-existing actions/upload-artifact@v3 "too old" warning, which is a deliberate pin for this Forgejo and untouched here.
  • No non-comment code moved, so coverage floors are untouched.
  • Not a visual change — the tray menu's behaviour and layout are unchanged (comments only), so no screenshots.

Follow-up, deliberately out of scope

The platform repo's submodule pins move once these four merge, not before — make lint-submodule-pins requires a pin on the default branch.

## Why Renovate's Go 1.27 bump in the agent repo ([run 178](https://git.grey.ooo/Grey.ooo/someones.computer_agent/actions/runs/178), PR [#34](https://git.grey.ooo/Grey.ooo/someones.computer_agent/pulls/34)) turned the `Lint` step red without reporting a single finding: ``` internal/forward/forward.go:6:8: could not import strings (… could not import internal/goarch (-: could not load export data: internal error in importing "internal/goarch" (cannot decode "internal/goarch", export data version 4 is greater than maximum supported version 2))) (typecheck) ``` golangci-lint typechecks through whichever `golang.org/x/tools` it was built against, and the pinned **v2.6.1** carries **v0.38.0** — too old to decode the export data Go 1.27's compiler emits. The linter could not import the standard library, so it linted nothing and exited 1. Nothing was wrong with the code. `v2.13.2` (x/tools v0.49.0) reads it. Measured on Go 1.27.1: | golangci-lint | x/tools | Result | |---|---|---| | v2.6.1 (old pin) | v0.38.0 | typecheck failure on every package | | v2.12.2 | v0.44.0 | typechecks | | v2.13.2 (new pin) | v0.49.0 | typechecks | So the pin has a **floor** as well as the ceiling it was introduced for: a Go bump needs the linter bumped alongside it, or the gate stops running rather than going red. `hack/lint.sh` now says so where the pin lives. `.github/workflows/ci.yaml` also grew a note that its `go install` version must equal `hack/lint.sh`'s `VERSION` — on a mismatch the script ignores the installed binary and falls back to the container, whose `-v "$PWD":/app` in a job step mounts an empty directory, i.e. a green `Lint` step that read no code. ## Carried across all four Go repos The pin and `.golangci.yaml` are duplicated on purpose and are meant to stay identical, so this lands as the same change in each: `someones.computer_agent`, `someones.computer_scclient`, `someones.computer_tray`, `someones.computer_terraform`. Both file headers still said "three repos" and did not mention the terraform provider; they name four now. ## The tail: gosec got stricter too The newer ruleset flags four sites here, all of them false, each now carrying a `#nosec` naming the rule and why: - `internal/tray/tray.go` — `G204` on `openBrowser`; one directive on the `switch` covering `open`/`rundll32`/`xdg-open`. The binary is a literal, the URL is one argv element, and there is no shell to re-split it. - `internal/tray/notify.go` — `G204` on `notify-send`. Same shape; the `osascript` branch beside it already had one. - `cmd/menudump/main.go` — `G602` (slice index out of range) on `args[0], args[1]`, which the `len(args) == 2` case expression directly above guards. gosec reads the index without the branch that reached it. Older gosec flagged only a variable command name for `G204`; the ruleset shipping from v2.12 flags variable arguments too, which is what turned these into findings. Keeping the rule enabled and annotating the legitimate sites, rather than excluding `G204` wholesale, keeps it live for a future `exec` call that is genuinely unsafe. ## Verified - `./hack/lint.sh` → **0 issues** on **Go 1.27.1** and on **Go 1.26.7** (what `main` builds today), so the branch is green before and after a Go bump lands here. - `go vet ./...` clean, `go test ./...` passes, on Go 1.27.1. - `shellcheck -x -S warning hack/lint.sh` clean. `actionlint` clean apart from the pre-existing `actions/upload-artifact@v3` "too old" warning, which is a deliberate pin for this Forgejo and untouched here. - No non-comment code moved, so coverage floors are untouched. - Not a visual change — the tray menu's behaviour and layout are unchanged (comments only), so no screenshots. ## Follow-up, deliberately out of scope The platform repo's submodule pins move once these four merge, not before — `make lint-submodule-pins` requires a pin on the default branch.
Bump golangci-lint to v2.13.2 so it can read Go 1.27 export data
All checks were successful
CI / build (pull_request) Successful in 3m4s
CI / captures (pull_request) Successful in 11m30s
157d12ecf1
golangci-lint typechecks through whichever golang.org/x/tools it was built
against, and v2.6.1 carries v0.38.0 — old enough that it cannot decode the
export data Go 1.27's compiler emits. On the Go 1.27 bump the Lint step did
not report a finding, it failed to import the standard library:

  could not import strings (… could not import internal/goarch (-: could not
  load export data: internal error in importing "internal/goarch" (cannot
  decode "internal/goarch", export data version 4 is greater than maximum
  supported version 2))) (typecheck)

v2.13.2 (x/tools v0.49.0) reads it. The pin therefore has a floor as well as
a ceiling, which hack/lint.sh now says: a Go bump needs the linter bumped
alongside it, or the gate stops running rather than going red.

The newer gosec that comes with it flags four sites here, all false: G204 on
the browser opener and on notify-send, where the binary is a literal and the
variable is one argv element with no shell to re-split it, and G602 on
menudump's args[0]/args[1], which the `len(args) == 2` case expression
guards — gosec reads the index without the branch that reached it. Each now
carries a #nosec naming the rule and why.

Verified against both toolchains: hack/lint.sh reports 0 issues on Go 1.27.1
and on Go 1.26.7. go vet and go test are unchanged; no non-comment code
moved.
geusebio changed title from WIP: Bump golangci-lint to v2.13.2 so it can read Go 1.27 export data to Bump golangci-lint to v2.13.2 so it can read Go 1.27 export data 2026-09-02 10:10:23 +00:00
Sign in to join this conversation.
No reviewers
No labels
in-progress
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Grey.ooo/someones.computer_tray!17
No description provided.