必须同时缓存$HOME/go/pkg/mod和~/.cache/go-build,并用go.mod哈希作cache key;GOPROXY需在每个run块显式注入,私有模块须配GOPRIVATE与,direct成对生效。

go mod download 在 CI 中反复拉取,根本不是网速问题
CI 流程里 go mod download 每次都从零开始下载,通常不是代理慢,而是本地模块缓存没被复用。Go 默认把模块存在 $GOPATH/pkg/mod,但多数 CI 配置只缓存 ~/.cache/go-build(构建缓存),漏掉这个目录就等于放弃所有模块复用。
- GitHub Actions 必须同时缓存两个路径:
~/.cache/go-build和$HOME/go/pkg/mod - GitLab CI 要在
cache:key:里显式包含go/pkg/mod子路径,不能只写go/ - 缓存 key 建议绑定
go.mod文件哈希,避免不同分支共用缓存导致版本错乱 - 禁止在 job 开头执行
go clean -modcache—— 这是人为清空缓存的最常见操作
GOPROXY 设置在 CI 中“看似生效实则失效”的典型场景
你在本地跑 go env -w GOPROXY=https://goproxy.cn,direct 成功了,但 CI 日志里仍出现 GET https://proxy.golang.org/...,说明子进程根本没读到该值。这不是配置失败,而是环境变量未注入到 CI 的执行上下文。
- GitHub Actions:必须在
steps:下每个run:块里加env:显式传入,或用setup-goaction 的cache: true自动处理 - GitLab CI:不能只靠
variables:,要确保 shell 启动方式为 login shell(如before_script: ["source /etc/profile"]),否则go env读不到全局设置 - 某些自托管 runner 若以 systemd 服务运行,需在 service 文件里用
Environment=注入GOPROXY,否则继承的是系统级空值
私有模块拉取失败时,,direct 和 GOPRIVATE 必须成对出现
只要项目 import 了公司内网 Git 地址(如 git.internal.company.com/libs/log),而 GOPROXY 里没配 ,direct 或漏设 GOPRIVATE,就会卡在 verifying ...: checksum mismatch 或直接 404。这不是权限问题,是 Go 强制校验逻辑导致的 fallback 失败。
-
GOPROXY=https://goproxy.cn,direct中的,direct不可省略——它告诉 Go:“匹配GOPRIVATE的模块,别走代理,直连” -
GOPRIVATE必须覆盖全部私有域名前缀,例如git.internal.company.com/*,不能只写git.internal.company.com(末尾通配符缺失) - 多个域名用逗号分隔,如
git.internal.company.com/*,github.company.com/* - CI 中建议用
go env -w GOPRIVATE=...写入,比 shellexport更可靠(尤其对go install类命令)
go.sum 校验失败不是换源能解决的,得先判断是缓存污染还是代理透传异常
CI 报 checksum mismatch,第一反应不该是换 GOPROXY,而应检查 go.sum 是否与当前 go.mod 一致、以及代理是否正确透传官方 sum.golang.org 记录。goproxy.cn 和阿里云镜像都支持透传,但某些自建代理若配置了 GOINSECURE 或跳过校验,会返回伪造哈希。
- 先运行
go mod verify看是否本地已损坏;若失败,再执行go clean -modcache清空后重试 - 临时调试可用
go env -w GOSUMDB=off,但上线前必须关掉——否则失去依赖完整性保护 - CI 中若用
go mod tidy自动生成go.sum,务必确保它和go.mod一起提交,否则下次构建会因校验不通过中断
go mod download 就会退化成裸连境外源,超时重试三次后才报错。

















