go module 必须打形如 v1.0.0 的小写 v 开头语义化版本 tag,主版本≥v2时 module 路径需加 /v2,推送需 git push origin v1.0.0,且 tag 必须在 default branch 可达。

怎么给 Go module 打 tag 才能被别人 go get 正确识别
Go module 的版本完全依赖 Git tag,不是靠 go.mod 里写的版本号。如果你打的是 v1.0、1.0.0 或 release/v1.0 这类 tag,go get 会直接失败或降级到 latest commit —— 它只认形如 v1.0.0、v2.3.1-beta.2 的语义化版本 tag。
- 必须以小写
v开头,后面紧跟语义化版本(v1.2.3),不能省略v - 预发布版本要带连字符,比如
v1.0.0-alpha.1,不是v1.0.0alpha1 - 如果模块主版本 ≥ v2,
go.mod文件里的 module 路径末尾必须加上/v2(如github.com/user/repo/v2),否则go get会拒绝解析 v2+ tag - tag 推送前务必确认当前 commit 已更新
go.mod中的版本注释(非必需但强烈建议)和实际代码兼容性
GitHub 上 push tag 的正确命令顺序
很多人 git tag v1.0.0 && git push 后发现 GitHub 没显示 tag,或者 CI 拉不到新版本 —— 因为默认 git push 不推 tag。
- 打完 tag 后,必须显式推送:
git push origin v1.0.0(推单个)或git push origin --tags(推全部,慎用,可能误推旧草稿 tag) - 如果本地 tag 名和远程已存在冲突(比如重打了同名 tag),需加
--force:git push --force origin v1.0.0,但要注意这会破坏其他协作者的本地引用 - GitHub Actions 等 CI 场景下,若用
GITHUB_TOKEN推送,需确保 workflow 有permissions: contents: write,否则git push静默失败
go list -m -versions 查不到你刚推的 tag?检查这三处
执行 go list -m -versions github.com/user/repo 返回空或旧版本,不代表 tag 没生效,而是 proxy 或本地缓存卡住了。
- Go 默认走
proxy.golang.org,它同步 tag 有延迟(通常几分钟,极端情况达 1 小时),可临时绕过:GO_PROXY=direct go list -m -versions github.com/user/repo - 本地模块缓存可能残留旧记录:
go clean -modcache再试(注意这会清空所有下载的 module) - 确认 tag 对应的 commit 在 default branch(通常是
main)上可达 —— 如果 tag 打在孤立分支或已 rebase 删除的提交上,go工具链会跳过该 tag
私有仓库或 GitHub Enterprise 怎么让 go get 认出你的 module
公开 GitHub 仓库默认可用,但私有 repo、GHE 或自建 Git 服务需要额外声明,否则 go get 会报 unknown revision 或 404。
立即学习“go语言免费学习笔记(深入)”;
- 在项目根目录放
.netrc(Linux/macOS)或_netrc(Windows),填入账号凭据,再配git config --global url."https://token:x-oauth-basic@github.com/".insteadOf "https://github.com/" - 更推荐方式:用
GOPRIVATE环境变量告诉 Go 哪些域名不走 proxy,例如GOPRIVATE=github.com/my-org/*,然后确保 Git 能正常 clone(SSH 或 HTTPS 凭据就绪) - 如果是 GHE,还需在
go env -w GOPROXY=https://proxy.golang.org,direct后追加GONOSUMDB=*.my-ghe-domain.com,避免 checksum database 拒绝私有域名
tag 和 module 路径的耦合比看起来 tight 得多,改错一个字母(比如 v1.0.0 写成 V1.0.0)就会让整个版本不可见,而且错误提示极其安静 —— 它不会报错,只是默默回退到 pseudo-version。










