Skip to content

Upgrade go directive to 1.26 - #787

Merged
emmanuelmaduwuba-lyft merged 1 commit into
mainfrom
go-1.26-upgrade
Sep 22, 2026
Merged

emmanuelmaduwuba-lyft merged 1 commit into
mainfrom
go-1.26-upgrade

Conversation

@emmanuelmaduwuba-lyft

@emmanuelmaduwuba-lyft emmanuelmaduwuba-lyft commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Bumps the go directive in go.mod from 1.25 to 1.26 (bare, matching this repo's own precedent — #775's Go 1.24 bump used go 1.24, not 1.24.0).
  • Part of the fleet-wide Go 1.26 upgrade campaign, tracked in DS-11161.
  • Bumps golangci-lint-action's pinned version (v2.4.0 → v2.13.0) and actions/setup-go's go-version (1.25 → 1.26) in lint.yml/test.yml — the old golangci-lint release was built with go1.25 and refused to run against a go1.26-targeted module.

Why this needed more than a version bump: the golangci-lint jump (v2.4.0→v2.13.0) crosses the exact release range where gosec shipped a brand-new taint-analysis engine (securego/gosec v2.22.1→v2.28.0, engine added in v2.23.0). That engine surfaced 13 real findings that the old linter simply couldn't see — this wasn't avoidable by picking a different golangci-lint version: v2.10.0 (the first release after Go 1.26 itself existed, so the first one plausibly able to lint go1.26 code) is the same release where the taint engine landed. Resolved each finding individually:

  • 3× G118 (goroutines using context.Background()) — false positive; each already has an inline comment explaining this is deliberate (parent doesn't wait for the goroutine). Added nolint referencing it.
  • 1× G118 (server.go, cancel func) — false positive; cancel is stored as CancelWorker below, not dropped.
  • 1× G602 (cmd/server.go slice index) — false positive; guarded by len(deprecatedFlags) == 1 in the same branch.
  • 2× G703 (path traversal, git_cred_writer.go) — false positive; filename is always a trusted home-dir + hardcoded literal, matching this file's own existing nolint precedent on the paired os.ReadFile calls.
  • 4× G705 (XSS, respond/logAndWriteBody helpers across 4 controllers) — real hardening applied: explicitly set Content-Type: text/plain before writing (the standard mitigation for content-sniffing-based XSS), then nolint since gosec's static taint check can't see that header-based mitigation.
  • G101 (hardcoded creds, test fixtures) — added a path-based exclusion rule to .golangci.yml for _test.go files and fixtures.go, matching the identical rule already in upstream runatlantis/atlantis's .golangci.yml for the same false-positive class.

Test plan

  • go mod tidy — clean
  • go build ./... — clean
  • go vet ./... — clean
  • go test -run '^$' ./... — compiles all test binaries clean
  • golangci-lint run --max-same-issues 0 (v2.13.0, matching CI) — 0 issues

@emmanuelmaduwuba-lyft emmanuelmaduwuba-lyft changed the title Upgrade go directive to 1.26.7 Upgrade go directive to 1.26 Sep 21, 2026
DS-11161: Production Infrastructure Go 1.26 fleet upgrade.

- go.mod go directive: 1.25 -> 1.26 (bare, matching this repo's own
  precedent -- #775's Go 1.24 bump used `go 1.24`, not `1.24.0`).
- .github/workflows/{lint,test}.yml: actions/setup-go go-version
  1.25 -> 1.26; golangci-lint-action pinned version v2.4.0 -> v2.13.0
  (the old release was built with go1.25 and refused to lint a
  go1.26-targeted module).

That golangci-lint jump crosses the exact release range where gosec
shipped a brand-new taint-analysis engine (v2.22.1 -> v2.28.0, engine
added in v2.23.0) -- unavoidable, since v2.10.0 is both the first
golangci-lint release after Go 1.26 itself existed and the release
where the engine landed. It surfaced 13 real findings the old linter
couldn't see. Resolved each:

- 3x G118 (goroutines using context.Background(), comment.go/
  pull_request.go/pull_request_review.go): false positive, each
  already has an inline comment explaining this is deliberate (parent
  doesn't wait for the goroutine). nolint referencing it.
- 1x G118 (server.go cancel func): false positive, cancel is stored
  as CancelWorker, not dropped.
- 1x G602 (cmd/server.go slice index): false positive, guarded by
  len(deprecatedFlags) == 1 in the same branch.
- 2x G703 (path traversal, git_cred_writer.go): false positive,
  filename is always a trusted home-dir + hardcoded literal -- matches
  this file's own existing nolint precedent on the paired
  os.ReadFile calls.
- 4x G705 (XSS, respond/logAndWriteBody helpers across 4 controllers):
  real fix applied -- explicitly set Content-Type: text/plain before
  writing (the standard mitigation for content-sniffing-based XSS),
  then nolint since gosec's static taint check can't see that
  header-based mitigation.
- G101 (hardcoded creds, test fixtures): added a path-based exclusion
  rule to .golangci.yml for _test.go files and fixtures.go, matching
  the identical rule already in upstream runatlantis/atlantis's
  .golangci.yml for the same false-positive class.

Verified: go mod tidy, go build ./..., go vet ./...,
go test -run '^$' ./... (compile-only), and golangci-lint v2.13.0
(matching CI, --max-same-issues 0) all clean.
@emmanuelmaduwuba-lyft
emmanuelmaduwuba-lyft merged commit 644a2ca into main Sep 22, 2026
3 checks passed
@emmanuelmaduwuba-lyft
emmanuelmaduwuba-lyft deleted the go-1.26-upgrade branch September 22, 2026 14:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants