pytest 预发布公告模板解析从release.pre.rst到 RC 版本发布的完整流水线【免费下载链接】pytestThe pytest framework makes it easy to write small tests, yet scales to support complex functional testing项目地址: https://gitcode.com/GitHub_Trending/py/pytest导读pytest 在正式发布大版本之前会先发布 RCRelease Candidate预发布版本并生成一份面向社区的公告文档。本文以仓库中的 scripts/release.pre.rst 为绝对主线完整解读这份预发布公告模板的每个组成部分并结合 scripts/release.py、scripts/prepare-release-pr.py、RELEASING.rst 等源码讲清模板中的{version}、{contributors}、{doc_version}占位符如何被替换、RC 版本号如何自动推导、公告如何写入 doc/en/announce 目录并被 toctree 收录。读完本文你将理解 pytest 预发布公告从模板到真实发布页面的完整生成链路并掌握自行发布/复现 RC 版本公告的每一步操作。一、模板在 pytest 发布体系中的定位pytest 的发布采用模板驱动的方式所有版本公告都从同一组 RST 模板生成再由脚本填充版本号与贡献者名单。仓库scripts/目录下共有四个公告模板按发布类型区分模板文件适用场景scripts/release.major.rst主版本major发布公告scripts/release.minor.rst次版本minor发布公告scripts/release.patch.rst补丁bugfix发布公告scripts/release.pre.rst预发布prerelease / RC公告模板的选择逻辑位于 scripts/prepare-release-pr.py优先major其次prerelease再次minor存在.feature.rst或.breaking.rst变更时兜底为patch。也就是说只要发布了 RC 版本无论它对应的最终版本是主版本还是次版本使用的都是release.pre.rst这份模板。这份模板本身是一份待填充的 RST 文档包含三个占位符{version}、{doc_version}、{contributors}。真实渲染产物可见 doc/en/announce/release-7.0.0rc1.rst 与 doc/en/announce/release-8.0.0rc2.rst。二、逐段拆解release.pre.rst模板内容2.1 标题与开篇声明模板首行为一级标题pytest-{version}其下是等号组成的 RST 标题下划线。渲染后形如pytest-8.0.0rc1。接着是预发布的核心声明The pytest team is proud to announce the {version} prerelease! This is a prerelease, not intended for production use, but to test the upcoming features and improvements in order to catch any major problems before the final version is released to the major public.这里明确了预发布版本的定位不面向生产环境目的是在正式版本推向公众前通过社区提前验证新功能与改进、暴露重大问题。这也是 RC 版本与正式版本在公告措辞上的根本区别——对照 scripts/release.major.rst 可以看到正式版公告直接表述 pytest {version} has just been released而预发布版始终强调 not intended for production use。2.2 回归问题报告约定[prerelease]标签模板要求测试者将发现的回归问题提交到项目的 issue 跟踪器并在标题中包含[prerelease]字符串We appreciate your help testing this out before the final release, making sure to report any regressions to our issue tracker. When doing so, please include the string[prerelease]in the title.这是一个可执行的协作协议[prerelease]前缀让维护者在海量 issue 中快速识别与 RC 版本相关的回归报告是预发布质量闭环的关键一环。2.3 安装命令模板给出精确版本锁定式安装命令pip install pytest{version}与正式版公告的pip install -U pytest见 scripts/release.patch.rst不同预发布版本强制使用精确指定版本号如pip install pytest8.0.0rc1。原因在于RC 版本不会作为最新稳定版被-U自动选中只有显式指定版本号才能安装到预发布构建。渲染实例见 release-7.0.0rc1.rst 中的pip install pytest7.0.0rc1。2.4 CHANGELOG 指引模板提示用户仔细阅读 CHANGELOG其中文档链接的版本路径同样由{doc_version}占位符控制指向该 RC 对应分支的在线文档如7.0.x分支。这正是doc_version参数存在的意义预发布版本的文档链接必须指向仍在维护的分支路径而不是stable。2.5 贡献者名单与签名模板末尾以占位符形式列出{contributors} Happy testing, The pytest Development Team贡献者名单由脚本从 git 提交历史中自动提取渲染后是一个以*开头的无序列表如 release-7.0.0rc1.rst 中列出的数十位贡献者。三、占位符的填充机制release.py源码级解析模板本身不能直接发布所有占位符都由 scripts/release.py 的announce()函数release.py填充。整个填充过程分四步3.1 从 git 历史提取贡献者last_version git describe --abbrev0 --tags rev_range f{last_version}..HEAD authors git log rev_range --format%aN co_authors git log rev_range --format%(trailers:keyCo-authored-by)release.py贡献者 上个 tag 到当前 HEAD 之间的提交作者%aN与Co-authored-by 尾注作者的并集并过滤掉[bot]结尾及pytest bot的自动化账号。名单去重后按字典序排序再逐行拼成* name形式的 RST 列表最终作为{contributors}注入模板。3.2 模板读取与格式化template_text Path(__file__).parent.joinpath(template_name).read_text(...) text template_text.format( versionversion, contributorscontributors_text, doc_versiondoc_version )release.py模板从scripts/目录按传入的template_name读取用 Python 的str.format()完成占位符替换。这也解释了模板中三个字段的写法{version}、{contributors}、{doc_version}正是format()的关键字参数名。3.3 写出公告文件target Path(__file__).parent.joinpath(f../doc/en/announce/release-{version}.rst) target.write_text(text, encodingUTF-8)release.py渲染结果写入 doc/en/announce/release-{version}.rst文件名为release- 版本号因此 7.0.0rc1 的公告文件名是release-7.0.0rc1.rst。3.4 更新发布索引announce()还会把新公告插入 doc/en/announce/index.rst 的 toctreerelease.py在首个release-条目之前插入新文件名从而保证公告列表按新版本在前排列若已存在同名条目则跳过并打印提示。这也解释了为什么 index.rst 中release-8.0.0rc2、release-8.0.0rc1排在正式版 8.0.0 之前。四、RC 版本号如何自动推导公告的{version}并非人工输入而是由 prepare-release-pr.py 的find_next_version()根据 git tag 自动计算发布类型推导公式示例主版本主版本号1.0.0 预发布后缀7.0.0 →8.0.0rc1次版本有 feature/breaking主.次1.0 后缀7.0.0 →7.1.0rc1补丁版本主.次.补丁1 后缀7.0.0 →7.0.1rc1预发布后缀由命令行参数--prerelease提供如rc1、rc2。脚本先从git tag中收集所有形如数字.数字.数字的稳定 tag 并排序取最大再叠加is_major/is_feature_release/prerelease三个因素拼接出下一个版本号。在 RELEASING.rst 中Release candidates一节给出的实际操作是触发 GitHub Actions workflowgh workflow run prepare-release-pr.yml -f branch8.0.x -f majoryes -f prereleaserc1该 workflow 会创建release-8.0.0rc1分支、生成公告并提交一个 Release PR。注意prerelease输入为空时-f prerelease则按正式版本发布。五、从模板到发布完整流水线调用链将 scripts/release.py 与 scripts/prepare-release-pr.py 串联起来一份预发布公告从模板到上线共经历以下环节入口tox.ini 定义[testenv:release]环境执行python scripts/release.py {posargs}自动化流程则使用[testenv:prepare-release-pr]tox.ini执行prepare-release-pr.py。tox 环境声明了colorama、pre-commit2.9.3、towncrier依赖。分支准备prepare-release-pr.py检出origin/{base_branch}根据changelog/目录下是否存在*.feature.rst/*.breaking.rst判断是否功能版本prepare-release-pr.py然后创建release-{version}分支并配置pytest bot的 git 身份。版本与模板决策find_next_version()计算版本号按 major → prerelease → minor → patch 顺序选择模板。发布主流程pre_release()release.py依次执行announce()填充模板并写出公告、更新 toctree 索引regen()通过tox -e regen重新生成文档中的示例输出以SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYTEST固定版本changelog()调用towncrier build --yes --version {version}汇总 changelog 目录下的片段写入时用--draft预览正式构建时写盘fix_formatting()pre-commit run --all-files统一格式check_links()tox -e docs-checklinks校验文档链接可用--skip-check-links跳过最后git commit -a生成提交。推送与 PR强制推送release-{version}分支并用gh pr create --draft创建草稿 PRprepare-release-pr.pyPR 正文提示维护者后续在release-{version}分支上运行 deploy workflow 完成 PyPI 上传与 tag。由此可以看出release.pre.rst虽然是全文不到 30 行的模板但它驱动了贡献者提取 → 版本渲染 → 公告归档 → 索引更新 → 发布分支 PR这一整套自动化流水线是预发布环节的公告骨架。六、真实渲染产物对照与验证把模板与真实产物对照可以直观验证占位符替换的正确性release-7.0.0rc1.rst标题pytest-7.0.0rc1{version}→7.0.0rc1安装命令pip install pytest7.0.0rc1贡献者列表含数十个* name条目{contributors}渲染结果文档链接指向7.0.x分支{doc_version}→7.0.x。release-8.0.0rc2.rst同一模板的第二次 RC 渲染对应8.0.0rc2。此外从仓库的语义化版本约定看预发布版本号中 rc 前缀遵循 主.次.补丁rc序号 的模式这也与 doc/en/reference/reference.rst 中对预发布版本组件的描述一致预发布版本的最后一段为字符串形式的预发布标识。七、实践要点与注意事项7.1 安装 RC 版本的正确姿势预发布公告明确要求使用精确版本安装pip install pytest{version}不要在 RC 阶段使用pip install -U pytest否则大概率不会命中预发布构建。7.2 反馈回归问题发现 RC 回归时在 issue 标题中带上[prerelease]标记模板原文要求 exactly[prerelease]便于维护者分类处理。7.3 维护者操作要点发布必须基于release-{version}分支合并 Release PR 时不要 squash merge以保证后续 tag 落在主分支提交上RELEASING.rstRC 阶段可向维护分支合入小幅改进但应避免引入重大变更RELEASING.rst发布完成后需将 CHANGELOG 与公告文件 cherry-pick 回main分支RELEASING.rst。7.4 模板的可扩展性release.pre.rst与另外三份模板同处 scripts 目录通过template_name参数切换。若未来要调整公告措辞或新增发布类型只需修改对应模板或扩展 release.py 的模板选择逻辑无需改动流水线其余部分——这正是模板 占位符设计带来的低耦合收益。结语release.pre.rst是 pytest 预发布公告的最小事实源它以三个占位符定义了 RC 公告的完整信息结构版本、协作协议、安装命令、变更指引、致谢名单再经由 release.py 的announce()填充、prepare-release-pr.py 的版本推导与分支管理最终沉淀为 doc/en/announce 目录中一份份可发布的公告文档。理解这条链路既能帮助测试者正确参与 RC 验证与反馈也能为其他开源项目设计类似的公告自动化提供可直接借鉴的范本。【免费下载链接】pytestThe pytest framework makes it easy to write small tests, yet scales to support complex functional testing项目地址: https://gitcode.com/GitHub_Trending/py/pytest创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考