Skip to content

Migrate golangci-lint from v1 to v2#3261

Open
robnester-rh wants to merge 2 commits intoconforma:mainfrom
robnester-rh:EC-1756
Open

Migrate golangci-lint from v1 to v2#3261
robnester-rh wants to merge 2 commits intoconforma:mainfrom
robnester-rh:EC-1756

Conversation

@robnester-rh
Copy link
Copy Markdown
Contributor

Summary

Migrates golangci-lint from v1 (1.64.8) to v2 (2.11.4), resolving the CodeRabbit config parsing warning seen on recent PRs.

What changed:

  • .golangci.yaml: Added version: "2", moved gci/goimports to formatters section, added v1-equivalent exclusion presets, excluded new v2-only checks (gosec G122/G702/G703, staticcheck QF*/ST*) to maintain parity
  • tools/go.mod + tools/tools.go: Updated module path from github.com/golangci/golangci-lintgithub.com/golangci/golangci-lint/v2
  • Makefile: Updated go run paths to v2, removed --sort-results flag (now default in v2)

Acceptance Criteria

  • version: "2" is present in .golangci.yaml
  • gci and goimports are under formatters.enable, not linters.enable
  • tools/go.mod references github.com/golangci/golangci-lint/v2
  • Makefile go run paths use the v2 module path
  • make lint passes locally
  • make lint-fix still auto-fixes formatting issues
  • CodeRabbit no longer reports the golangci-lint config warning (to verify after merge)

Notes

  • The v2 staticcheck linter now bundles ST* (style) and QF* (quickfix) checks that were previously in the separate stylecheck linter (not enabled in our v1 config). These are excluded to maintain parity — enabling them can be done in a follow-up.
  • New gosec taint analysis rules (G122, G702, G703) added in the gosec version bundled with v2 are excluded for the same reason.
  • The tools/go.mod and tools/go.sum diff is mechanical dependency resolution — sanity check, not line-by-line.

Ref: EC-1756

Made with Cursor

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 23, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5a235dee-4593-4352-96d4-84e4e04a29a7

📥 Commits

Reviewing files that changed from the base of the PR and between d854dba and 7d35b0d.

⛔ Files ignored due to path filters (1)
  • tools/go.sum is excluded by !**/*.sum
📒 Files selected for processing (4)
  • .golangci.yaml
  • Makefile
  • tools/go.mod
  • tools/tools.go
✅ Files skipped from review due to trivial changes (2)
  • tools/tools.go
  • Makefile
🚧 Files skipped from review as they are similar to previous changes (1)
  • .golangci.yaml

📝 Walkthrough

Walkthrough

Update linting toolchain to golangci-lint v2: migrate config schema, adjust Makefile targets to v2 command path, update tooling blank imports, and bump tooling dependencies in tools/go.mod.

Changes

Cohort / File(s) Summary
golangci-lint configuration
\.golangci\.yaml
Change version to "2"; move gci/goimports into formatters.enable and relocate gci sections under formatters.settings; enable staticcheck (all with QF*/ST* disabled); add linters.exclusions.presets and linters.settings gosec exclusions (G122, G702, G703); replace empty issues.exclude-rules with issues.exclude-generated: lax.
Makefile targets
Makefile
Switch golangci-lint invocations to v2 module entrypoint (github.com/golangci/golangci-lint/v2/cmd/golangci-lint); remove --sort-results from lint runs; keep --fix for lint-fix and conditional --timeout=10m0s when GITHUB_ACTIONS is set.
Tooling blank imports
tools/tools.go
Update blank import for tracking golangci-lint from v1 command package to v2 command package path.
Tooling dependencies
tools/go.mod
Bump github.com/golangci/golangci-lint to v2.11.4, github.com/daixiang0/gci to v0.13.7, and update a large set of indirect linter/analyzer dependencies (adds, removals, and version bumps).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and clearly summarizes the main change: migrating golangci-lint from v1 to v2, which is the core objective of the pull request.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, covering the migration scope, configuration changes, dependency updates, and acceptance criteria.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.11.4)

Command failed


Comment @coderabbitai help to get the list of available commands and usage tips.

@qodo-code-review
Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Migrate golangci-lint from v1 to v2

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Migrate golangci-lint from v1 (1.64.8) to v2 (2.11.4)
• Move gci and goimports to formatters section in config
• Exclude new v2-only checks to maintain parity with v1
• Update module paths and remove deprecated --sort-results flag
Diagram
flowchart LR
  A["golangci-lint v1.64.8"] -- "upgrade version" --> B["golangci-lint v2.11.4"]
  C[".golangci.yaml v1 config"] -- "restructure formatters" --> D[".golangci.yaml v2 config"]
  E["tools/go.mod v1 path"] -- "update module path" --> F["tools/go.mod v2 path"]
  G["Makefile v1 invocations"] -- "update go run paths" --> H["Makefile v2 invocations"]
  B --> D
  B --> F
  B --> H
Loading

Grey Divider

File Changes

1. .golangci.yaml ⚙️ Configuration changes +32/-9

Restructure config for golangci-lint v2 compatibility

• Added version: "2" to enable golangci-lint v2 configuration
• Moved gci and goimports from linters.enable to formatters.enable with settings under
 formatters.settings
• Added linters.exclusions.presets to preserve v1 default exclusion behavior (comments,
 common-false-positives, legacy, std-error-handling)
• Excluded new v2-only gosec rules (G122, G702, G703) and staticcheck checks (QF*, ST*) to maintain
 parity
• Changed issues.exclude-rules: [] to issues.exclude-generated: lax

.golangci.yaml


2. tools/tools.go Dependencies +1/-1

Update golangci-lint import to v2 module path

• Updated import path from github.com/golangci/golangci-lint/cmd/golangci-lint to
 github.com/golangci/golangci-lint/v2/cmd/golangci-lint

tools/tools.go


3. tools/go.mod Dependencies +99/-78

Update golangci-lint and transitive dependencies to v2

• Updated github.com/golangci/golangci-lint from v1.64.8 to github.com/golangci/golangci-lint/v2
 v2.11.4
• Updated github.com/daixiang0/gci from v0.13.5 to v0.13.7
• Resolved transitive dependencies for v2 linter ecosystem (added new linters, updated versions of
 existing linters)

tools/go.mod


View more (2)
4. Makefile ⚙️ Configuration changes +4/-4

Update Makefile to use golangci-lint v2 paths

• Updated go run module paths from github.com/golangci/golangci-lint/cmd/golangci-lint to
 github.com/golangci/golangci-lint/v2/cmd/golangci-lint in lint and lint-fix targets
• Removed --sort-results flag from lint commands (now default behavior in v2)
• Updated both main and acceptance test linting invocations

Makefile


5. tools/go.sum Additional files +208/-180

...

tools/go.sum


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown
Contributor

qodo-code-review Bot commented Apr 23, 2026

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. No local lint timeout 🐞 Bug ☼ Reliability
Description
make lint only applies --timeout when GITHUB_ACTIONS is set, so local runs (and any non-GitHub
CI) can run indefinitely under golangci-lint v2. This can hang developer workflows when analysis
stalls or is unusually slow.
Code

Makefile[R200-201]

+	@go run -modfile tools/go.mod github.com/golangci/golangci-lint/v2/cmd/golangci-lint run $(if $(GITHUB_ACTIONS), --timeout=10m0s)
+	@(cd acceptance && go run -modfile ../tools/go.mod github.com/golangci/golangci-lint/v2/cmd/golangci-lint run --path-prefix acceptance $(if $(GITHUB_ACTIONS), --timeout=10m0s))
Evidence
The Makefile passes --timeout=10m0s only under $(if $(GITHUB_ACTIONS), ...), leaving other
environments without any timeout. The EC-1756 ticket notes golangci-lint v2 removes the default
timeout, so the conditional becomes a behavior change vs v1.

[cli] Migrate golangci-lint from v1 to v2
Makefile[194-207]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`make lint` (and the acceptance subdir lint) only sets `--timeout` when `GITHUB_ACTIONS` is present. With golangci-lint v2 having no default timeout, local/non-GHA runs can hang indefinitely.

## Issue Context
This is a workflow reliability regression after moving to golangci-lint v2.

## Fix Focus Areas
- Update `Makefile` to always pass a timeout (optionally configurable via a make var, e.g. `LINT_TIMEOUT ?= 10m0s`), and use it in both the root and `acceptance/` golangci-lint invocations.

### Fix locations
- Makefile[194-207]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Duplicated gci settings 🐞 Bug ⚙ Maintainability
Description
gci section ordering is configured in .golangci.yaml and also hard-coded in the Makefile
lint-fix command, creating two sources of truth. If they diverge, developers can get inconsistent
import grouping depending on which path runs.
Code

.golangci.yaml[R47-56]

+formatters:
+  enable:
+    - gci
+    - goimports
+  settings:
+    gci:
+      sections:
+        - standard
+        - default
+        - prefix(github.com/conforma/cli)
Evidence
.golangci.yaml newly defines formatters.settings.gci.sections, but make lint-fix still runs
gci write with explicit -s ... flags, bypassing the YAML and requiring manual synchronization.

.golangci.yaml[47-57]
Makefile[203-212]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`gci` section config exists in two places: `.golangci.yaml` and a hard-coded `gci write` invocation in `make lint-fix`. This duplication will drift over time.

## Issue Context
The PR moved `gci` under `formatters` for golangci-lint v2, but the Makefile still directly runs `gci` with flags.

## Fix Focus Areas
- Prefer a single source of truth for gci sections.
- Option A (preferred): switch `lint-fix` to use golangci-lint's formatter execution (e.g., `golangci-lint fmt` if adopted in this repo) and remove the explicit `gci write ... -s ...` line.
- Option B: keep the explicit `gci write` call but remove the duplicated `formatters.settings.gci.sections` (only if it’s not required by golangci-lint v2 for formatting checks in this repo).
- If neither option is feasible, at least add an explicit comment in the Makefile pointing to `.golangci.yaml` as the canonical config and stating the flags must be kept in sync.

### Fix locations
- .golangci.yaml[47-57]
- Makefile[203-212]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Advisory comments

3. Staticcheck enablement unclear🐞 Bug ⚙ Maintainability
Description
.golangci.yaml configures staticcheck.checks but doesn’t list staticcheck under
linters.enable, making it unclear whether staticcheck is expected to run explicitly or only via
defaults. This increases the risk of accidental lint-scope changes when golangci-lint defaults
evolve.
Code

.golangci.yaml[R25-39]

linters:
  enable:
-    - gci
-    - goimports
    - gosec
    - misspell
-linters-settings:
-  gci:
-    sections:
-      - standard
-      - default
-      - prefix(github.com/conforma/cli)
+  settings:
+    gosec:
+      excludes:
+        - G122
+        - G702
+        - G703
+    staticcheck:
+      checks:
+        - "all"
+        - "-QF*"
+        - "-ST*"
Evidence
The config sets linters.settings.staticcheck.checks but only explicitly enables gosec and
misspell, so readers can’t easily tell whether staticcheck is intended to be active and controlled
here.

.golangci.yaml[25-39]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`staticcheck` is configured but not explicitly enabled, which is confusing and can lead to unexpected behavior if golangci-lint defaults change.

## Issue Context
The PR adds staticcheck check exclusions to maintain parity, but the activation mechanism isn’t obvious from the config.

## Fix Focus Areas
- Either explicitly list `staticcheck` in `linters.enable`, OR add a short comment explaining that staticcheck is expected to run via golangci-lint defaults and this block only adjusts its checks.

### Fix locations
- .golangci.yaml[25-39]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread Makefile
Comment on lines +200 to +201
@go run -modfile tools/go.mod github.com/golangci/golangci-lint/v2/cmd/golangci-lint run $(if $(GITHUB_ACTIONS), --timeout=10m0s)
@(cd acceptance && go run -modfile ../tools/go.mod github.com/golangci/golangci-lint/v2/cmd/golangci-lint run --path-prefix acceptance $(if $(GITHUB_ACTIONS), --timeout=10m0s))
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.

Action required

1. No local lint timeout 🐞 Bug ☼ Reliability

make lint only applies --timeout when GITHUB_ACTIONS is set, so local runs (and any non-GitHub
CI) can run indefinitely under golangci-lint v2. This can hang developer workflows when analysis
stalls or is unusually slow.
Agent Prompt
## Issue description
`make lint` (and the acceptance subdir lint) only sets `--timeout` when `GITHUB_ACTIONS` is present. With golangci-lint v2 having no default timeout, local/non-GHA runs can hang indefinitely.

## Issue Context
This is a workflow reliability regression after moving to golangci-lint v2.

## Fix Focus Areas
- Update `Makefile` to always pass a timeout (optionally configurable via a make var, e.g. `LINT_TIMEOUT ?= 10m0s`), and use it in both the root and `acceptance/` golangci-lint invocations.

### Fix locations
- Makefile[194-207]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 23, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

Flag Coverage Δ
acceptance 55.20% <ø> (-0.01%) ⬇️
generative 17.90% <ø> (ø)
integration 26.65% <ø> (ø)
unit 69.01% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

- Add `version: "2"` to `.golangci.yaml`
- Move `gci` and `goimports` from `linters.enable` to `formatters.enable`
  with settings under `formatters.settings`
- Add `linters.exclusions.presets` to preserve v1 default exclusion behavior
- Exclude new v2-only gosec rules (G122, G702, G703) and staticcheck
  checks (QF*, ST*) that weren't active in v1
- Update `tools/go.mod` and `tools/tools.go` to the v2 module path
- Update Makefile `go run` invocations to use v2 module path
- Remove `--sort-results` flag (removed in v2, now default behavior)
- Add `issues.exclude-generated: lax` to preserve v1 default

Ref: EC-1756
Signed-off-by: Rob Nester <rnester@redhat.com>
Made-with: Cursor
- Add staticcheck explicitly to linters.enable for clarity
- Remove redundant gci write invocation from lint-fix target;
  golangci-lint v2 run --fix handles formatters including gci

Ref: EC-1756
Signed-off-by: Rob Nester <rnester@redhat.com>
Made-with: Cursor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant