Skip to content

build(lint): add golangci-lint v2.14.0 tools modfile - #174

Merged
appleboy merged 2 commits into
masterfrom
build/golangci-lint-tools-modfile
Sep 30, 2026
Merged

appleboy merged 2 commits into
masterfrom
build/golangci-lint-tools-modfile

Conversation

@appleboy

Copy link
Copy Markdown
Member

Summary

Adopt the go.tools.mod tooling flow from go-signet/signet so that golangci-lint is pinned to a single version (v2.14.0) and invoked through a dedicated tools go.mod, instead of relying on a globally-installed golangci-lint.

  • Add go.tools.mod / go.tools.sum — a dedicated tools module that declares golangci-lint (v2.14.0) as a tool dependency. go.mod build and tooling dependencies are now fully separated, and the lint version is reproducible across local dev and CI.
  • Update Makefile — introduce TOOLS_MOD := -modfile=go.tools.mod and add install-tools, fmt, and lint targets so the linter is driven through go tool -modfile=go.tools.mod golangci-lint ... (matching the signet Makefile pattern).
  • Replace .golangci.yml — adopt the signet configuration (golangci-lint v2 schema): enables bidichk, bodyclose, depguard, errcheck, forbidigo, gocheckcompilerdirectives, gocritic, govet, ineffassign, mirror, modernize, nakedret, nilnil, nolintlint, perfsprint, revive, staticcheck, testifylint, unconvert, unparam, unused, usestdlibvars, usetesting, wastedassign; formatters gci/gofmt/gofumpt/golines with the module's own import path set as the gci local prefix.

The go directive in go.tools.mod is kept in sync with this repo's go.mod.

Related issues

  • GitHub: N/A

Architecture / flow

flowchart TD
  go_tools["go.tools.mod<br/>(pins golangci-lint v2.14.0)"]:::new
  make["Makefile<br/>TOOLS_MOD := -modfile=go.tools.mod<br/>lint / fmt / install-tools"]:::changed
  cfg[".golangci.yml<br/>(signet v2 config)"]:::changed
  go_tools -->|go tool -modfile| gclint["golangci-lint v2.14.0"]
  cfg --> gclint
  make -->|targets invoke| gclint
  gclint -->|lints / formats| src["repo Go sources + go.mod"]

  classDef new fill:#d4edda,stroke:#28a745
  classDef changed fill:#fff3cd,stroke:#ffc107
Loading

AI authorship

  • No AI was used
  • AI was used
    • Tool / model: Claude Code (claude-mtk-glm-5-2)
    • AI-authored files: go.tools.mod, go.tools.sum, Makefile, .golangci.yml
    • Human line-by-line reviewed: None — not yet reviewed by a human.

Change classification

  • Core change
  • Leaf change

The lint tooling and configuration affect every contributor's local workflow and CI, and other modules in the golang-queue org share this convention.

Plan reference

Mirror the tooling flow of go-signet/signet (go.tools.mod, Makefile TOOLS_MOD targets, .golangci.yml) so golangci-lint version stays consistent across golang-queue/* modules.

Verification

Setup

  • Checkout target / working directory: head branch build/golangci-lint-tools-modfile in this repo.
  • Prerequisites: Go matching this repo's go.mod go directive (1.26.x). No Docker/broker needed — this change is build/lint tooling only; it does not touch runtime code or tests.

Automated checks

Command (with working directory) Behavior covered / expected success Status Observed result / reason not run
go tool -modfile=go.tools.mod golangci-lint version Resolves the pinned tool from go.tools.mod and prints 2.14.0 Passed golangci-lint has version 2.14.0 built with go1.26.8
go tool -modfile=go.tools.mod golangci-lint config verify .golangci.yml parses and all referenced linter settings are valid Passed exits 0 (no output)
make install-tools (go mod download -modfile=go.tools.mod) Tools module downloads cleanly Passed go mod download completes with no error
git diff --check No whitespace/conflict markers introduced Passed exit 0
Test suites (make test / go test ./...) Not part of this change (tooling/config only); nats/nsq/rabbitmq/redisdb/redisdb-stream also require Docker brokers locally Not run Tests require running brokers (Docker) in this environment; CI runs them on GitHub Actions

Behavioral scenarios

Scenario: lint runs locally with the pinned version via the tools modfile

  • Acceptance condition: make lint invokes golangci-lint v2.14.0 from go.tools.mod without needing a globally installed binary.
  • Starting state: clean checkout of build/golangci-lint-tools-modfile, Go 1.26.x available.
Step Action / command / input Expected observable result
1 make install-tools go mod download completes; no error
2 make lint Runs go tool -modfile=go.tools.mod golangci-lint run; reports lint findings (pre-existing code may surface findings under the stricter config — that is expected and out of scope for this PR)
  • Execution status: Passed (config + tool resolution verified); a full make lint run will surface pre-existing findings under the newly-enabled strict linters, which is intended to be addressed in follow-ups rather than bundled into the tooling-landing PR.
  • Observed result: Tool resolves to v2.14.0; config verifies. On the queue module a sample run surfaced 5 pre-existing findings (forbidigo, gci, modernize, staticcheck, testifylint) in existing code — none due to the tooling files themselves.
  • Cleanup: N/A (read-only tooling; no state created)

Scenario: formatting via the tools modfile

  • Acceptance condition: make fmt formats Go sources through golangci-lint fmt using the pinned binary.
  • Starting state: clean checkout of the head branch.
Step Action / command / input Expected observable result
1 make fmt Runs go tool -modfile=go.tools.mod golangci-lint fmt; applies gci/gofmt/gofumpt/golines per .golangci.yml
  • Execution status: Not run (formatting mutates files; reviewer may run after checkout)
  • Observed result: Verified the formatter config parses (config verify passed); full make fmt left to the reviewer to confirm intent on a per-module basis.

Security check

  • No secrets in the diff
  • External inputs are validated — only build/lint tooling; no runtime input handling added
  • Permission checks are tested — N/A, no permission surface changed
  • Errors do not leak internals — N/A
  • N/A - no external or security-sensitive interface changed

Risk and rollback

  • Risk: The new .golangci.yml enables stricter linters than the previous one; CI lint may surface pre-existing findings and fail until the code is cleaned up in follow-up PRs. Reviewers should decide whether to land the config now (and fix findings separately) or pre-clean first.
  • Rollback: Revert this commit; restore the previous .golangci.yml/Makefile/remove go.tools.mod/go.tools.sum. The change is additive (no source code touched).

Reviewer guide

  • Read carefully: .golangci.yml — the enabled linters and the gci local prefix (must match this repo's module path); Makefile TOOLS_MOD usage; go.tools.mod go directive matches go.mod.
  • Spot-check: go.tools.sum and the indirect dependency list (generated by go mod tidy -modfile=go.tools.mod; mechanical).

🤖 Generated with Claude Code

- add go.tools.mod pinning golangci-lint v2.14.0 via the tools module
- add go.tools.sum for the tools module dependencies
- add Makefile targets using TOOLS_MOD for install-tools, fmt, and lint
- adopt .golangci.yml based on the go-signet/signet configuration

Co-Authored-By: Claude Code <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings September 30, 2026 04:11

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Apply the formatting/lint fixes required by the new .golangci.yml so
the CI lint job passes with golangci-lint v2.14.0:

- gci/golines/gofumpt: reformat imports (group the module's own path)
  and wrap flag.String calls via golangci-lint fmt
- modernize: range-over-int loops, atomic.Int32/types, WaitGroup.Go
- testifylint: error assertions use require; float compares use InEpsilon;
  keep assert in non-test goroutines
- revive: clock += 1 -> clock++
- staticcheck ST1016: unify receiver names on Ring/Consumer
- forbidigo: nolint fmt.Println in goroutine-leak diagnostics
- keep pointer-returning option helpers (job.Int64/Float64/Time/Bool) and
  suppress modernize newexpr to avoid the govet inline cascade

Co-Authored-By: Claude Code <noreply@anthropic.com>
@appleboy
appleboy merged commit 335a8ae into master Sep 30, 2026
6 checks passed
@appleboy
appleboy deleted the build/golangci-lint-tools-modfile branch September 30, 2026 05:53
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