根本原因是ci未复用gomodcache且goproxy配置不稳,导致重复下载;必须提交并实时更新go.mod/go.sum,配置goproxy+缓存,内网环境须启用vendor并提交。

为什么go build在CI里总在重复拉依赖
根本原因不是Go本身慢,而是每次构建都从头下载模块——go.mod没变,但GOMODCACHE没复用,GOPROXY又没配稳,结果CI机器反复走公网、重试、超时。本地能跑,CI卡住,八成是这个环节断了链。
必须提交go.mod和go.sum,且确保它们实时更新
go.mod和go.sum不是“可选配置”,是Go模块的锁定文件。CI环境不认你本地的缓存,只信这两个文件里的哈希与版本。
- 每次执行
go get或go mod tidy后,立刻git add go.mod go.sum && git commit,别跳过 - 如果CI报错类似
checksum mismatch for github.com/some/pkg,说明go.sum没提交或被手动改过,回退并重新go mod tidy -v - 禁止在CI脚本里加
go mod download——它会绕过go.sum校验,引入不可控版本
用GOPROXY + 缓存组合,把网络开销压到最低
单靠GOPROXY=https://proxy.golang.org不够稳定,尤其在CI服务器出口受限或国内访问慢时。真正有效的是代理+本地缓存双保险。
- 统一设置
GOPROXY=https://goproxy.cn,direct(国内推荐)或自建http://your-internal-proxy:8080,避免直连GitHub - 在CI配置中显式挂载
GOMODCACHE路径为缓存目录,例如GitHub Actions里:steps:<br> - uses: actions/cache@v4<br> with:<br> path: ~/go/pkg/mod<br> key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - 关键点:
key必须含go.sum哈希,否则依赖没变也刷新缓存,等于白配
内网或离线环境:vendor不是备选,是刚需
当CI节点完全无法出网(比如金融、军工类内网),go mod vendor不是权宜之计,而是唯一可靠路径。
- 运行
go mod vendor生成vendor/目录后,所有go build命令自动优先读取它,不发任何网络请求 - CI脚本里加一句
go env -w GO111MODULE=on && go env -w GOPROXY=off,彻底关掉模块远程行为 - 注意:
vendor目录要提交进Git,且每次go mod tidy后需重新go mod vendor并提交——漏掉这点,CI就找不到包
最常被忽略的其实是缓存键的设计:用go.sum哈希做key,而不是用分支名或时间戳。依赖没动,就不该重下;一动,就必须全刷。这事关CI是否真提速,而不是看起来在跑。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











