写在前面
Go 生态里没有 npm registry / Maven Central 这种"集中仓库"——Go 模块直接通过 git 仓库地址拉取:
| |
但有一个东西扮演了"官方文档站"的角色——pkg.go.dev。它不存代码,只存文档——从你的 Go 源码自动生成。
如果你写了一个 Go 库想让人用,go get 能拉到不代表你"发布了"——pkg.go.dev 上有完整文档、版本列表、示例代码、依赖图,才是 Go 生态意义上的"发布"。
本文用我自己的 go-fsm 作为例子,把发布流程、文档规范、版本管理讲清楚。
一、pkg.go.dev 是什么
它是 Google 维护的 Go 模块文档中心:
- 自动从 GitHub / GitLab 拉取公开 Go 模块
- 解析源码生成 HTML 文档
- 显示版本列表、license、依赖图、被引用数
- 支持搜索、跳转、链接到源码
你不需要"提交"什么——只要模块能被 go get,pkg.go.dev 就会自动收录。
二、最小可发布的 Go 模块
1. 仓库结构
| |
2. go.mod
| |
module 名必须是仓库的 import path——pkg.go.dev 通过这个找到对应的 git 仓库。
3. doc.go:包级文档
| |
doc.go 里的 package 注释会成为 pkg.go.dev 主页的描述——它是用户对你库的第一印象。
4. README.md
pkg.go.dev 会同时展示 README 与包级 doc——README 显示在首页 Overview 区,包级 doc 显示在 Documentation 区。两者各司其职:README 面向 GitHub / pkg.go.dev 访客做项目介绍,doc.go 面向 godoc / IDE 跳转做 API 文档。建议把 GitHub 风格的徽章、功能 GIF、安装命令放 README,把 API 用法和 example 放 doc.go。
三、文档规范:让 godoc 漂亮
pkg.go.dev 的文档完全从 Go 源码注释生成——注释规范决定文档质量。
1. 每个导出符号都要有注释
| |
注释必须以符号名开头——这是 godoc 的强约定。
2. 多行注释
| |
空行分段,每段一个意思。
3. 列表
| |
注意——列表项前要有 4 空格缩进,pkg.go.dev 才会渲染成 bullet。
4. 可执行示例
example_*.go 文件里的 Example* 函数会自动出现在 pkg.go.dev:
| |
// Output: ... 是 Go 测试框架的语法——它既验证示例正确性,也是文档。
5. 标题(Go 1.19+)
| |
# 在注释里被识别为标题——pkg.go.dev 会渲染成大标题、生成目录。
四、版本管理:发布正式版本
1. 用 git tag 发布
| |
tag 必须是 vX.Y.Z 格式——Go modules 强制语义化版本。
2. 让 pkg.go.dev 收录新版本
打 tag 后,第一次访问 https://pkg.go.dev/github.com/lingcoder/go-fsm@v1.0.0 会触发proxy.golang.org 抓取——几秒后页面就有了。
或者用:
| |
也会触发同样的抓取。
3. v2+ 的特殊规则
重要:v2 及以上版本要在 module path 里加版本号:
| |
发布 v2 时:
| |
并打 tag v2.0.0。这是 Go 1.13 之后的强制规则——强迫"breaking change 必显式"。
五、license 文件:影响排名
pkg.go.dev 会显示模块的 license——有 license 的模块在搜索结果里更靠前。最常用:
- MIT —— 最宽松,工业首选
- Apache 2.0 —— 带专利授权条款,大公司喜欢
- BSD-3-Clause —— 简单、宽松
把对应的 LICENSE 文件放仓库根目录就行——pkg.go.dev 自动识别。
没 license 的代码 法律上等于"All rights reserved" ——别人不能用。开源前一定要加。
六、CI 集成:自动化发布
GitHub Actions 自动测试 + 发版:
| |
最后一步主动告诉 proxy.golang.org 拉取——比等用户访问快。
七、提高搜索排名
pkg.go.dev 的搜索排名考虑:
- 被 import 数量——其他 Go 模块依赖你的越多,排名越高
- license 是否存在
- 文档完整度——所有导出符号都有注释
- 版本稳定——是否打过 v1+ tag
- README / doc.go 内容——关键词是否覆盖搜索词
策略:
- 取好搜的名字(关键词命中度高)
- 早发 v1.0.0——pkg.go.dev 把 0.x 版本视为不稳定
- 写好 doc.go——是搜索引擎的主要食粮
- 写 example——示例丰富的库更受欢迎
八、常见问题
1. 推了 tag 但 pkg.go.dev 没显示
主动触发抓取:
| |
或访问一次 https://pkg.go.dev/github.com/your/repo@v1.0.0。
2. README 里的图片不显示
pkg.go.dev 会渲染 README,但不加载相对路径的本地图片—— 这种引用在 pkg.go.dev 上看不到。要让图片正常显示:
- 用 GitHub raw 的绝对 URL:
 - 或者把图片放在 GitHub Pages / 图床上引用
API 文档建议同时维护 README(项目介绍)和 doc.go(API 用法)——两者会分别在 Overview 区和 Documentation 区展示,互不替代。
3. 私有仓库怎么办
私有 module 不会在 pkg.go.dev 出现。要内部 doc:
- 自托管
godoc -http=:6060 - 公司内部用
pkgsite自建
4. 删除已发布版本
不能删除。一旦 tag 发布到 proxy.golang.org,会被永久缓存——这是 Go modules 的"checksum 不可变"承诺。
发现版本有 bug:
- 标记 retract(go.mod 里加
retract v1.0.5) - 立刻发新版本 v1.0.6 修复
| |
retracted 版本仍能解析,但用户用 go get 时会得到警告。
5. examples 怎么组织
- 简单示例 →
example_test.go(pkg.go.dev 显示) - 完整 demo →
examples/目录(GitHub 显示但 pkg.go.dev 不显示——所以 doc.go 里指向)
九、一份发布前 Checklist
发版前对照检查:
- go.mod 的 module path 正确
- doc.go 写好包级文档
- 所有导出符号有注释(用
golint/revive检查) - LICENSE 文件存在
- README.md 包含安装、quickstart、license
- 至少 3 个 Example 函数
- 单元测试覆盖关键路径
- CI 通过
- 打 v1.0.0+ tag(或符合 v2+ 规则)
- 推 tag 后访问 pkg.go.dev 验证
小结
把全文压一句:
Go 模块发布的『正式仪式』是 git tag + pkg.go.dev——但真正决定库能否被人用的是 doc.go 和 Example 函数的质量。
工程要点:
- 注释以符号名开头,每个导出符号都有
- doc.go 是包的脸面——花时间写
- Example 函数比一万字文档有效
- v1.0.0 是分水岭——别永远停在 0.x
- v2+ 必改 module path
把这套做对,你的 Go 库就不只是"能 go get"——它有文档、有版本、有声誉,是 Go 生态的"正式公民"。