Go项目CI需确保模块路径、工作目录和Go版本一致,避免静默失败;多module时go test -v ./仅测当前module;Windows交叉编译须加.exe后缀;GITHUB_TOKEN需显式设contents: write权限;标签触发用if: startsWith(github.ref, 'refs/tags/')。

Go 项目用 GitHub Actions 做 CI,只要环境配置对、测试命令写准、模块路径一致,基本不会翻车。关键不是“能不能跑”,而是“会不会漏掉静默失败的点”。
go test -v ./ 为什么有时不跑所有包?
这个命令看似覆盖全部子包,但实际行为取决于当前工作目录和 go.mod 路径。如果项目有多个 module(比如 cmd/ 和 internal/ 分属不同 module),go test -v ./ 只会测试当前 module 下的包。
- 确认当前 CI 工作目录是仓库根(默认就是),且
go.mod在该目录下 - 若含集成测试(依赖 DB、HTTP server 等),建议单独拆出 job,并加
if: github.event_name == 'push' && github.head_ref == 'main'控制触发时机 - 避免在测试步骤里手动加
go mod download:actions/setup-go 已隐式处理,冗余调用可能因缓存导致本地与 CI 行为不一致 - 需要覆盖率时,用
go test -coverprofile=coverage.out -covermode=count ./,别用atomic模式——它在并发测试中更安全,但部分覆盖率服务(如 Codecov)解析不稳定
交叉编译产物名不对,Windows 用户双击没反应
GitHub Actions runner 是 Linux,GOOS=windows GOARCH=amd64 go build 能生成可执行文件,但默认没扩展名。Windows 不认 myapp_Windows_x86_64 这种名字,双击直接无响应——这不是权限问题,是系统根本没把它当可执行文件。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 构建时显式加后缀:
GOOS=windows GOARCH=amd64 go build -o myapp.exe ./cmd/app - 若用
goreleaser,必须在.goreleaser.yml的archives块里设name_template,例如:"{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if eq .Os \"windows\" }}.exe{{ end }}" - 别依赖
builds[].binary字段改名,它只影响主二进制输出名,不影响最终打包进 release 的 archive 文件名 - 本地快速验证命名逻辑:运行
goreleaser build --snapshot,看dist/下生成的文件名是否符合预期
GITHUB_TOKEN 权限不足,Release 静默失败
${{ secrets.GITHUB_TOKEN }} 默认只有 contents: read,而创建 Release 至少需要 contents: write。更麻烦的是:私有仓库默认禁用写权限,且错误日志只报 403 Forbidden,不提示缺哪项。
立即学习“go语言免费学习笔记(深入)”;
- 必须手动进入仓库 Settings → Actions → General → “Workflow permissions”,改为 “Read and write permissions”
- 如果用了
goreleaser并推送到 GitHub Packages,还需勾选packages: write - 若 workflow 中启用了 OIDC(比如对接 AWS),还得额外开
id-token: write - 发布 job 必须加
permissions: contents: write显式声明,否则softprops/action-gh-release@v1或goreleaser会静默跳过 - 标签触发要用
if: startsWith(github.ref, 'refs/tags/'),别信github.event.head_commit.tag——它在 PR 合并时不可靠
最容易被忽略的其实是 Go 版本一致性:CI 用 actions/setup-go@v5 装了 1.22,但 go.mod 里写的是 go 1.19,某些 linter 或 goreleaser v2+ 会直接跳过构建,连 warning 都不打。

















