Go test 在 GitHub Actions 失败主因是环境未对齐:需用 actions/setup-go@v4 显式安装 Go、启用 Go modules(go mod init + tidy)、设 GO111MODULE=on、避免手动 cd 子目录;构建时应禁用 CGO、指定 GOOS/GOARCH、加 -ldflags="-s -w";缓存 key 必须基于 go.sum 哈希;部署宜用制品上传而非直连 SSH。

Go test 在 GitHub Actions 里跑不起来?先检查 go-version 和模块初始化
最常见现象是 go test 报 no Go files in current directory 或 cannot find package,本质不是代码问题,而是环境没对齐。
GitHub Actions 默认 Ubuntu runner 不预装 Go,也不能靠系统自带版本——必须显式用 actions/setup-go@v4 安装;同时 Go modules 必须启用,否则依赖解析会 fallback 到旧的 GOPATH 模式。
- 在
steps中第一件事就是用actions/setup-go@v4,go-version推荐写'1.23.x'(语义化匹配),别硬写'1.23.0' - 确保项目根目录存在
go.mod;如果还没初始化,CI 里go mod init不够,得补上go mod tidy拉真实依赖 - 显式加
env: { GO111MODULE: on },尤其对 Go -
actions/checkout@v4后别手动cd子目录,否则go test ./会找不到模块;真要测子包,用working-directory参数或直接写路径如go test ./pkg/...
go build 失败或产物无法运行?关键看 CGO_ENABLED 和 GOOS/GOARCH
本地能编译、CI 构建成功、但上传到服务器后执行报 exec format error 或直接 panic,90% 是平台和链接问题。
GitHub Actions 默认 runner 是 Linux x86_64,但如果你的部署目标是 CentOS、Alpine 或 Windows,不约束构建参数就会出事。CGO 更是隐形雷区:没关它,go build 会静默依赖系统 gcc,而 runner 上压根没装。
- 对外发布服务二进制,一律加
CGO_ENABLED=0,避免动态链接和系统工具链依赖 - 明确指定
GOOS和GOARCH,比如GOOS=linux GOARCH=amd64 go build -o bin/app .;别依赖go env输出——CI 环境下它可能还是 darwin - 加
-ldflags="-s -w"去掉调试信息和符号表,体积通常能减 30%+,也少被逆向 - 如果项目真要调 C 库(比如 SQLite、OpenSSL),就别交叉编译,改用
strategy.matrix分发到对应 OS runner(如runs-on: ubuntu-latestvsmacos-latest)
缓存 go.mod 下载慢?key 必须基于 go.sum 哈希
很多人加了 actions/cache@v4 却发现每次还是重下模块,耗时 40–90 秒——缓存根本没命中。
|Git删除了文件,但还会在Git 仓库历史中遗留。 - 想要从 Git 历史移除敏感信息(密码、密钥、token、私钥) - 想要删除意外提交的大文件 - 想要重写 Git 历史、移除特定文件的所有痕迹 - 提到 "force push"、"重写 commit 历史" - 需要从所有分支、所有 tag 中删除某个文件
根本原因是 key 写错了:go.mod 可能不变,但 go.sum 里间接依赖的校验和变了,模块树实际已不同。只按 Go 版本或时间戳设 key 更不准。
- 缓存路径固定写
~/go/pkg/mod(不是${{ env.HOME }}/go/pkg/mod,后者在部分 runner 上为空) - key 推荐格式:
${{ runner.os }}-go-${{ hashFiles('**/go.sum') }};**/go.sum能覆盖多模块子项目 - 顺序不能错:必须在
go mod download之前restore,之后save;否则缓存写入失败,下次还是空跑 - 不用
actions/cache也可用官方封装的gomod-cacheaction,底层一样但 key 构造更鲁棒
自动部署到服务器?别让 runner 直接 ssh,优先走制品上传 + 手动触发
直接在 workflow 里用 ssh-action 或 scp-action 部署,看着方便,实则埋了三个坑:凭据硬编码风险、runner 无状态导致部署状态不可追溯、失败后 rollback 困难。
更稳的做法是把构建产物当“制品”上传,再由运维或另一套流程拉取部署。若真要 CI 直连,至少守住安全底线。
- 构建产物用
actions/upload-artifact@v4上传,名字带${{ github.sha }}或${{ github.event.head_commit.tag_name }},便于回溯 - 部署步骤必须用
secrets注入 SSH 私钥或 token,绝不能明文写密码;私钥建议转成 base64 后存 secret,再在 job 里 decode - 远程执行脚本前,务必
cd到目标目录,否则.env、配置文件路径全错——这是 80% 的启动失败原因 - 用
nohup或systemd启动服务,别让 ssh-action 阻塞 workflow;否则超时失败,但进程已在后台跑着,形成“幽灵实例”
真正容易被忽略的点是:**测试和构建不该混在一个 job 里跑 race 检测和交叉编译**。前者吃内存,后者要清环境,强行合并会导致缓存污染、OOM 或产物覆盖。拆成独立 job,用 artifact 传递二进制,才是稳定可维护的起点。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










