关于 go-ci
go-ci 面向 Go 项目维护者,规划涵盖构建、vet 与 lint、竞态检测测试和漏洞扫描的 CI 流水线。内容还包括 GitHub Actions 配置、本地与 CI 检查对齐以及仓库安全实践。
主要功能
- 01CI 四项核心门禁
- 02GitHub Actions 工作流建议
- 03golangci-lint 配置
- 04竞态测试与覆盖率门禁
- 05安全扫描与依赖更新
适用场景
- 01搭建 Go CI 流水线
- 02使本地检查与 CI 保持一致
- 03添加竞态和覆盖率检查
- 04加固仓库自动化流程
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ eduardo-sl/ go-agent-skills --skill go-ci安装后在 Claude Code 中输入/go-ci确认已加载。
附带文件references/security-and-automation.md
详细介绍
Go CI
Go 流水线恰好有四道关卡:构建、vet/lint、运行竞态检测器的测试,以及漏洞扫描。其他一切都是优化。
详细参考资料按需加载:
references/security-and-automation.md— CodeQL 和 gosec SARIF、Dependabot 配置、SHA 固定、仓库加固、Trivy、AI 评审工作流。
只有在下方摘要不够时,才读取参考文件。
1. 基础 GitHub Actions 工作流
name: ci
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-go@v7
with:
go-version-file: go.mod # single source of truth
cache: true # caches module + build cache
- run: go build ./...
- run: go vet ./...
- run: go test -race -shuffle=on -coverprofile=coverage.out ./...
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-go@v7
with:
go-version-file: go.mod
- uses: golangci/golangci-lint-action@v9 # v7+ runs golangci-lint v2
with:
version: v2.6 # pin a minor; v2.6+ has `modernize`
vuln:
runs-on: ubuntu-latest
steps:
- uses: golang/govulncheck-action@v1
with:
go-version-file: go.mod
Action 的主要版本每年会更新数次。请将上面的版本视为一个快照,并让 Dependabot 的 github-actions 生态系统保持其最新状态,而不要手动编辑。
其中的关键决策:
go-version-file: go.mod— 绝不要在两个地方硬编码 Go 版本。- 在 setup-go 中启用
cache: true可处理模块和构建缓存;不要再为 Go 添加手动的actions/cache步骤。 -race -shuffle=on— 竞态和依赖顺序的测试应在 CI 中失败,而不是在生产环境中。permissions: contents: read— 默认遵循最小权限原则。- 将 lint 放在单独的任务中 — 这样可以快速失败,并与测试并行运行。
2. golangci-lint 配置
提交 .golangci.yml;未配置的 linter 只会制造噪声:
version: "2" # required: golangci-lint v2 rejects v1 files
linters:
default: standard # errcheck, govet, ineffassign, staticcheck, unused
enable:
- errorlint # %w misuse, == on errors
- gosec # security patterns
- revive # style, replaces golint
- misspell
exclusions:
rules:
- path: _test\.go
linters: [gosec] # test code may use weak randomness etc.
golangci-lint v2 将排除项从 issues.exclude-rules 移到了
linters.exclusions.rules,并将 version 键设为必填。v1 文件会加载失败,而 golangci-lint migrate 可原地转换文件。
从这组精简配置开始,并有意识地添加 linter。启用所有检查会产生数百条无人处理的问题。nolint 指令必须说明原因://nolint:gosec // G404: jitter, not crypto。
3. 构建矩阵——仅在发布时使用
strategy:
matrix:
go: [oldstable, stable] # the two releases the Go team supports
os: [ubuntu-latest, macos-latest, windows-latest]
库:测试两个受支持的 Go 版本。setup-go 会在运行时解析
stable/oldstable,因此矩阵不会过时。
部署在 Linux 上的服务:跳过操作系统矩阵 — 为永远不会发布的平台测试会使成本翻倍。交叉编译比模拟更便宜:
GOOS=windows go build ./... 可发现大多数可移植性问题。
4. 覆盖率关卡
- run: go test -race -coverprofile=coverage.out ./...
- name: enforce coverage floor
run: |
total=$(go tool cover -func=coverage.out | awk '/^total:/ {sub(/%/,"",$3); print $3}')
echo "coverage: ${total}%"
awk -v t="$total" 'BEGIN { exit (t < 70.0) }'
设置一个逐步提高的最低门槛,而不是容易被钻空子的目标。通过 //go:generate 生成的文件的构建标签或 grep 过滤器排除生成代码,而不是降低门槛。
5. Makefile — CI 的本地镜像
CI 必须运行开发者本地运行的内容。一个定义,两个调用方:
.PHONY: build lint test vuln ci
build:
go build ./...
lint:
golangci-lint run
test:
go test -race -shuffle=on -coverprofile=coverage.out ./...
vuln:
go tool govulncheck ./... # pinned via `go get -tool` (Go 1.24+)
ci: build lint test vuln
如果 CI 执行了 make ci 未执行的操作,开发者就只能在推送后才发现失败。两者应保持一致。
6. 加速规则
- 将 lint/test/vuln 拆分为并行任务(如 §1 所示)。
go test ./...已会在各软件包间并行运行;小型仓库不要拆分任务。- 带有构建标签的集成测试应放在单独的任务中,或按计划运行,而不是每次推送时运行:
go test -tags=integration ./...。 - 如果构建缓存总是未命中,请检查
go.sum是否作为缓存键的输入(setup-go 会处理),并确认任务不会修改它。
7. 安全关卡
除 govulncheck 外,还应使用 CodeQL(security-extended)和 gosec,并将 SARIF 上传到 Security 标签页;对构建的任何容器镜像运行 Trivy。先以 -no-fail 运行 gosec 来收集基线,然后让新发现的问题导致 PR 失败。
8. 依赖更新与 Action 固定
- 为
gomod和github-actions启用 Dependabot,每周更新一次,并将次要版本和补丁更新合并到一个 PR 中。主要版本更新应单独处理 — 需要阅读变更日志。 - 使用提交 SHA 固定第三方 Action,并在注释中注明版本;标签可能被改指向恶意代码,而 Dependabot 会更新 SHA 固定项。
9. 工作流与仓库加固
- 在默认只读权限的基础上,按作业设置权限。
- 不使用会检出并运行 fork 代码且提供密钥的
pull_request_target工作流。 - 分支保护:必需检查、代码审查、禁止强制推送。
- 加载了 go-code-review 技能的 AI 审查者可作为额外审查者,但绝不能成为能够自行批准的检查项。
第 7–9 节的代码片段:references/security-and-automation.md。
由标签触发的发布流程——GoReleaser、签名、SBOM、来源证明——由 go-build-release 技能负责。
验证清单
- 流水线包含全部四个关卡:构建、vet+lint、test -race、govulncheck
- Go 版本从 go.mod 获取(
go-version-file),而非重复声明 - 在工作流级别设置
permissions: contents: read - 测试使用
-race -shuffle=on运行 - 已提交包含精选 linter 集的
.golangci.yml - 每个
nolint都注明 linter 名称和原因 - 矩阵仅包含实际支持的版本和平台
- 强制执行覆盖率下限,并排除生成代码
make ci可在本地逐字节复现流水线- 集成测试通过标签隔离,不拖慢每次推送
- CodeQL/gosec 结果以 SARIF 格式上传;镜像在推送前扫描
- Dependabot 覆盖模块和操作;第三方操作按 SHA 固定
- 按作业设置权限;不使用密钥运行 fork 代码