GitLab CI交付成败取决于.gitlab-ci.yml配置细节:test阶段需精准限定go test路径并加-short参数,build必须用多阶段Dockerfile启用BuildKit,deploy须按环境分离values文件、加--atomic--cleanup-on-fail,verify需业务级端到端检测而非仅healthz。

GitLab CI 不是“用来作为交付工具”的抽象概念,它就是一个执行流水线的调度器——真正完成交付的是你写的 .gitlab-ci.yml 里定义的命令。关键不是“用不用”,而是**哪些阶段必须有、哪些命令不能少、哪些配置一错就卡在 staging 环境半天不进 prod**。
test 阶段必须跑 go test,但别只跑 ./...
常见错误是写成 go test ./...,看似覆盖全项目,实则会把 internal/ 下未导出的包、deploy/ 下的 YAML 文件、甚至 vendor/(如果存在)全扫一遍,导致超时或误报失败。
- 推荐写法:
go test ./... -timeout 60s -short,加-short跳过耗时集成测试 - 单元测试应集中在
internal/handler和internal/service,避免测cmd/main.go或deploy/helm - 如果用了
golangci-lint,建议单独设 stage(如lint),别塞进test,否则 lint 失败会掩盖真实测试失败
build 阶段用多阶段 Dockerfile,别在 CI 里 go build 后直接 push 二进制
直接在 runner 上 go build -o app ./cmd 再打包上传,等于把构建环境耦合进 CI 流程:Go 版本、CGO_ENABLED、交叉编译目标都得手动对齐,且无法复用镜像层缓存。
- 必须用
Dockerfile多阶段构建:builder 阶段用golang:1.21-alpine编译,final 阶段用scratch或alpine:latest只放二进制 -
docker build命令里必须加--build-arg BUILDKIT=1启用 BuildKit,否则CACHE FROM在 GitLab shared runner 上大概率失效 - 镜像 tag 别硬写
:latest,统一用$CI_COMMIT_SHA或$CI_PIPELINE_ID,Helm 部署时靠这个做精确灰度
deploy-staging 阶段要触发 helm upgrade,但必须检查 values.yaml 是否被覆盖
很多团队把 values.yaml 放进 repo,CI 里直接 helm upgrade --install svc ./deploy/helm,结果 staging 和 prod 共用同一份 values,改一个字段全环境生效。
在 Go 中使用 google/wire 实现编译时依赖注入——wire.NewSet、wire.Build、wire.Bind(接口→实现)、wire.Struct、wire.Value、wire.Interface
- 正确做法:按环境拆
values-staging.yaml/values-prod.yaml,CI 中用--values ./deploy/helm/values-staging.yaml -
helm upgrade必须加--atomic --cleanup-on-fail,否则 deploy 失败后 release 会卡在 pending-upgrade 状态,后续再跑也起不来 - 别跳过
helm lint和helm template验证:CI 里加一步helm template ./deploy/helm --debug | head -20,能提前发现 YAML 缩进错误或模板变量缺失
verify 阶段不能只 ping /healthz,得验证业务逻辑是否真通
很多流水线在 deploy-staging 后只跑 curl -f http://svc.staging/healthz,返回 200 就认为 OK。但实际 service 可能连不上数据库、配置没注入、metrics endpoint 挂了——这些健康检查根本测不出来。
立即学习“go语言免费学习笔记(深入)”;
- 必须写轻量级端到端验证脚本(比如
evaluator/main.go),调真实 API 并断言返回字段(如GET /users/123返回{"id":123,"name":"test"}) - 脚本里用
context.WithTimeout控制总耗时,超时直接 fail pipeline,别让 verify 卡住整个流程 - verify 的 target URL 必须带 namespace 和 service name(如
http://user-svc.staging.svc.cluster.local),别用 Ingress 地址,避免 DNS 或 LB 故障干扰判断
gitlab-runner 装没装好,而是 helm upgrade 命令漏了 --atomic,或是 values.yaml 里一个缩进空格没对齐。CI 流水线越往后越不透明,问题往往藏在 staging 验证通过、prod 部署失败之间的那几行日志里。

















