pybind11 版本发布指南:从版本号规范到完整的发布流程实战
【免费下载链接】pybind11Seamless operability between C++11 and Python项目地址: https://gitcode.com/GitHub_Trending/py/pybind11
本篇指南以 pybind11 官方文档 docs/release.rst 为骨架,系统讲解 pybind11 项目的版本号规范(PEP 440)、源码中的版本宏定义、基于 nox 的自动化校验与打包工具链,以及从打 tag、管理 stable/发布分支到最终发布 GitHub Release 与 PyPI 包的完整流程。读完本文,你将掌握 pybind11 项目“如何正确发布一个新版本”的全套操作,也能理解版本号为何必须以include/pybind11/detail/common.h为唯一事实来源。
版本号规范:必须符合 PEP 440
pybind11 的版本号必须是一个合法的 PEP 440 中可以看到当前版本的全部版本宏:
#define PYBIND11_VERSION_MAJOR 3 #define PYBIND11_VERSION_MINOR 1 #define PYBIND11_VERSION_MICRO 0 // ALPHA = 0xA, BETA = 0xB, GAMMA = 0xC (release candidate), FINAL = 0xF (stable release) #define PYBIND11_VERSION_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL #define PYBIND11_VERSION_RELEASE_SERIAL 0 #define PYBIND11_VERSION_PATCH 0各宏的含义与规范如下:
| 宏 | 含义 | 取值约定 |
|---|---|---|
PYBIND11_VERSION_MAJOR | 主版本号 X | 正整数 |
PYBIND11_VERSION_MINOR | 次版本号 Y | 正整数 |
PYBIND11_VERSION_MICRO | 补丁号 Z | 简单整数(发布流程要求) |
PYBIND11_VERSION_RELEASE_LEVEL | 发布阶段 | PY_RELEASE_LEVEL_ALPHA/BETA/GAMMA(RC) /FINAL |
PYBIND11_VERSION_RELEASE_SERIAL | 发布序号 | 开发版本用0xA0(LEVEL=0xA,SERIAL=0),稳定版固定为 0 |
PYBIND11_VERSION_PATCH | 版本字符串补丁段 | 例如0a0、0b1、0rc1,最终发布必须是简单整数 |
关于PYBIND11_VERSION_PATCH的写法,文档明确规定:
- alpha 阶段:如
Za0,表示 Z 号版本的第一个 alpha; - beta 阶段:应为
Zb1(如3.2.0b1); - RC 阶段:可为
Zrc1(如3.2.0rc1); - 最终发布:必须是简单整数(如
3.1.0的 PATCH 为0)。
这些宏还会被组合成一个 4 字节十六进制版本号PYBIND11_VERSION_HEX(见 include/pybind11/detail/common.h),通过Py_PACK_FULL_VERSION打包,用于与 Python 运行时的 API 版本做兼容判断。
版本号单一事实来源(Single Source of Truth)
include/pybind11/detail/common.h中的宏是版本号的唯一权威来源,仓库内的其他版本信息都由它派生:
- pybind11/_version.py 在未安装(从源码直接运行)时通过正则从
common.h解析出__version__与version_info;构建成 wheel 后该文件会被替换为写死的版本号; - pyproject.toml 中的
[tool.scikit-build.metadata.version]也使用regexprovider 从common.h读取版本,实现打包元数据与源码宏的自动同步; - 构建时 scikit-build 会根据
common.h中的版本自动生成正式版 pybind11/_version.py(模板见 pyproject.toml)。
因此发布时只要改一处(common.h),就能保证 pip 元数据、pybind11.__version__和 C++ 头文件宏保持一致。
发布前的环境准备
发布流程大量使用 nox 会话。如果你没有安装 nox,官方推荐以下任一方式:
- 直接使用
pipx run nox(无需显式安装); uv tool install nox;pipx install nox;- Unix 系统下
brew install nox。
发布一个新版本的完整步骤
1. 更新版本号
修改 include/pybind11/detail/common.h 中的PYBIND11_VERSION_MAJOR等宏,其中MICRO 应为简单整数。改完后运行打包测试验证修改是否正确:
nox -s tests_packaging从源码看,该 nox 会话会安装 tests/requirements.txt 并执行pytest tests/extra_python_package(见 noxfile.py),实际校验打包结果与版本号是否符合预期。
2. 核对 pyproject.toml 元数据
确保 pyproject.toml 中的信息保持最新,例如:
- 支持的 Python 版本(classifiers 中的
Programming Language :: Python :: 3.x列表); - 项目描述、作者、许可证、依赖分组等。
当前仓库的 classifiers 覆盖 Python 3.9 至 3.15,并声明 CPython 与 PyPy 实现,requires-python = ">=3.9"。
3. 更新 changelog
在 docs/changelog.md 中补充发布日期,并整合nox -s make_changelog的输出:
nox -s make_changelog这个命令的底层是 tools/make_changelog.py,其工作机制值得了解:
- 它调用 GitHub API 查询所有已关闭且带有
needs changelog标签的 PR/issue(每页 100 条); - 从每个条目 body 中的
## Suggested changelog entry:区块提取内容,格式化成本文条目并附上 PR 编号链接; - 依据 PR 标题的 conventional commit 前缀(如
feat(...)、fix(...)、docs、tests、ci、chore)自动归类为 "New Features"、"Bug fixes"、"Documentation"、"Tests"、"CI"、"Other" 等章节; - 若 token 可用则使用
GITHUB_TOKEN/GH_TOKEN或gh auth token获取,避免公共 CDN 的过期缓存导致结果陈旧。
注意:make_changelog只是输出建议内容,需要手动在 docs/changelog.md 中集成,并且要手动在 GitHub Web 界面清除已处理条目的needs changelog标签(点击文档中给出的标签链接筛选即可,非常方便)。
4. 提交并推送,确保 CI 通过
git add git commit git push务必确保 CI 通过。如果失败原因是已知的 flake(偶发不稳定)问题,可以选择忽略或重启 CI。
5. 创建或更新发布分支
如果是新的MINOR版本,创建新的发布分支;如果是patch版本,则更新已有分支。文档假设你的upstream指向 pybind11 官方仓库(https://github.com/pybind/pybind11.git):
# 新分支(新 MINOR 版本): git checkout -b vX.Y git push -u upstream vX.Y # 更新分支(patch 版本): git checkout vX.Y git merge <release branch> git push6. 更新 tags(可选步骤)
打 annotated tag 并做最后一次一致性检查:
git tag -a vX.Y.Z -m 'vX.Y.Z release' git grep PYBIND11_VERSION include/pybind11/detail/common.h # 最后一次一致性检查:与 tag 是否一致? git push upstream vX.Y.Zgit grep输出中的版本宏应与 tag 名称完全一致。如果跳过此步骤也没关系,后续创建 GitHub Release 时会自动为你生成一个轻量(non-annotated)tag。
7. 更新 stable 分支
pybind11 维护一个长期指向最新稳定版的stable分支,更新流程如下:
git checkout stable git merge -X theirs vX.Y.Z git diff vX.Y.Z # 仔细审查并调和差异,理论上应无差异 git push其中-X theirs表示冲突时以被合并分支(vX.Y.Z)为准,随后用git diff vX.Y.Z确认 stable 与发布 tag 完全一致。
8. 创建 GitHub Release
GitHub Release 会显示在仓库 UI 中、向关注 releases 的用户发送通知,同时触发 PyPI 包的上传。提供两种方式:
GUI 方式:在仓库的 Releases 页面点击 "Draft a new release",填写 tag 名称(若第 6 步未打 tag,可在此处创建),Release 名称格式为 "Version X.Y.Z",将Markdown 格式的 changelog 复制粘贴到描述中。可以移除多余换行,也可以去掉 PR/issue 的超链接标记(例如简化为裸的#1234)。如果是 alpha/beta/RC 版本,勾选 "pre-release"。
CLI 方式(需安装gh):
gh release create vX.Y.Z -t "Version X.Y.Z" # 预发布版本加 -p 参数 gh release create vX.Y.Z -t "Version X.Y.Z" -p9. 发布后回到开发状态
发布完成后立即把仓库恢复到开发状态,防止误在发布版本上继续开发:
git checkout master # 确保在 master 上然后:
- 更新 include/pybind11/detail/common.h 中的版本宏:PATCH 设为
0a0,MINOR 递增(例如 3.1.0 发布后变成 3.2.0a0); - 同步更新 pybind11/_version.py 使其匹配;
- 再次运行
nox -s tests_packaging验证修改正确; - 如果本次发布是新的 MINOR 版本,在 docs/changelog.md 中新增一个
IN DEVELOPMENT章节; git add、git commit、git push。
版本分支的 PATCH 约定
如果后续更新了某个版本分支(如 vX.Y 上继续出 patch),记得将 PATCH 设为1a0——这与 master 上的0a0约定相区分,表示该分支已进入维护期。
下游渠道的自动发布
pybind11 的发布会自动传导到主流包管理器:
- conda-forge:发布后几个小时内会自动创建 PR,若无问题会自动合并;
- Homebrew:同样自动更新。
维护者无需手动干预这两个渠道。
手动打包与上传(备用方案)
正常情况下 GitHub Release 会自动上传 PyPI 包,无需手动操作。但如果你需要手动上传发行产物,可以从 CI job artifacts 下载后用 twine 上传,也可以在本地构建(文档不建议常规情况下这样做,因为本地目录更可能"不干净",SDist 构建时容易把无关的隐藏文件一并打包进去)。本地构建流程为:
nox -s build # 构建 SDist 和 wheel nox -s build_global # 构建 pybind11-global 的 SDist 和 wheel twine upload dist/* # 上传产物前两行分别构建标准包与全局包,最后一行把dist/目录下的所有产物上传到 PyPI。
从源码看,这两个 nox 会话的行为是:
build:安装build后执行python -m build(见 noxfile.py),产出 SDist 与 wheel;build_global:先运行 tools/make_global.py,用 tomlkit 动态改写 pyproject.toml(将项目名改为pybind11-global、移除 entry-points 与 optional-dependencies、设置wheel.install-dir = "/data"等),再执行python -m build,构建完成后利用preserve_file上下文管理器恢复原始 pyproject.toml(见 noxfile.py)。
小结
pybind11 的版本发布是一套高度流程化、且由工具链强校验的工程实践,其核心要点可以概括为:
- 版本号唯一来源是 include/pybind11/detail/common.h 的宏定义,
_version.py与 PyPI 元数据都由它自动派生; - 每次改版本宏后必须运行
nox -s tests_packaging做打包级校验,tests/extra_python_package 下的测试是发布前的最后一道关卡; - changelog 由 tools/make_changelog.py 依据
needs changelog标签与 PR 描述自动生成,维护者负责集成与清理标签; - 发布分支(vX.Y)、tag(vX.Y.Z)与
stable分支三者的状态必须严格一致,并用git diff/git grep做交叉校验; - 发布结束后立即恢复 master 开发态(PATCH 置
0a0、MINOR 递增),避免在发布版本上继续开发。
对于 pybind11 的维护者而言,本文即是一份可直接对照执行的发布操作手册;对于希望理解该项目 CI 与打包体系的读者,noxfile.py、tools/make_changelog.py 与 tools/make_global.py 则是值得深入阅读的实现参考。
【免费下载链接】pybind11Seamless operability between C++11 and Python项目地址: https://gitcode.com/GitHub_Trending/py/pybind11
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考