发布指南#
本文档仅适用于 Matplotlib 发布管理者.
一份为进行 Matplotlib 发布的开发者准备的指南.
版本控制方案#
Matplotlib 遵循 Intended Effort Versioning (EffVer) 版本控制方案:主版本号.中期版本号.次要版本号.
- 主版本号
一个我们期望用户花费大量精力来升级的版本.从 v1 到 v2 的过渡包括对默认样式的全面修改,而从 v2 到 v3 的过渡涉及放弃对 Python 2 的支持.
未来的主版本更新将包括规模相当的更改,这些更改无法在中期版本中逐步完成.
- 中期版本号
一个我们期望用户花费一些精力来升级的版本.我们的目标是每 6 个月发布一个中期版本.这些版本的目的主要是向用户发布新功能,但也包含根据 our policy 有意的功能弃用和删除.
- 次要版本号
一个我们期望用户几乎不需要任何精力即可升级的版本.根据我们的 反向移植策略 ,我们只将错误修复反向移植到维护分支.我们期望对用户的影响最小,只是可能会破坏对已修复错误的解决方法或"bugs being used as features ".
这些版本会根据需要发布,但通常在中期版本之间每 1-2 个月发布一次.
创建发布分支#
备注
这假设规范仓库的只读远程仓库是"remote",读/写远程仓库是"DANGER"
当新的中期版本(vX.Y.0)即将发布时,必须创建一个新的发布分支.具体何时发生取决于发布管理者,但此时是大多数针对中期版本的新功能合并的地方,并且您正在进入功能冻结期(即,新实现的功能将进入 vX.Y+1).这并不一定意味着在发布之前不会进行任何进一步的更改,只是这些更改将使用反向移植系统进行.
对于即将发布的 v3.7.0 版本,首先创建分支:
git switch main
git pull
git switch -c v3.7.x
git push DANGER v3.7.x
更新 v3.7.0 里程碑,以便描述如下:
New features and API changes
on-merge: backport to v3.7.x
次要版本应改为:
Bugfixes and docstring changes
on-merge: backport to v3.7.x
检查所有活动里程碑的一致性.较旧的里程碑也应反向移植到更高的中期版本(例如,一旦 v3.7.x 分支存在并且 PR 反向移植仍然以 v3.6.x 为目标,则 v3.6.3 和 v3.6-doc 应反向移植到 v3.6.x 和 v3.7.x ).
为下一个中期版本创建里程碑(即 v3.9.0 ,因为 v3.8.0 应该已经存在).虽然大多数活动项目应该进入下一个中期版本,但此里程碑可以帮助进行长期规划,尤其是在弃用周期方面.
测试#
我们使用 GitHub Actions 进行持续集成.在准备发布时,最终标记的提交应在上传之前在本地进行测试:
pytest -n 8 .
此外,应运行以下测试并手动检查:
python tools/memleak.py agg 1000 agg.pdf
运行 NBAgg 和 ipympl 后端的用户接受测试:
jupyter notebook lib/matplotlib/backends/web_backend/nbagg_uat.ipynb
对于 ipympl,重新启动内核,添加一个单元格 %matplotlib widget ,不要运行带有 matplotlib.use('nbagg') 的单元格. 检查 connection_info ,使用 reshow 或测试 OO 接口的测试预计不适用于 ipympl .
GitHub 统计信息#
我们通过 API 从 GitHub 自动提取 GitHub issue,PR 和作者.准备此列表:
存档现有的 GitHub 统计信息页面.
将当前的
doc/users/github_stats.rst复制到doc/users/prev_whats_new/github_stats_X.Y.Z.rst.更改文件顶部的链接目标.
删除末尾的"之前的 GitHub 统计信息"部分.
例如,当从 v3.7.0 更新到 v3.7.1 时:
cp doc/users/github_stats.rst doc/users/prev_whats_new/github_stats_3.7.0.rst $EDITOR doc/users/prev_whats_new/github_stats_3.7.0.rst # Change contents as noted above. git add doc/users/prev_whats_new/github_stats_3.7.0.rst
重新生成更新后的统计信息:
python tools/github_stats.py --since-tag v3.7.0 --milestone=v3.7.1 \ --project 'matplotlib/matplotlib' --links > doc/users/github_stats.rst
查看并提交更改.某些 issue/PR 标题可能不是有效的 reST(最常见的问题是
*,它被解释为未闭合的标记). 另请确认codespell没有发现任何问题.
备注
确保您已通过 GitHub API 进行身份验证. 如果不这样做,您将因超出 API 速率限制而被 GitHub 阻止.您可以通过以下两种方式之一进行身份验证:
使用
keyring包;pip install keyring,然后在运行统计脚本时,系统会提示您输入用户名和密码,这些信息将存储在您的系统密钥环中,或者,使用个人访问令牌;在 on this GitHub page 上生成一个新令牌,范围为
repo:public_repo,并将令牌放在~/.ghoauth中.
更新并验证文档#
合并 *-doc 分支#
将最新的 'doc' 分支(例如 v3.7.0-doc )合并到您要标记的分支中,并删除 GitHub 上的 doc 分支.
更新安全策略中支持的版本#
在进行宏版本或中版本发布时,请更新 SECURITY.md 中安全策略中支持的版本.
对于中版本发布,请更新 SECURITY.md 中的表格,以指定当前宏版本系列中最新的两个中版本发布受到支持.
对于宏版本发布,请更新 SECURITY.md 中的表格,以指定之前的宏版本系列中的最后一个中版本仍然受到支持. 放弃对宏版本系列的最后一个版本的支持将以特别处理的方式进行.
更新发行说明#
新功能#
仅宏版本和中版本发布需要.Bugfix 版本不应包含新功能.
将 doc/users/next_whats_new/ 中所有文件的内容合并到单个文件 doc/users/prev_whats_new/whats_new_X.Y.0.rst 中,并删除各个文件.
API 更改#
主要用于宏版本和中版本发布. 我们有时会在微版本发布中进行 API 更改.
将 doc/api/next_api_changes/ 中所有文件的内容合并到单个文件 doc/api/prev_api_changes/api_changes_X.Y.Z.rst 中,并删除各个文件.
发行说明 TOC#
更新 doc/users/release_notes.rst :
对于宏版本和中版本发布,添加一个新部分
X.Y === .. toctree:: :maxdepth: 1 prev_whats_new/whats_new_X.Y.0.rst ../api/prev_api_changes/api_changes_X.Y.0.rst prev_whats_new/github_stats_X.Y.0.rst
对于微版本发布,将 GitHub 统计信息和(如果存在)API 更改添加到现有的 X.Y 部分
../api/prev_api_changes/api_changes_X.Y.Z.rst prev_whats_new/github_stats_X.Y.Z.rst
更新版本切换器#
更新 doc/_static/switcher.json :
如果是微版本发布
X.Y.Z,则无需更改.如果是中版本发布
X.Y.0,则更改name: X.Y+1 (dev)和name: X.Y (stable)的名称,并为之前的稳定版本添加一个新版本 (name: X.Y-1).
验证文档是否构建成功#
最后,请确保文档构建顺利:
make -Cdoc O=-j$(nproc) html latexpdf
构建文档后,检查所有链接(内部和外部)是否仍然有效. 我们为此使用 linkchecker
pip install linkchecker
pushd doc/build/html
linkchecker index.html --check-extern
popd
解决可能出现的任何问题. 内部链接在 Circle CI 上进行检查,因此这只会标记失败的外部链接.
创建发布提交和标签#
要创建标签,首先创建一个空提交,并在提交消息中使用非常简洁的发行说明集:
git commit --allow-empty
然后使用正文消息中的相同文本创建一个带签名的带注释的标签:
git tag -a -s v3.7.0
这将提示您输入 GPG 密钥密码和注释. 对于预发布版本,按照 PEP 440 进行操作非常重要,以便构建工件在 PyPI 中正确排序.
为了防止任何下游构建器从 GitHub 下载 tarball 时出现问题,重要的是将所有分支从带有标签的提交中移开 [1]
git commit --allow-empty
最后,将标签推送到 GitHub:
git push DANGER v3.7.x v3.7.0
恭喜,最可怕的部分已经完成! 这假定已创建发布分支. 通常,这是在中版本版本的功能冻结时完成的(通常与之前的中间版本的最后一个微版本同时发生)
如果这是一个最终版本,还要创建一个 'doc' 分支 (预发布版本不执行此操作):
git branch v3.7.0-doc
git push DANGER v3.7.0-doc
更新 (或创建) v3.7-doc 里程碑.描述应包含 meeseeksmachine 指令,将带有 v3.7-doc 里程碑的更改向后移植到 v3.7.x 分支和 v3.7.0-doc 分支:
Documentation changes (.rst files and examples)
on-merge: backport to v3.7.x
on-merge: backport to v3.7.0-doc
检查所有活跃的里程碑,确保一致性.较旧的 doc 里程碑也应向后移植到更高的 meso 版本 (例如,如果 v3.7.x 分支存在,则 v3.6-doc 应向后移植到 v3.6.x 和 v3.7.x )
发布管理 / DOI#
通过 GitHub UI ,将新推送的标签转换为发布版本.如果这是一个预发布版本,请记住将其标记为预发布版本.
对于最终版本,还要从 Zenodo 获取 DOI (一旦标签被推送,它将自动生成一个 DOI).将 DOI 后缀和版本添加到 tools/cache_zenodo_svg.py 中的字典中,并运行脚本.
这会将新的 SVG 下载到 doc/_static/zenodo_cache/postfix.svg 并编辑 doc/project/citing.rst .将新的 SVG,对 tools/cache_zenodo_svg.py 的更改以及对 doc/project/citing.rst 的更改提交到 VER-doc 分支并推送到 GitHub.
git checkout v3.7.0-doc
$EDITOR tools/cache_zenodo_svg.py
python tools/cache_zenodo_svg.py
git commit -a
git push DANGER v3.7.0-doc:v3.7.0-doc
构建二进制文件#
我们通过 PyPI 分发 macOS,Windows 和许多 Linux wheels 以及一个源代码 tarball.大多数构建器应该在标签推送到 GitHub 后自动触发:
Windows,macOS 和 manylinux wheels 在 GitHub Actions 上构建.构建由
.github/workflows/cibuildwheel.yml中定义的 GitHub Action 触发,wheels 将作为构建的 artifacts 提供.一旦所有 wheels 构建完成,源代码 tarball 和 wheels 将自动上传到 PyPI.auto-tick bot 应该打开一个拉取请求到 conda-forge feedstock .审查并合并 (如果你有权限的话).
警告
因为这是自动化的,所以将所有分支从标签上移开非常重要,如 创建发布提交和标签 中所讨论的.
手动上传到 PyPI#
备注
如上所述,GitHub Actions 工作流程应自动构建和上传源代码 tarball 和 wheels.如果出于某种原因,您需要手动上传这些 artifacts,请按照本节中的说明进行操作.
一旦你收集到所有的 wheels (预计需要几个小时),生成 tarball:
git checkout v3.7.0
git clean -xfd
python -m build --sdist
并将所有的 wheels 复制到 dist 目录.首先,检查 dist 文件是否正常:
twine check dist/*
然后使用 twine 将所有文件上传到 PyPI
twine upload -s dist/matplotlib*tar.gz
twine upload dist/*whl
恭喜,你现在已经完成了第二可怕的部分!
构建和部署文档#
要构建文档,您必须安装已标记的版本,但从 ver-doc 分支构建文档.一种简单的方法是:
pip install matplotlib
pip install -r requirements/doc/doc-requirements.txt
git checkout v3.7.0-doc
git clean -xfd
make -Cdoc O="-t release -j$(nproc)" html latexpdf LATEXMKOPTS="-silent -f"
这将构建 HTML 和 PDF 版本的文档.
构建的文档存在于 matplotlib.github.com 存储库中.将更改推送到 main 会自动更新网站.
文档按版本组织在子目录中.最新的稳定版本从 stable 目录进行符号链接.当前 main 的文档在 Circle CI 上构建并推送到 devdocs 存储库.这些可以在 matplotlib.org/devdocs 上找到.
假设您已在与 matplotlib 相同的目录下检出此存储库:
cd ../matplotlib.github.com
cp -a ../matplotlib/doc/build/html 3.7.0
rm 3.7.0/.buildinfo
cp ../matplotlib/doc/build/latex/Matplotlib.pdf 3.7.0
这将复制构建的文档.如果这是最终版本,请将 stable 子目录链接到最新版本:
rm stable
ln -s 3.7.0 stable
您还需要编辑 sitemap.xml 和 versions.html 以包含新发布的版本.现在提交并将所有内容推送到 GitHub
git add *
git commit -a -m 'Updating docs for v3.7.0'
git push DANGER main
恭喜,您现在已经完成了第三个最可怕的部分!
如果您有访问权限,请清除 CloudFlare 缓存.
网站通常需要大约 5-10 分钟来处理推送并更新实时网页(请记住清除浏览器缓存).
将更改合并到主分支#
完成发布后,应将发布分支中的更改合并到 main 分支中.这主要是为了使发布的标签位于主分支上,以便 git describe (以及 setuptools-scm )具有最新的标签.其次,在发布期间所做的更改(包括删除个性化的发行说明,修复断开的链接和更新版本切换器)会添加到 main .
很可能出现 Git 冲突,但除了直接对发布分支所做的更改(主要作为发布的一部分)之外,通过使用 main 中的版本应该可以相对容易地解决这些冲突.这不是一个普遍的规则,应注意确保正确性:
git switch main
git pull
git switch -c merge_up_v3.7.0
git merge v3.7.x
# resolve conflicts
git merge --continue
由于 main 分支的分支保护,这是通过标准拉取请求合并的,尽管预计 PR 清洁度状态检查将失败.不应压缩 PR,因为其目的是合并分支历史记录.
宣传此次发布#
在将版本发布到 PyPI 和 conda 之后,应通过我们的沟通渠道宣布它:
将发行说明和致谢的简短版本发送到所有 邮件列表
在活跃的 What's new 上发布亮点并链接到 social media accounts
通过编辑
docs/body.html,将发布公告添加到 matplotlib.org 的"新闻"部分.链接到自动生成的公告 discourse 帖子,该帖子位于 Announcements > matplotlib-announcements 中.
Conda 包#
Matplotlib 项目本身不发布 conda 包.特别是,Matplotlib 发布经理不负责 conda 打包.
有关为 conda-forge 打包 Matplotlib 的信息,请参阅 conda-forge/matplotlib-feedstock.