不是必须打v0.0.0标签,但需确保module路径稳定且go.mod已提交;v1.0.0发布前module路径须含/v1后缀,tag须推送至远端,否则其他项目无法正常go get。

go mod init 后必须先打 v0.0.0 标签?
不是必须,但不打会踩坑。Go 模块版本解析依赖 Git 标签,v0.0.0 这类“占位标签”本身没意义,真正关键的是:首次发布前,模块路径必须稳定,且 go.mod 文件已提交到主分支。
- 如果你还没打任何标签,
go list -m -versions会只显示(devel),其他模块无法正常go get -
v0.0.0不是规范要求,但很多 CI/CD 工具(如 goreleaser)默认从v0.1.0或v1.0.0开始识别正式发布,跳过v0.x可能导致版本推断失败 - 真正要做的:确保
go.mod中的 module 路径和你最终想发布的域名/仓库地址完全一致(比如github.com/user/repo),改错一次,后续所有标签都会失效
发布 v1.0.0 前必须删掉所有 v0.x 标签?
不用删,但得理解语义版本规则对 Go 模块的实际约束力——Go 不强制校验兼容性,只按字符串规则排序和解析。
- Go 的
go get默认取 latest tagged version,如果存在v0.9.0和v1.0.0,它会选v1.0.0;但如果只有v0.9.0,它不会自动升级到未发布的v1.0.0 -
v0.x和v1.x在 Go 模块中属于不同 major 版本路径:v0 不需要/v0后缀,v1 必须用/v1(例如github.com/user/repo/v1),否则其他项目go get时会报invalid version: module contains a go.mod file, so major version must be compatible - 错误做法:直接把
go.mod中的 module 改成github.com/user/repo/v1然后打v1.0.0标签——这会导致旧导入路径(github.com/user/repo)和新路径(github.com/user/repo/v1)被视为两个不同模块
打标签时 git tag -a v1.0.0 -m "release" 就够了吗?
够了,但容易漏掉两个硬性前提:tag 必须指向含有效 go.mod 的 commit,且该 commit 必须已 push 到远端。
- 常见错误:本地打了
v1.0.0,但没运行git push origin v1.0.0,其他开发者执行go get github.com/user/repo@v1.0.0会报unrecognized import path或unknown revision v1.0.0 - Go 代理(如 proxy.golang.org)缓存的是 tag 对应的 commit hash,不是 tag 名字本身;如果 tag 被 force push 或删除,已缓存的版本仍可用,但新请求会失败
- 建议加一步验证:
go list -m -json github.com/user/repo@v1.0.0,输出里有Version字段且不为(devel)才算成功
为什么别人 go get 后还是拉到 v0.x 而不是 v1.0.0?
大概率是他们本地缓存或 GOPROXY 拿到了旧版本索引,或者你的模块路径没按 v1 规则更新。
立即学习“go语言免费学习笔记(深入)”;
- 检查对方是否显式指定了版本:
go get github.com/user/repo@v0.5.0会固定拉那个版本,和你有没有发 v1 无关 - 如果他们用
go get github.com/user/repo(无 @),Go 会查index.golang.org或你配置的 GOPROXY,而该索引更新有延迟(通常几分钟到几小时);可临时加-u=patch强制刷新:go get -u=patch github.com/user/repo - 最隐蔽的坑:你发布了
v1.0.0,但go.mod里写的是module github.com/user/repo(没/v1),这时 Go 会拒绝解析为 v1 模块,报错信息通常是malformed module path或major version mismatch
路径后缀、tag 推送、GOPROXY 缓存——这三个点只要一个没对上,v1 就像没发过一样。尤其 /v1 是硬编码进导入路径的,改 module 名不是改个配置的事,是改所有 import 语句的事。










