go mod download 必须在 go build 前显式执行,否则因模块缺失直接报错退出;ci 中需先 restore 缓存、再执行 go mod download、最后 save,且 goproxy 必须含 direct 以支持私有模块 fallback。

go mod download 必须在 build 前显式执行
GitHub Actions 中 go build 不会自动下载缺失模块——它直接报错退出,比如 cannot find module 或 no required module provides package。这不是网络问题,而是 Go 工具链的明确行为:依赖必须提前就位。
正确做法是在 go build 步骤前加一步:go mod download。CI 流水线里这步不能省,也不能指望 go build “顺带”完成。
- 加
-x参数可确认是否走代理:运行go mod download -x github.com/golang/example,输出里应出现GET https://goproxy.cn/...,而非proxy.golang.org或git clone - 若项目含私有模块(如
git.internal.company/foo),GOPROXY必须含direct,否则 fallback 失败,报 404 - 不要在
go mod download前执行go clean -modcache——这是人为清空缓存,等同于重下所有模块
GOPROXY 配置必须包含 direct 且生效
只设 GOPROXY=https://goproxy.cn 是危险的。Go 会把所有模块请求(包括私有域名)都发给该代理,而 goproxy.cn 不支持内网鉴权或 SSH,必然失败。
正确写法是用逗号分隔多个源:GOPROXY=https://goproxy.cn,direct。其中 direct 表示“代理查不到就自己连”,这是 fallback 的唯一可靠方式。
Go语言(Golang)1.26.0版本提供 Go 官方 Windows amd64 MSI 安装包下载入口,版本号 1.26.0,可用于旧项目维护、兼容性测试和指定版本开发环境配置。
- 验证是否生效:运行
go env GOPROXY,输出必须含direct;再试go list -m github.com/golang/example,无 curl 日志即命中缓存 - 国内慎用
https://proxy.golang.org:DNS 污染常见,超时不是配置错,而是根本连不上 - 环境变量必须被 shell 继承:仅
go env -w GOPROXY=...不够,要在 job 的env:下显式设置,或在每个run:步骤里用env:覆盖
actions/cache 必须缓存 $HOME/go/pkg/mod
actions/cache@v4 缓存 node_modules 或 ~/.cache/go-build 对模块下载无效。Go 模块缓存只存在 $GOPATH/pkg/mod(通常为 /home/runner/go/pkg/mod),不缓存它,每次都是全新下载。
缓存 key 必须稳定且精准,否则命中率归零:
- 路径必须写全:
/home/runner/go/pkg/mod,不能只写pkg/mod或漏掉/home/runner/go - key 推荐用
${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}:go.sum哈希比 Go 版本更敏感,依赖变更时自动失效,不变时复用 - 顺序不能错:先
restore,再go mod download,最后save;顺序反了会导致缓存写入失败 - Docker 构建中需挂载
--mount=type=cache,target=/root/go/pkg/mod,否则每次构建都是空缓存
golangci-lint 缓存容易被 go.mod 格式变动破坏
golangci-lint-action 的缓存键默认含 go.mod 的 SHA,但这个哈希对空白字符、换行、注释极其敏感。一次 go mod tidy 后多一个空行,缓存就全失效。
这不是 bug,是设计使然——但容易被忽略:
- 团队应约定提交前统一运行
go mod tidy,避免格式抖动 - 若用自定义配置文件(如
.golangci.yml),它的内容也应参与缓存键计算,官方 action 默认不包含,需手动拼进key -
cache-invalidation-interval设为 14 或 30 更实用,设为 0 无效,设太小(如 1)等于没缓存 - 缓存目录默认是
~/.cache/golangci-lint,若 CI 中未持久化该路径,每次 lint 都从头分析
$GOPATH/pkg/mod,构建走 $GOCACHE,lint 走自己的 ~/.cache/golangci-lint。三者互不共享,各自独立失效。混用或漏掉任一,加速效果就断在那个环节。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










