Skip to content

Update Go toolchain to 1.26#301

Merged
kindermax merged 2 commits intomasterfrom
codex/update-lets-to-go-126
Mar 18, 2026
Merged

Update Go toolchain to 1.26#301
kindermax merged 2 commits intomasterfrom
codex/update-lets-to-go-126

Conversation

@kindermax
Copy link
Copy Markdown
Collaborator

@kindermax kindermax commented Mar 17, 2026

Summary

  • bump Go requirement in module, workflows, Dockerfile, and golangci config to 1.26
  • refresh golangci lint version and settings plus document the dependency update in the changelog

Testing

  • Not run (not requested)

Summary by Sourcery

Update the project to Go 1.26 and refresh linting configuration to match the newer toolchain.

Enhancements:

  • Update Go version requirement in go.mod and development tooling to 1.26.
  • Refresh golangci-lint configuration and exclusions to align with the newer major lint version.

Build:

  • Bump Docker builder image to Go 1.26 and upgrade the golangci-lint Docker image to v2.11.3.

CI:

  • Update test and release GitHub workflows to use Go 1.26 and the corresponding GoReleaser cross-compilation image.

Documentation:

  • Document the Go 1.26 dependency upgrade in the changelog.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Mar 17, 2026

Reviewer's Guide

Updates the project to Go 1.26 across tooling and CI, refreshes golangci-lint to v2, and modernizes its configuration including linter selection and exclusion rules, while documenting the dependency change in the changelog.

Flow diagram for updated golangci lint configuration

flowchart TD
  RunConfig[run
  go 1_26
  tests false]
  LintersDefault[linters
  default all]
  DisabledLinters[disabled linters
  containedctx
  copyloopvar
  cyclop
  depguard
  err113
  exhaustive
  exhaustruct
  forcetypeassert
  funlen
  funcorder
  gochecknoglobals
  gocognit
  gocritic
  gocyclo
  godoclint
  godox
  gomoddirectives
  goprintffuncname
  gosec
  importas
  lll
  mnd
  musttag
  nestif
  nilnil
  noctx
  noinlineerr
  nlreturn
  prealloc
  recvcheck
  revive
  tagliatelle
  unparam
  wastedassign
  wrapcheck
  wsl]
  LinterSettings[settings
  lll line_length 120
  varnamelen min_name_length 1]
  Exclusions[exclusions
  generated lax]
  Presets[presets
  comments
  common_false_positives
  legacy
  std_error_handling]
  Rules[rules
  linter mnd excluded in _test\.go]
  Paths[paths
  third_party$
  builtin$
  examples$]

  RunConfig --> LintersDefault
  LintersDefault --> DisabledLinters
  LintersDefault --> LinterSettings
  LintersDefault --> Exclusions
  Exclusions --> Presets
  Exclusions --> Rules
  Exclusions --> Paths
Loading

File-Level Changes

Change Details Files
Bump Go toolchain requirement to 1.26 across module, Docker build image, and CI workflows.
  • Update go.mod language version from 1.24 to 1.26.
  • Change Go version used in GitHub Actions test and release workflows from 1.24.x to 1.26.x.
  • Update GoReleaser Docker env variable GOLANG_CROSS_VERSION from v1.24 to v1.26.
  • Switch builder base image in Dockerfile from golang:1.24-bookworm to golang:1.26-bookworm.
go.mod
.github/workflows/test.yaml
.github/workflows/release.yaml
Dockerfile
Upgrade golangci-lint to v2 and migrate configuration to the new schema.
  • Bump golangci-lint Docker image from v1.64.7-alpine to v2.11.3-alpine.
  • Add top-level version: "2" and go: "1.26" in the .golangci.yaml run section.
  • Replace deprecated enable-all with default: all and refresh the disabled linter list to match v2 behavior and project preferences.
  • Move linter-specific configuration under linters.settings and add new exclusions, presets, and paths according to the v2 configuration model.
Dockerfile
.golangci.yaml
Document the Go version bump in the changelog.
  • Add an Unreleased changelog entry marking the Go toolchain dependency update to 1.26.
docs/docs/changelog.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 4 issues, and left some high level feedback:

  • In the workflows you’re updating, consider also bumping actions/setup-go and actions/checkout to their latest major versions (e.g., setup-go@v5, checkout@v4) to avoid relying on deprecated actions.
  • The new .golangci.yaml explicitly disables several safety/security-related linters (e.g., gosec, noctx, noinlineerr); if that’s intentional, it may be worth narrowing those disables (e.g., via paths/rules) rather than turning them off globally so you still catch issues in most of the codebase.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In the workflows you’re updating, consider also bumping `actions/setup-go` and `actions/checkout` to their latest major versions (e.g., `setup-go@v5`, `checkout@v4`) to avoid relying on deprecated actions.
- The new `.golangci.yaml` explicitly disables several safety/security-related linters (e.g., `gosec`, `noctx`, `noinlineerr`); if that’s intentional, it may be worth narrowing those disables (e.g., via `paths`/`rules`) rather than turning them off globally so you still catch issues in most of the codebase.

## Individual Comments

### Comment 1
<location path=".golangci.yaml" line_range="6" />
<code_context>
-
 linters:
-  enable-all: true
+  default: all
   disable:
-    - typecheck
</code_context>
<issue_to_address>
**issue:** The `default: all` setting under `linters` may not be a recognized key in the v2 golangci-lint config schema.

In v2 configs, the supported way to control linters is via `enable`, `disable`, and `presets`; `default: all` isn’t part of the documented schema and may be ignored or fail validation. Please verify against the v2 reference and switch to the supported fields so the intended linters are reliably applied.
</issue_to_address>

### Comment 2
<location path=".golangci.yaml" line_range="44-49" />
<code_context>
+    - wastedassign
+    - wrapcheck
+    - wsl
+  settings:
+    lll:
+      line-length: 120
+    varnamelen:
+      min-name-length: 1
+  exclusions:
+    generated: lax
</code_context>
<issue_to_address>
**issue (bug_risk):** Linter-specific settings are nested under `linters.settings`, which may not match golangci-lint’s expected config layout.

These settings used to live under `linters-settings`, which aligns with the v1 docs. In v2, examples still show a top-level `linters-settings` rather than `linters: settings:`. If this nesting isn’t supported, `lll` and `varnamelen` configs may be silently ignored. Please verify against the v2 golangci-lint config docs and adjust the structure so these options are applied.
</issue_to_address>

### Comment 3
<location path=".github/workflows/release.yaml" line_range="15-18" />
<code_context>
         uses: actions/setup-go@v1
         with:
-          go-version: 1.24.x
+          go-version: 1.26.x
       - name: Run GoReleaser (dry run)
         env:
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Using `actions/setup-go@v1` with a future Go version can be brittle and may not be supported.

Since `setup-go@v1` is outdated and has had breaking changes and deprecations, using it with Go 1.26 increases the chance of workflow failures. Please upgrade to a maintained major version (e.g., `actions/setup-go@v5`) that explicitly supports newer Go releases.

```suggestion
      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: 1.26.x
```
</issue_to_address>

### Comment 4
<location path="docs/docs/changelog.md" line_range="8" />
<code_context>

 ## [Unreleased](https://github.com/lets-cli/lets/releases/tag/v0.0.X)

+* `[Dependency]` update go to `1.26`
 * `[Added]` Show similar command suggestions on typos.
 * `[Changed]` Exit code 2 on unknown command.
</code_context>
<issue_to_address>
**nitpick (typo):** Capitalize "Go" as the language name.

In this changelog entry, update `go` to `Go`: `* 

* `[Dependency]` update Go to `1.26``.

```suggestion
* `[Dependency]` update Go to `1.26`
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread .golangci.yaml

linters:
enable-all: true
default: all
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: The default: all setting under linters may not be a recognized key in the v2 golangci-lint config schema.

In v2 configs, the supported way to control linters is via enable, disable, and presets; default: all isn’t part of the documented schema and may be ignored or fail validation. Please verify against the v2 reference and switch to the supported fields so the intended linters are reliably applied.

Comment thread .golangci.yaml
Comment thread .github/workflows/release.yaml
Comment thread docs/docs/changelog.md

## [Unreleased](https://github.com/lets-cli/lets/releases/tag/v0.0.X)

* `[Dependency]` update go to `1.26`
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick (typo): Capitalize "Go" as the language name.

In this changelog entry, update go to Go: `*

  • [Dependency] update Go to `1.26``.
Suggested change
* `[Dependency]` update go to `1.26`
* `[Dependency]` update Go to `1.26`

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Mar 17, 2026

Greptile Summary

This PR is a straightforward Go toolchain upgrade from 1.24 → 1.26, consistently applied across go.mod, both CI workflows, the Dockerfile, and the golangci-lint configuration. It also migrates the linter config from the golangci-lint v1 format to the v2 format (version: "2", default: all, restructured settings/exclusions), and bumps the linter image from v1.64.7 to v2.11.3.

Key observations:

  • The Go version is now consistent across all files (go.mod, .golangci.yaml, workflows, Dockerfile), fixing a pre-existing drift where .golangci.yaml still referenced Go 1.23.
  • The golangci-lint v2 config migration looks correct overall — deprecated linters (typecheck, maligned, ifshort) are properly removed and renamed linters (goerr113err113, exhaustivestructexhaustruct, gomndmnd) are updated.
  • Minor concerns: the goreleaser-cross image tag uses v1.26 without a patch version (same as before), goimports is no longer explicitly disabled in the linter config (was disabled in v1), and go.mod omits the optional toolchain directive introduced in Go 1.21.

Confidence Score: 4/5

  • This PR is safe to merge with a few minor items worth verifying before the next release.
  • The changes are mechanical and well-scoped — every version reference is updated consistently. The only real risks are: (1) the goreleaser-cross tag format (v1.26 without patch) which follows the pre-existing pattern and is likely fine, and (2) goimports now being unintentionally enabled by golangci-lint v2's default: all, which could silently cause the lint CI job to fail. Neither is a blocking issue for the module itself, but the lint change could break the CI pipeline.
  • .golangci.yaml — verify that goimports is not unintentionally enabled by default: all in golangci-lint v2; .github/workflows/release.yaml — confirm goreleaser-cross:v1.26 image tag resolves correctly.

Important Files Changed

Filename Overview
go.mod Bumps the minimum Go version from 1.24 to 1.26; no toolchain directive added (optional but now common practice for Go ≥ 1.21)
.golangci.yaml Migrates from golangci-lint v1 to v2 config format (version: "2", default: all, settings/exclusions restructured); aligns Go version from 1.23 to 1.26; goimports is no longer explicitly disabled
Dockerfile Updates base image from golang:1.24-bookworm to golang:1.26-bookworm and golangci-lint from v1.64.7-alpine to v2.11.3-alpine
.github/workflows/release.yaml Updates go-version and GOLANG_CROSS_VERSION from 1.24 to 1.26; uses version tag v1.26 for goreleaser-cross without a patch component
.github/workflows/test.yaml Straightforward go-version bump from 1.24.x to 1.26.x; no other changes
docs/docs/changelog.md Adds a changelog entry for the Go 1.26 dependency update under the Unreleased section

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    PR[PR: Bump Go to 1.26] --> GM[go.mod\ngo 1.26]
    PR --> DF[Dockerfile\ngolang:1.26-bookworm\ngolangci-lint:v2.11.3-alpine]
    PR --> GL[.golangci.yaml\nversion: 2 format\ngo: 1.26]
    PR --> TW[test.yaml\nsetup-go: 1.26.x]
    PR --> RW[release.yaml\nsetup-go: 1.26.x\nGOLANG_CROSS_VERSION: v1.26]

    TW --> CI1[Unit tests\nmacOS + Ubuntu]
    TW --> CI2[Bats integration tests]
    TW --> CI3[Lint job\nlints lint]

    RW --> REL[GoReleaser cross-compile\nghcr.io/goreleaser/goreleaser-cross:v1.26]

    CI3 -- uses --> DF
    CI3 -- uses --> GL
Loading

Last reviewed commit: e121c50

env:
PACKAGE_NAME: github.com/lets-cli/lets
GOLANG_CROSS_VERSION: v1.24
GOLANG_CROSS_VERSION: v1.26
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 goreleaser-cross tag lacks patch version

GOLANG_CROSS_VERSION is set to v1.26 (no patch component). The ghcr.io/goreleaser/goreleaser-cross images are typically published with full patch version tags (e.g., v1.26.0, v1.26.1). If the registry does not provide a floating v1.26 tag, both the dry-run and release steps will fail with an image-not-found error at runtime.

The same pattern existed previously (v1.24), so this may have been fine in practice — but it's worth pinning to a specific patch tag to make the workflow reproducible and avoid surprises when a new patch is published.

Suggested change
GOLANG_CROSS_VERSION: v1.26
GOLANG_CROSS_VERSION: v1.26.0

The same change should also be applied on line 36.

Comment thread go.mod
module github.com/lets-cli/lets

go 1.24
go 1.26
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Consider adding a toolchain directive

Since Go 1.21, the recommended practice is to pair the go directive with an explicit toolchain directive that pins the exact toolchain version. Without it, developers and CI with a newer toolchain installed may silently use a different patch than intended.

Suggested change
go 1.26
go 1.26
toolchain go1.26.0

Comment thread .golangci.yaml
Comment on lines 7 to +43
disable:
- typecheck
- gomoddirectives
- containedctx
- gochecknoglobals
- goimports
- funlen
- godox
- maligned
- goerr113
- exhaustivestruct
- wrapcheck
- prealloc # enable it sometimes
- wsl
- ifshort
- unparam
- copyloopvar
- cyclop
- gocyclo
- depguard
- err113
- exhaustive
- exhaustruct
- forcetypeassert
- funlen
- funcorder
- gochecknoglobals
- gocognit
- tagliatelle
- nestif
- nlreturn
- gocritic
- gocyclo
- godoclint
- godox
- gomoddirectives
- goprintffuncname
- exhaustruct
- wastedassign
- gosec
- importas
- lll
- mnd
- musttag
- nestif
- nilnil
- noctx
- noinlineerr
- nlreturn
- prealloc
- recvcheck
- musttag
- mnd
- lll
- gocritic
- forcetypeassert
- exhaustive
- depguard
- revive
- gosec
- copyloopvar

linters-settings:
lll:
line-length: 120
varnamelen:
min-name-length: 1

issues:
exclude-rules:
- path: _test\.go
linters:
- gomnd
- path: set\.go
linters:
- typecheck
- tagliatelle
- unparam
- wastedassign
- wrapcheck
- wsl
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 goimports no longer explicitly disabled

The previous config explicitly disabled goimports. The new config migrates to default: all (golangci-lint v2) but goimports is absent from the disable list. If goimports is included in the v2 default set, any file whose imports are not in goimports order will now produce lint failures and could break the lint CI job.

It's worth verifying whether the legacy exclusion preset covers this, or whether goimports should be added back to the disable list to preserve prior behaviour:

Suggested change
disable:
- typecheck
- gomoddirectives
- containedctx
- gochecknoglobals
- goimports
- funlen
- godox
- maligned
- goerr113
- exhaustivestruct
- wrapcheck
- prealloc # enable it sometimes
- wsl
- ifshort
- unparam
- copyloopvar
- cyclop
- gocyclo
- depguard
- err113
- exhaustive
- exhaustruct
- forcetypeassert
- funlen
- funcorder
- gochecknoglobals
- gocognit
- tagliatelle
- nestif
- nlreturn
- gocritic
- gocyclo
- godoclint
- godox
- gomoddirectives
- goprintffuncname
- exhaustruct
- wastedassign
- gosec
- importas
- lll
- mnd
- musttag
- nestif
- nilnil
- noctx
- noinlineerr
- nlreturn
- prealloc
- recvcheck
- musttag
- mnd
- lll
- gocritic
- forcetypeassert
- exhaustive
- depguard
- revive
- gosec
- copyloopvar
linters-settings:
lll:
line-length: 120
varnamelen:
min-name-length: 1
issues:
exclude-rules:
- path: _test\.go
linters:
- gomnd
- path: set\.go
linters:
- typecheck
- tagliatelle
- unparam
- wastedassign
- wrapcheck
- wsl
disable:
- containedctx
- copyloopvar
- cyclop
- depguard
- err113
- exhaustive
- exhaustruct
- forcetypeassert
- funlen
- funcorder
- gochecknoglobals
- gocognit
- gocritic
- gocyclo
- godoclint
- godox
- goimports
- gomoddirectives
- goprintffuncname
- gosec
- importas
- lll
- mnd
- musttag
- nestif
- nilnil
- noctx
- noinlineerr
- nlreturn
- prealloc
- recvcheck
- revive
- tagliatelle
- unparam
- wastedassign
- wrapcheck
- wsl

@kindermax kindermax force-pushed the codex/update-lets-to-go-126 branch from e121c50 to 08e42dc Compare March 18, 2026 18:13
@kindermax kindermax force-pushed the codex/update-lets-to-go-126 branch from 65e7282 to a688482 Compare March 18, 2026 18:34
@kindermax kindermax merged commit c31e857 into master Mar 18, 2026
5 checks passed
@kindermax kindermax deleted the codex/update-lets-to-go-126 branch March 18, 2026 18:37
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.

1 participant