golangci-lint仅识别module根目录下的.golangci.yml(小写、带点、yml后缀),多模块需各模块独立配置;推荐启用govet、errcheck、staticcheck、gosimple、unused、goconst;须排除vendor/pb/migrations等目录及_test.go/.gen.go文件;ci中需设timeout、启用缓存、限定working-directory并同步go环境。

配置文件名和位置必须严格匹配 .golangci.yml
很多人配了规则却没生效,根本原因就卡在这一步:golangci-lint **只认 .golangci.yml(小写、带点、yml 不是 yaml)**,且必须放在 go.mod 所在目录——也就是 module 根目录。不是项目根,不是 IDE 工作区根,更不继承父目录配置。
常见错误现象:
• 修改了 .golangci.yaml 或 golangci.yml,但 golangci-lint run 仍走默认规则
• 多 module 项目(如 monorepo)只在顶层放一个配置,结果 a/ 和 b/ 模块都用同一套规则,甚至报错找不到依赖
• IDE(如 GoLand)里没提示,重启也不管用——其实是插件还在读缓存的旧配置或根本没找到文件
- 实操建议:进 module 目录,执行
ls -a | grep golangci确认文件存在且拼写完全正确 - 多 module 项目,每个
go.mod目录下都要有独立的.golangci.yml - 改完配置后,务必手动运行
golangci-lint run验证;IDE 插件需手动刷新缓存或重启
别开全量 linter,优先启用这 6 个实用检查器
默认只跑 govet、errcheck 等约 10 个基础 linter,大量关键问题(比如重复字面量、圈复杂度、未使用变量)根本不会报。但盲目启用全部 50+ 个,又会导致:
• 扫描变慢(尤其含 gosec 或 goconst 的大项目)
• 误报率高(如 dupl 对模板代码敏感,lll 纯属风格争议)
• 团队协作成本陡增(比如 revive 的命名规则和现有 test 文件冲突)
- 推荐起步组合(兼顾深度与稳定):
govet、errcheck、staticcheck、gosimple、unused、goconst - 禁用高风险 linter:
dupl(阈值难调)、lll(行长限制)、stylecheck中的命名强约束(除非团队已统一规范) - 示例片段(写进
.golangci.yml):linters:<br> enable:<br> - govet<br> - errcheck<br> - staticcheck<br> - gosimple<br> - unused<br> - goconst<br> disable-all: true
run.skip-dirs 和 issues.exclude-rules 是性能与准确性的关键开关
不加路径过滤时,golangci-lint run 默认递归扫描整个工作目录,包括 vendor/、pb/(protobuf 生成代码)、migrations/、testdata/——这些目录要么无意义检查,要么直接拖慢速度、触发误报。
- 必须排除的目录:
vendor、third_party、generated、pb、migrations - 建议排除的文件模式:
_test\.go$(避免对测试文件施加生产级命名/结构要求)、\.gen\.go$(忽略所有生成代码) - 配置示例:
run:<br> skip-dirs:<br> - vendor<br> - pb<br> - migrations<br>issues:<br> exclude-rules:<br> - path: "_test\.go"<br> - path: "\.gen\.go$"
CI 中用 golangci-lint-action 要绕过三个典型陷阱
GitHub Actions 里跑 lint 最容易出问题的地方不在规则本身,而在环境适配和缓存逻辑:
-
超时失败:日志停在
loading cache或报context deadline exceeded→ 必须显式设timeout,例如args: --timeout=5m -
缓存失效:没配缓存策略时,每次重装依赖+重编译 linter,启动耗时 30 秒起 → 启用
skip-cache: false并设cache-invalidation-interval: 7 -
PR 检查不准:默认检查全项目,历史问题刷屏 → 开
only-new-issues: true,配合github-token自动比对 diff - 多 module 场景下,必须用
working-directory指向具体模块,例如working-directory: ./services/auth
最常被忽略的一点:本地能跑通 ≠ CI 能跑通。Go 版本、GO111MODULE 环境变量、模块下载模式(modules-download-mode: readonly)在 CI 中必须显式对齐,否则会静默跳过某些 type-check 类 linter。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











