skills/upgrade-golangci-lint/SKILL.md
--- name: upgrade-golangci-lint description: Upgrade golangci-lint to the latest version, automatically migrate config (v1→v2), run lint and supplement config to make code pass. Core principle: only adjust config, do not modify code. --- # golangci-lint Version Upgrade Upgrade golangci-lint to the latest version, handle configuration migration, and adjust configuration to make existing code pass lint checks. > **Core Principle**: Make existing code pass lint by adjusting configuration, **do n
npx skillsauth add alingse/golangci-lint-skills skills/upgrade-golangci-lintInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Upgrade golangci-lint to the latest version, handle configuration migration, and adjust configuration to make existing code pass lint checks.
Core Principle: Make existing code pass lint by adjusting configuration, do not modify existing code. Only affects new code.
# Check current version
golangci-lint --version
# Check for configuration file (supports 4 formats)
ls .golangci.* 2>/dev/null || echo "No config"
# Check config format version (v1 or v2) - only valid for YAML format
grep "^version:" .golangci.yml .golangci.yaml 2>/dev/null && echo "v2 config" || echo "v1 config (needs migration)"
# Detect installation method
if command -v brew &> /dev/null && brew list golangci-lint &> /dev/null 2>/dev/null; then
INSTALL_METHOD="brew"
elif command -v golangci-lint &> /dev/null; then
INSTALL_METHOD="binary"
else
echo "golangci-lint not installed, please run setup-golangci-lint first"
exit 1
fi
Execute upgrade based on detected installation method:
| Installation Method | Upgrade Command |
|---------------------|-----------------|
| Binary | curl -sSfL https://golangci-lint.run/install.sh | sh -s -- -b $(go env GOPATH)/bin latest |
| Homebrew | brew upgrade golangci-lint |
| Alpine (no curl) | wget -O- -nv https://golangci-lint.run/install.sh | sh -s -- -b $(go env GOPATH)/bin latest |
# Binary upgrade (recommended)
curl -sSfL https://golangci-lint.run/install.sh | sh -s -- -b $(go env GOPATH)/bin latest
# Verify upgrade success
golangci-lint --version
If v1 configuration is detected (no version: field in config file), execute migration:
# Automatically migrate v1 config to v2 format
golangci-lint migrate --skip-validation
Notes:
--skip-validation: Skip validation, convert directly (recommended)migrate command will automatically:
version: 2enable-all/disable-all to linters.defaultlinters-settings to linters.settingsissues.exclude-rules to linters.exclusions.rulesAfter migration, manually check the configuration to ensure:
linters.default value meets expectations (standard/all/none/fast)# TODO fix later by human comments# TODO reduce this# Verify configuration format
golangci-lint config verify
# Run lint
golangci-lint run --timeout=5m ./...
🆕 Special Handling for New Linters: After version upgrade, the new version may introduce linters that didn't exist before. Handling strategy for these new linters differs from existing linters.
Identify New Linters:
# Save old version linter list (execute before upgrade)
golangci-lint help linters > /tmp/old_linters.txt
# Compare after upgrade
golangci-lint help linters > /tmp/new_linters.txt
diff /tmp/old_linters.txt /tmp/new_linters.txt
Or simply check the error output after upgrade to identify previously unseen linter names.
New Linter Handling Strategy:
| Issue Count | Category | Action | Notes | |-------------|----------|--------|-------| | < 5 | Any category | Provide fix suggestions | Few issues, worth fixing | | 5-20 | c. Critical bugs | Provide fix suggestions | Security/error issues, recommended to fix | | 5-20 | a. Configurable | Adjust settings | Prioritize threshold adjustment | | 5-20 | b/d/f Others | disable + TODO | Handle per original logic | | > 20 | Any category | disable + TODO | Too many issues, handle later |
Fix Suggestion Format:
## 🆕 New Linter Fix Suggestions
The following linters are newly introduced in this upgrade and have few issues, recommended to fix:
### Linter: nilerr
- **Issue Count**: 3
- **Severity**: High (may cause bugs)
- **Fix Suggestions**:
1. `pkg/api/handler.go:45` - Check error return is correct
2. `pkg/service/user.go:123` - Ensure non-nil return when error is non-nil
3. `pkg/db/client.go:67` - Fix error handling logic
### Linter: contextcheck
- **Issue Count**: 2
- **Severity**: Medium (may cause context loss)
- **Fix Suggestions**:
1. `pkg/api/client.go:89` - Add context parameter
2. `pkg/service/order.go:156` - Pass context to downstream
---
**Would you like me to help fix these issues?** Reply "fix" to start fixing.
Why Not Auto-Fix New Linter Issues:
✅ AI MUST include "New Linter Analysis" section in final output report:
- List all newly added linters
- Categorize by issue count and severity (recommended to fix vs defer)
- Provide clear summary table
- Refer to format in "Output Report Template" below
📌 AI Operation Requirements:
Core Principle: Do not modify existing code, only make code pass by adjusting configuration (settings/disable/exclusions)
Workflow: Run lint → Categorize and handle → Add standardized TODO comments
Universal Classification Logic (based on keywords in linter description):
Step 1: Get linter description
golangci-lint help <linter-name>Step 2: Categorize based on keywords in description
| Category | Keywords in Description | Action | Example Linters & Descriptions | |----------|------------------------|--------|-------------------------------| | a. Configurable | complexity, long, deeply, count, length, size, max, min, limit | Adjust settings | funlen: "Checks for long functions"<br>gocyclo: "Checks cyclomatic complexity"<br>nestif: "Reports deeply nested if"<br>dogsled: "Checks too many blank identifiers" | | b. Code Style-Manual Confirm | style, format, naming, whitespace, align, order, declaration | disable + TODO | godot: "Check if comments end in period"<br>tagalign: "Check struct tags well aligned"<br>misspell: "Finds commonly misspelled"<br>varnamelen: "Checks variable name length" | | c. Critical Bugs-Suggest Fix | bug, security, error, check, nil, unsafe, detect, inspects | disable + TODO | errcheck: "Checking for unchecked errors"<br>gosec: "Inspects source code for security"<br>staticcheck: "set of rules from staticcheck"<br>nilerr: "returns nil even if error is not nil" | | d. Cannot Modify | (check specific error message, usually involves external constraints) | exclusions | canonicalheader: HTTP header spec (3rd-party APIs)<br>asciicheck: Non-ASCII symbols (Chinese function names) | | e. Can Fix Small | (determined by actual issue count, < 5) | exclude-rules | Any linter with few issues | | f. New Features-Defer | modern, new, latest, replace, simplification, feature | disable + TODO | modernize: "suggest simplifications using modern language"<br>exptostd: "replaced by std functions"<br>usestdlibvars: "use variables from standard library" |
Step 3: Complete Decision Tree
1. Issue count < 5? ├── Yes → Category e (can fix small): exclude-rules └── No → Continue 2. Description has complexity/long/deeply/max/min/limit/length? ├── Yes → Category a (configurable): Prioritize adjusting settings └── No → Continue 3. Specific error caused by external constraints (3rd-party APIs/generated code/Chinese naming)? ├── Yes → Category d (cannot modify): exclusions path exclusion └── No → Continue 4. Description has modern/new/latest/replace/std/simplification? ├── Yes → Category f (new features-defer): disable + TODO └── No → Continue 5. Description has bug/security/error/check/nil/unsafe/detect/inspects? ├── Yes → Category c (critical bugs-suggest fix): disable + TODO └── No → Category b (code style-manual confirm): disable + TODOConfiguration Priority:
- 1st Priority: Adjust
settingsthresholds (e.g., funlen.lines, gocyclo.min-complexity)- 2nd Priority: Use
linters.exclusionspath exclusion (code that cannot be modified)- 3rd Priority: Use
issues.exclude-rulesrule-based exclusion (specific few issues)- Last Resort: Completely
disable(many issues and cannot be resolved via config)Avoid Duplicates: Each linter appears only once, check for duplicates
Adjust Configuration Based on Actual Errors:
Configuration Priority (try in order):
| Priority | Action | Use Case |
|----------|--------|----------|
| 1️⃣ Highest | Adjust settings thresholds | Linters with config options for complexity/length |
| 2️⃣ Second | linters.exclusions path exclusion | Code that cannot be modified (generated/3rd-party) |
| 3️⃣ Then | issues.exclude-rules rule exclusion | Specific few issues |
| 4️⃣ Last | disable completely | Many issues and no config options |
Category a: Configurable (Prioritize adjusting settings)
linters:
settings:
# Complexity linters: Prioritize adjusting thresholds rather than completely disabling
funlen:
lines: 100 # Default 60, raised to accommodate existing code
statements: 60 # Default 40
gocyclo:
min-complexity: 25 # Default 15
gocognit:
min-complexity: 30 # Default 15
nestif:
min-complexity: 8 # Default 5
Category b: Code Style-Manual Confirm
linters:
disable:
# TODO code style-confirm whether to disable: Does not affect functionality, requires manual confirmation
- mnd # magic numbers, style issues
- wsl # whitespace, code style
- lll # line length limit, style issues
- godot # comment period
- tagalign # struct tag alignment
- goconst # constant extraction suggestion
Category c: Critical Bugs-Suggest Fix
linters:
disable:
# TODO critical bugs-suggest fix: Security and error handling issues, recommend gradual fixes
- errcheck # unchecked errors
- gosec # security checks
- staticcheck # static analysis
- wrapcheck # error wrapping
- nilerr # nil error checks
Category d: Cannot Modify (Path Exclusion)
linters:
exclusions:
rules:
# Generated code (cannot modify)
- path: \.pb\.go|\.gen\.go|\.gen-\w+\.go|\.mock\.go
linters: [all]
# Third-party dependencies (cannot modify)
- path: vendor/|third_party/
linters: [all]
issues:
exclude-rules:
# Third-party APIs (cannot modify)
- text: "non-canonical header"
linters: [canonicalheader]
# Chinese function names (business requirement, cannot modify)
- text: "ID.*must match"
linters: [asciicheck]
Category e: Can Fix Small (Few Specific Issues)
issues:
exclude-rules:
# Specific business scenarios (cannot modify)
- text: "G101: potential hardcoded credential"
path: config/.*\.go
linters: [gosec]
# Relax for test files
- path: _test\.go
linters: [errcheck, gosec, contextcheck]
Category f: New Features-Defer
linters:
disable:
# TODO new features-defer: Does not affect current code, can be selectively enabled later
- modernize # modern Go syntax suggestions
- revive # revive ruleset
- gocritic # code style suggestions
- exhaustruct # struct field completeness
# Run again to ensure pass
golangci-lint run --timeout=5m ./...
# golangci-lint Upgrade Complete
## Version Information
- Old Version: v1.59.1
- New Version: v2.8.0
- Config Migration: v1 → v2
## 🆕 New Linter Analysis
This upgrade introduced **5 new linters**, here are handling recommendations:
### Recommended New Linters to Fix (issue count < 5 or critical issues)
| Linter | Issues | Category | Severity | Recommended Action |
|--------|--------|----------|----------|-------------------|
| **nilerr** | 3 | c. Critical Bugs-Suggest Fix | 🔴 High | **Recommended Fix** - May cause bugs |
| **contextcheck** | 2 | c. Critical Bugs-Suggest Fix | 🟡 Medium | **Recommended Fix** - May cause context loss |
| **sqlclosecheck** | 1 | c. Critical Bugs-Suggest Fix | 🟡 Medium | **Recommended Fix** - Resource leak risk |
**Fix Suggestion Example**:
```go
// ❌ Current code (issue detected by nilerr)
if err != nil {
return nil, nil // bug: returning nil error with nil value
}
// ✅ After fix
if err != nil {
return nil, err
}
| Linter | Issues | Category | Action | Notes | |--------|--------|----------|--------|-------| | exhaustruct | 49 | f. New Features-Defer | disable + TODO | Struct field completeness, non-critical | | testifylint | 8 | b. Code Style-Manual Confirm | disable + TODO | Test code style, can optimize later |
Would you like me to help fix the above "recommended fix" issues? Reply "fix" to start auto-fix.
| Linter | Category | Reason | |--------|----------|--------| | errcheck | c. Critical Bugs-Suggest Fix | 13 issues: unchecked errors | | gosec | c. Critical Bugs-Suggest Fix | 10 issues: security checks | | mnd | b. Code Style-Manual Confirm | 47 issues: magic numbers | | exhaustruct | f. New Features-Defer | 49 issues: new linter, too many issues | | testifylint | b. Code Style-Manual Confirm | 8 issues: new linter, test style |
| Linter | Config | Old Value | New Value | |--------|--------|-----------|-----------| | funlen | lines | 60 | 100 | | gocyclo | min-complexity | 15 | 25 |
.pb.go, .gen.go, .mock.go
## Notes
1. **Core Principle**: **Do not modify existing code**, only adjust configuration to make code pass lint
2. **Special Handling for New Linters**:
- For new linters with few issues (< 5) or critical issues (security/error handling), **provide fix suggestions**
- Users can choose whether to fix, AI will not automatically modify code
- This does not conflict with "do not modify existing code" principle, as these are "new rule" issues
3. **v2 Configuration Format**: Must add `version: 2`, use `linters.default` instead of `enable-all`
4. **Preserve Existing Configuration**: Keep all disable/exclude settings during migration
5. **Backup Before Upgrade**: Recommended to backup `.golangci.yml` configuration file
6. **Gradual Tightening**: Can gradually reduce settings thresholds later to improve code quality
## Related Resources
- [Official Installation Docs](https://golangci-lint.run/docs/welcome/install/local/)
- [Configuration Migration Guide](https://golangci-lint.run/docs/configuration/migrate/)
- [v2 Changes](https://golangci-lint.run/usage/v2/)
development
Quickly set up golangci-lint environment for Go projects. Auto-detect version, create config, integrate CI, generate smart ignore rules, ensure existing code passes safely.
development
Maintainer-only workflow for handling GitHub Secret Scanning alerts on OpenClaw. Use when Codex needs to triage, redact, clean up, and resolve secret leakage found in issue comments, issue bodies, PR comments, or other GitHub content.
development
Maintainer workflow for OpenClaw releases, prereleases, changelog release notes, and publish validation. Use when Codex needs to prepare or verify stable or beta release steps, align version naming, assemble release notes, check release auth requirements, or validate publish-time commands and artifacts.
development
Run, watch, debug, and extend OpenClaw QA testing with qa-lab and qa-channel. Use when Codex needs to execute the repo-backed QA suite, inspect live QA artifacts, debug failing scenarios, add new QA scenarios, or explain the OpenClaw QA workflow. Prefer the live OpenAI lane with regular openai/gpt-5.4 in fast mode; do not use gpt-5.4-pro or gpt-5.4-mini unless the user explicitly overrides that policy.