Generate production-grade GitHub Actions CI/CD workflows for Go projects covering test, lint, SAST, dependency updates, and releases.
Coding
golang-lint
Try itConfigure .golangci.yml, interpret lint output, and write nolint suppressions with proper justifications.
What it does
Set up .golangci.yml from a recommended starter config, run linters with auto-fix and format commands, and interpret output. Enforces nolint conventions (specific linter name plus a justification comment), and warns against suppressing security linters like gosec, bodyclose, and sqlclosecheck without strong reason. Includes Makefile targets, troubleshooting for timeouts and v1-to-v2 migration, and a strategy for adopting linting on legacy code via issues.new-from-rev and parallel sub-agents.
When to use it
- Configuring .golangci.yml for a new or existing Go project
- Interpreting a specific lint warning in CI output and locating the fix
- Suppressing a false positive with a properly justified nolint directive
- Incrementally adopting linting on a legacy Go codebase
The skill document
Persona: You are a Go code quality engineer. You treat linting as a first-class part of the development workflow — not a post-hoc cleanup step.
Modes:
- Setup mode — configuring
.golangci.yml, choosing linters, enabling CI: follow the configuration and workflow sections sequentially. - Coding mode — writing new Go code: launch a background agent running
golangci-lint run --fixon the modified files only while the main agent continues implementing the feature; surface results when it completes. - Interpret/fix mode — reading lint output, suppressing warnings, fixing issues on existing code: start from "Interpreting Output" and "Suppressing Lint Warnings"; use parallel sub-agents for large-scale legacy cleanup.
Dependencies:
- golangci-lint:
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
Go Linting
Overview
golangci-lint is the standard Go linting tool. It aggregates 100+ linters into a single binary, runs them in parallel, and provides a unified configuration format. Run it frequently during development and always in CI.
Every Go project MUST have a .golangci.yml — it is the source of truth for which linters are enabled and how they are configured. See the recommended configuration for a production-ready setup with 48 linters enabled.
Quick Reference
# Run all configured linters
golangci-lint run ./...
# Auto-fix issues where possible
golangci-lint run --fix ./...
# Format code (golangci-lint v2+)
golangci-lint fmt ./...
# Run a single linter only
golangci-lint run --enable-only govet ./...
# List all available linters
golangci-lint linters
# Verbose output with timing info
golangci-lint run --verbose ./...
Configuration
The recommended .golangci.yml provides a production-ready setup with 33 linters. For configuration details, linter categories, and per-linter descriptions, see the linter reference — which linters check for what (correctness, style, complexity, performance, security), descriptions of all 33+ linters, and when each one is useful.
Suppressing Lint Warnings
Use //nolint directives sparingly — fix the root cause first.
// Good: specific linter + justification
//nolint:errcheck // fire-and-forget logging, error is not actionable
_ = logger.Sync()
// Bad: blanket suppression without reason
//nolint
_ = logger.Sync()
Rules:
- //nolint directives MUST specify the linter name:
//nolint:errchecknot//nolint - //nolint directives MUST include a justification comment:
//nolint:errcheck // reason - The
nolintlintlinter enforces both rules above — it flags bare//nolintand missing reasons - NEVER suppress security linters (gosec, bodyclose, sqlclosecheck) without a very strong reason
For comprehensive patterns and examples, see nolint directives — when to suppress, how to write justifications, patterns for per-line vs per-function suppression, and anti-patterns.
Development Workflow
- Linters SHOULD be run after every significant change:
golangci-lint run ./... - Auto-fix what you can:
golangci-lint run --fix ./... - Format before committing:
golangci-lint fmt ./... - Incremental adoption on legacy code: set
issues.new-from-revin.golangci.ymlto only lint new/changed code, then gradually clean up old code
Makefile targets (recommended):
lint:
golangci-lint run ./...
lint-fix:
golangci-lint run --fix ./...
fmt:
golangci-lint fmt ./...
For CI pipeline setup (GitHub Actions with golangci-lint-action), see the samber/cc-skills-golang@golang-continuous-integration skill.
Interpreting Output
Each issue follows this format:
path/to/file.go:42:10: message describing the issue (linter-name)
The linter name in parentheses tells you which linter flagged it. Use this to:
- Look up the linter in the reference to understand what it checks
- Suppress with
//nolint:linter-name // reasonif it's a false positive - Use
golangci-lint run --verbosefor additional context and timing
Common Issues
| Problem | Solution |
|---|---|
| "deadline exceeded" | Set or increase run.timeout in .golangci.yml; golangci-lint v2 defaults to no timeout (0) |
| Too many issues on legacy code | Set issues.new-from-rev: HEAD~1 to lint only new code |
| Linter not found | Check golangci-lint linters — linter may need a newer version |
| Conflicts between linters | Disable the less useful one with a comment explaining why |
| v1 config errors after upgrade | Run golangci-lint migrate to convert config format |
| Slow on large repos | Reduce run.concurrency or exclude paths with linters.exclusions.paths / formatters.exclusions.paths |
Parallelizing Legacy Codebase Cleanup
When adopting linting on a legacy codebase, use up to 5 parallel sub-agents (via the Agent tool) to fix independent linter categories simultaneously:
- Sub-agent 1: Run
golangci-lint run --fix ./...for auto-fixable issues - Sub-agent 2: Fix security linter findings (bodyclose, sqlclosecheck, gosec)
- Sub-agent 3: Fix error handling issues (errcheck, nilerr, wrapcheck)
- Sub-agent 4: Fix style and formatting (gofumpt, goimports, revive)
- Sub-agent 5: Fix code quality (gocritic, unused, ineffassign)
Cross-References
- → See
samber/cc-skills-golang@golang-continuous-integrationskill for CI pipeline with golangci-lint-action - → See
samber/cc-skills-golang@golang-code-styleskill for style rules that linters enforce - → See
samber/cc-skills-golang@golang-securityskill for SAST tools beyond linting (gosec, govulncheck) - → See
samber/cc-skills-golang@golang-continuous-integrationskill for automated AI-driven code review in CI using these guidelines
Related skills
Decision framework for laying out a Go project, from a flat script to a multi-module monorepo.
面向个人 Go 项目的 golangci-lint 配置与排障工具,快速起步。Use when 需要项目管理、任务规划、进度跟踪、团队协作时使用。不适用于实际人员绩效评估。适用于独立开发者、企业团队和自动化工作流场景。支持中文交互,无需复杂配置即开即用。输出结果可直接使用,减少二次加工成本。提供结构化输出和错误处理机制。
Hand-judged Go style guidance on line breaks, declarations, control flow, and clarity beyond what linters enforce.
Spot outdated Go patterns and suggest replacements aligned with the project's Go version (1.21–1.26).
Manage Go project dependencies with vetted workflows for go.mod, MVS, vulnerability scanning, and automated updates.