本地 goreleaser build --snapshot 成功不等于能发 GitHub Release;主因是 builds 未显式声明 goos/goarch 组合、GITHUB_TOKEN 权限不足(需 repo/delete_repo/workflow)、Windows 二进制缺 .exe 后缀。

本地 goreleaser build --snapshot 成功,不代表能发 GitHub Release;真正卡住的八成是 builds 配置没写全、GITHUB_TOKEN 权限不足,或 Windows 二进制缺 .exe 后缀。
builds 块必须显式列出所有 goos/goarch 组合
GoReleaser 不会自动做笛卡尔积。默认只写 goos: [linux, darwin, windows] 和 goarch: [amd64, arm64],它只编译你当前系统能跑的那个组合(比如 macOS 上只出 darwin/amd64),其余平台全漏。
- 正确做法是拆成多个
builds子项,每个明确指定一对goos和goarch - 常见组合包括:
linux/amd64、linux/arm64、darwin/amd64、darwin/arm64、windows/amd64、windows/386、windows/arm64 - ARM 架构(尤其是
armv7)要单独加,树莓派用户真会用到 - 记得统一加
env: [CGO_ENABLED=0],避免动态链接问题
archives.name_template 控制用户看到的文件名
用户点开 GitHub Release 下载的是 archives 打包后的归档(如 .zip 或 .tar.gz),不是 builds 直接输出的原始二进制。改 builds[].binary 只影响构建时生成的文件名,不影响最终压缩包内容或名字。
- 用
replacements把系统名转成用户习惯写法:darwin: macos、386: i386、amd64: x86_64 - Windows 下想让包内主程序带
.exe?在模板末尾加{{ if eq .Os "windows" }}.exe{{ end }} - 想统一输出
.zip?设format: zip,并确保name_template结尾有.zip - 推荐模板:
{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if eq .Os "windows" }}.exe{{ end }}.zip
GITHUB_TOKEN 权限和 builds.main 是两个高频失败点
goreleaser init 生成的配置几乎不能直接用。它默认找当前目录下的 main.go,但真实项目往往把入口放在 cmd/myapp/main.go;同时,CI 环境里 GITHUB_TOKEN 缺权限或根本没注入,也会直接 403。
立即学习“go语言免费学习笔记(深入)”;
- 必须手动改
builds[].main,例如:./cmd/myapp/main.go - 必须手动改
builds[].binary,尤其 Windows 要写成myapp.exe,否则 zip 包里文件没扩展名,双击打不开 -
GITHUB_TOKEN至少需要repo、delete_repo、workflow三项权限;CI 中建议用gh auth login --scopes repo,delete_repo,workflow重登验证 - CI 中检查是否生效:
echo $GITHUB_TOKEN | cut -c1-10,为空或太短就说明没配对
checksums 和 signature 不是可选项,而是发布底线
不生成 checksums.txt 或签名文件,下游用户就无法验证二进制是否被篡改。GoReleaser 默认开启 checksums,但容易被注释掉或忽略。
- 确认
checksums块没被注释,且name_template设为checksums.txt - 签名需配置 GPG 私钥,通过 CI secrets 注入(如
GORELEASER_GPG_KEY),别硬编码 - ARM 编译慢、体积大,可在 CI 中临时用
builds[].skip: true跳过,但本地测试务必跑一次全平台
最容易被忽略的是:builds 没拆开写全组合、Windows 二进制名没加 .exe、archives.name_template 和 builds.binary 混为一谈——这三个点错一个,Release 页面就看不到对应平台的下载项。


















