go模块发布核心卡点是module路径与仓库url一致、tag严格为v1.2.3格式并推送至远端、v2+版本go.mod中显式含/v2后缀,任一缺失将导致go get静默失败或unknown revision错误。

Go 模块发布不是“打个 tag 就完事”,核心卡点在三件事:module 路径是否与远端仓库 URL 一致、tag 名是否严格为 v1.2.3 格式且已推送到远端、v2+ 版本是否在 go.mod 中显式带 /v2 后缀。漏掉任一,下游 go get 就会静默失败或报 unknown revision。
module 路径写错,所有后续操作都白干
初始化时 go mod init 的参数必须和你最终托管代码的 Git 地址完全一致——包括大小写、子路径、有无 .git 后缀。比如仓库地址是 https://github.com/yourname/mylib,那必须用:
go mod init github.com/yourname/mylib
而不是 go mod init mylib、go mod init ./mylib 或 go mod init github.com/yourname/mylib.git。后者会导致别人 go get github.com/yourname/mylib 时拉不到正确版本,因为 Go 工具链只认 go.mod 里声明的路径,不自动补全或纠错。
- 改过一次
module路径,所有历史 tag 都失效——旧导入路径(如github.com/yourname/mylib)和新路径(如github.com/yourname/mylib/v2)被 Go 视为两个完全独立模块 - 私有仓库同理,比如
gitlab.company.com/team/utils,初始化就得写全,不能省略域名或用内部 IP - 验证方式:在空目录执行
go list -m -json github.com/yourname/mylib@v0.1.0,能返回 JSON 才算路径和 tag 同时生效
git tag 不是随便写个 v1.0 就行
Go 模块版本解析只认 Git 注解标签(annotated tag),且格式必须是 vMAJOR.MINOR.PATCH,开头的 v 是硬性要求,缺了就当不存在。
- 合法:
v1.0.0、v0.5.2、v2.1.0-rc1(预发布需加-pre参数才显示) - 非法:
1.0.0(缺v)、release-v1.0(含非数字字符)、v1.0(省略 PATCH)、v1.0.0-beta(应为v1.0.0-beta.1) - 必须用
git tag -a v1.0.0 -m "release"创建,再执行git push origin v1.0.0——别用git push --tags,它可能把本地测试 tag 也推上去 -
go list -m -versions github.com/yourname/mylib返回空?先检查远端有没有这个 tag:git ls-remote --tags origin | grep v1.0.0
v2+ 发布必须同步改 module 路径和 import
v2 不是“升级版本号”那么简单,它是模块路径语义变更:Go 强制要求 v2+ 的 go.mod 中 module 行末尾必须带 /v2,否则 go get 会报 invalid version: module contains a go.mod file, so major version must be compatible。
- 原
go.mod是module github.com/yourname/mylib→ 发 v2 时必须改为module github.com/yourname/mylib/v2 - 所有内部
import语句也要同步改成github.com/yourname/mylib/v2/xxx,Go 不做自动重写 - 用户代码从 v1 升级到 v2,必须把
import "github.com/yourname/mylib"改成import "github.com/yourname/mylib/v2",这是两个不同路径,无法兼容 - 不要试图用
replace在同一个仓库里“模拟”多版本——这仅对本地go build有效,go get时会被忽略
验证发布是否真正成功,别只信本地 git tag -l
本地能看到 tag,不代表别人能 go get 到。真正有效的验证是站在下游视角,用 Go 工具链直连远端检查。
- 在干净目录运行:
go list -m -json github.com/yourname/mylib@v1.0.0,能输出 JSON 才说明路径、tag、推送三者全对 - 再试:
go mod download github.com/yourname/mylib@v1.0.0,看是否进缓存、有无校验错误 - 私有仓库要额外检查:
GOPRIVATE是否覆盖对应域名,git clone该 URL 是否需 SSH 密钥或 token - 最容易被忽略的是:tag 必须打在包含有效
go.mod的 commit 上——如果那个 commit 里go.mod还没提交,或路径写错了,tag 就是无效的“空壳”
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











