发布版本#
以下指南包含如何准备 NumPy 发布的详细信息。
如何准备发布#
这些说明概述了构建 NumPy 二进制版本所需的内容。
当前的构建和发布信息#
有用的信息可在以下位置找到
支持的平台和版本#
NEP 29 概述了支持的 Python 版本;在 2020 年上半年,这将是 Python >= 3.6。每次将代码合并到主分支时,我们都会针对所有这些版本测试 NumPy。二进制安装程序可能适用于这些版本的一个子集(见下文)。
OS X
支持 OS X 版本 >= 10.9;有关 Python 版本支持,请参阅 NEP 29。我们为 OSX 构建与 Python.org Python、系统 Python、homebrew 和 macports 兼容的二进制 wheels——有关详细信息,请参阅此 OSX wheel 构建摘要。
Windows
我们在 Windows 上构建 32 位和 64 位 wheels。支持 Windows 7、8 和 10。我们使用 mingw-w64 工具链、cibuildwheels 和 GitHub Actions 构建 NumPy。
Linux
我们为 NumPy 构建并提供 manylinux_2_28 wheels。许多 Linux 发行版都包含自己的 NumPy 二进制构建。
BSD / Solaris
不提供二进制文件,但据报告在 Solaris 和 BSD 上成功构建。
工具链#
我们所有的 wheels 都在云基础设施上构建——因此这份编译器列表仅供信息和本地调试构建之用。有关使用 multibuild 构建的过时构建配方来源,请参阅 numpy wheels 仓库中的 .travis.yml
脚本。
编译器#
使用的 gcc 版本与 Python 本身在每个平台上构建时使用的版本相同。目前这意味着
在 travis 上构建的 OS X 目前使用 clang。当针对 Python.org 安装程序中的 Python 进行构建时,OSX >= 10.6 的二进制 wheels 似乎可以安全地从 travis-ci OSX 10.9 VM 构建;
Windows 构建使用 mingw-w64 工具链;
Manylinux2014 wheels 使用 Manylinux docker 镜像上提供的 gcc。
您将需要 Cython 来构建二进制文件。Cython 将 NumPy 分发中的 .pyx
文件编译为 .c
文件。
OpenBLAS#
所有 wheels 都链接到通过 openblas-libs 仓库提供的 OpenBLAS 版本。共享对象(或 DLL)随 wheel 一起提供,并已重命名以防止与文件系统中可能存在的其他 OpenBLAS 共享对象发生名称冲突。
构建源存档和 wheels#
NumPy wheels 和 sdist 现在使用 cibuildwheel 和 GitHub Actions 构建。
构建文档#
我们不再构建 PDF
文件。所需的一切是
virtualenv (pip)。
其他要求将在文档构建过程中自动满足。
上传到 PyPI#
上传所需的唯一应用程序是
twine (pip)。
您还需要一个 PyPI 令牌,最好将其保存在密钥环中。有关如何操作,请参阅 twine 密钥环 文档。
发布了什么#
Wheels 我们目前支持 Windows、OSX 和 Linux 上的 Python 3.10-3.13。
Windows:使用 GitHub Actions 构建的 32 位和 64 位 wheels;
OSX:使用 GitHub Actions 构建的 x64_86 和 arm64 OSX wheels;
Linux:使用 GitHub Actions 构建的 x64_86 和 aarch64 Manylinux2014 wheels。
其他 发行说明和更新日志
源代码分发 我们以 .tar.gz 格式构建源代码发布。
发布过程#
商定发布时间表#
典型的发布时间表是一个 beta 版,两个发布候选版和一个最终发布版。最好先在邮件列表上讨论时间安排,以便人们及时提交他们的 commits,合并文档 wiki 编辑等。日期确定后,创建一个新的维护/x.y.z 分支,在主分支中为下一个版本添加新的空发布说明,并更新 Trac Milestones。
确保当前分支正确构建包#
当 PR 标题以 REL
开头时,CI 会构建 wheels。您在发布前的最后一个 PR 应标记为如此,并且所有测试都应通过。您也可以执行
git clean -fxdq
python setup.py bdist_wheel
python setup.py sdist
有关构建过程本身的详细信息,最好阅读下面的分步说明。
注意
以下步骤会重复用于 beta 版、发布候选版和最终发布版。
检查弃用#
在 制作发布分支 之前,应检查所有应删除的已弃用代码是否已实际删除,以及所有新的弃用在 docstring 或弃用警告中说明代码将在哪个版本中删除。
检查 C API 版本号#
C API 版本需要在三个地方进行跟踪
numpy/_core/meson.build
numpy/_core/code_generators/cversions.txt
numpy/_core/include/numpy/numpyconfig.h
该过程分为三个步骤。
如果 API 已更改,请在 numpy/core/meson.build 中递增 C_API_VERSION。仅当针对当前 API 编译的任何代码都向后兼容上一个发布的 NumPy 版本时,API 才未更改。对 C 结构或公共接口的任何添加都将使新 API 不向后兼容。
如果第一步中的 C_API_VERSION 已更改,或者 API 的哈希已更改,则需要更新 cversions.txt 文件。要检查哈希,请运行脚本 numpy/_core/cversions.py 并记下打印的 API 哈希。如果该哈希与 numpy/_core/code_generators/cversions.txt 中的最后一个哈希不匹配,则哈希已更改。使用适当的 C_API_VERSION 和哈希,向 cversions.txt 添加新条目。如果 API 版本未更改,但哈希不同,则需要注释掉该 API 版本的先前条目。例如,在 NumPy 1.9 中添加了注解,这改变了哈希,但 API 与 1.8 相同。哈希用作 API 更改的检查,但它并非最终结果。
如果步骤 1 和 2 正确完成,则编译发布不应发出警告“API mismatch detect at the beginning of the build”。
numpy/_core/include/numpy/numpyconfig.h 将需要一个新的 NPY_X_Y_API_VERSION 宏,其中 X 和 Y 是发布的主要和次要版本号。如果包含文件中的某些函数或宏已弃用,则赋予该宏的值才需要从先前版本增加。
numpy/_core/meson.build 中的 C ABI 版本号应仅在主要版本发布时更新。
检查发布说明#
使用 towncrier 构建发布说明并提交更改。这将从 doc/release/upcoming_changes
中删除所有片段,并添加 doc/release/<version>-note.rst
。
towncrier build --version "<version>"
git commit -m"Create release note"
检查发布说明是否是最新的。
更新发布说明,添加“亮点”部分。提及以下几点:
主要新功能
已弃用和已删除的功能
支持的 Python 版本
对于 SciPy,支持的 NumPy 版本
近期展望
分步说明#
这是在 Linux 上进行 NumPy 2.1.0 发布的分步指南,已修改为使用 GitHub Actions 和 cibuildwheels 构建并上传到 Anaconda.org NumPy 暂存仓库。命令可以复制到命令行中,但请务必将 2.1.0 替换为正确的版本。应与 通用发布指南 一起阅读。
设施准备#
在开始发布之前,请使用 requirements/*_requirements.txt
文件确保您拥有所需的软件。大多数软件都可以用 pip 安装,但有些需要 apt-get、dnf 或您的系统用于软件的其他工具。您还需要一个 GitHub 个人访问令牌 (PAT) 来推送文档。有几种方法可以简化操作
Git 可以设置为使用密钥环存储您的 GitHub 个人访问令牌。在线搜索详细信息。
您可以使用
keyring
应用程序存储 twine 的 PyPI 密码。有关详细信息,请参阅在线 twine 文档。
发布前#
添加/删除 Python 版本#
添加或删除 Python 版本时,需要编辑三个文件
.github/workflows/wheels.yml # 用于 github cibuildwheel
tools/ci/cirrus_wheels.yml # 用于 cibuildwheel aarch64/arm64 构建
pyproject.toml # 用于分类器和最小版本检查。
在针对主分支的普通 PR 中进行这些更改,并在必要时进行回溯。在提交摘要的标题行末尾添加 [wheel build]
指令,以便运行 wheel 构建以测试更改。我们目前在新 Python 版本的第一个 RC 发布后(一旦 manylinux 和 cibuildwheel 支持)发布其 wheels。对于 Python 3.11,我们能够在 RC1 发布后一周内发布。
回溯拉取请求#
已标记为本次发布要进行的更改必须回溯到 maintenance/2.1.x 分支。
更新 2.1.0 里程碑#
查看带有 2.1.0 里程碑的问题/PR,然后将其推迟到更高版本,或者删除该里程碑。您可能需要添加一个里程碑。
创建发布 PR#
发布 PR 通常需要更新或创建四个文档
更新日志
发布说明
The
.mailmap
fileThe
pyproject.toml
file
这些更改应该在针对维护分支的普通 PR 中进行。提交标题应包含 [wheel build]
指令以测试 wheels 是否构建成功。其他小的杂项修复也可能是此 PR 的一部分。提交消息可能类似于
REL: Prepare for the NumPy 2.1.0 release [wheel build]
- Create 2.1.0-changelog.rst.
- Update 2.1.0-notes.rst.
- Update .mailmap.
- Update pyproject.toml
设置发布版本#
检查 pyproject.toml
文件,并在需要时设置发布版本
$ gvim pyproject.toml
检查 pavement.py
和 doc/source/release.rst
文件#
检查 pavement.py
文件是否指向正确的发布说明。它应该在上次发布后已经更新,但如果没有,请现在修复。还要确保这些说明在 release.rst
文件中有一个条目。
$ gvim pavement.py doc/source/release.rst
生成更新日志#
更新日志是使用 changelog 工具生成的
$ spin changelog $GITHUB v2.0.0..maintenance/2.1.x > doc/changelog/2.1.0-changelog.rst
其中 GITHUB
包含您的 GitHub 访问令牌。文本需要检查非标准贡献者名称并删除 dependabot 条目。最好删除 PR 标题中可能存在的任何链接,因为它们不能很好地转换为 Markdown,将其替换为等宽文本。非标准贡献者名称应通过更新 .mailmap
文件来修复,这是一项繁重的工作。最好在达到此点之前进行几次试运行,并使用 GitHub issue ping 那些“罪魁祸首”以获取所需信息。
完成发布说明#
如果 doc/release/upcoming_changes/
中有任何发布说明片段,请运行 spin notes
,这将把片段合并到 doc/source/release/notes-towncrier.rst
文件中并删除片段。
$ spin notes
$ gvim doc/source/release/notes-towncrier.rst doc/source/release/2.1.0-notes.rst
一旦 notes-towncrier
的内容已合并到发布说明中,就可以删除 .. include:: notes-towncrier.rst
指令。说明总是需要一些修正,需要编写引言,并应指出重大更改。对于补丁发布,也可以附加更新日志文本,但对于初始发布则不行,因为它太长。查看以前的发布说明以了解如何操作。
发布演练#
请注意,在下面的代码片段中,upstream
指的是 GitHub 上的根仓库,而 origin
指的是您个人 GitHub 仓库中的分支。如果您没有分叉仓库而只是在本地克隆它,您可能需要进行调整。您还可以编辑 .git/config
并添加 upstream
(如果它不存在)。
1. 准备发布提交#
签出发布分支,确保其最新,并清理仓库。
$ git checkout maintenance/2.1.x
$ git pull upstream maintenance/2.1.x
$ git submodule update
$ git clean -xdfq
健全性检查
$ python3 -m spin test -m full
标记发布并推送标签。这需要 NumPy 仓库的写入权限。
$ git tag -a -s v2.1.0 -m"NumPy 2.1.0 release"
$ git push upstream v2.1.0
如果由于错误需要删除标签
$ git tag -d v2.1.0
$ git push --delete upstream v2.1.0
2. 构建 wheels#
在此过程开始时标记构建将触发通过 cibuildwheel 进行的 wheel 构建,并将 wheels 和 sdist 上传到暂存仓库。GitHub Actions 上的 CI 运行(适用于所有基于 x86 和 macOS arm64 的 wheels)大约需要 1 小时 15 分钟。Cirrus 上的 CI 运行(适用于 aarch64 和 M1)耗时较少。您可以在暂存仓库中检查已上传的文件,但请注意,它与您看到的正在运行的作业的同步并不紧密。
如果您希望手动触发 wheel 构建,可以这样做
在 GitHub Actions -> Wheel builder 上有一个“运行工作流程”按钮,单击它并选择要构建的标签。
在 Cirrus 上,我们目前没有简单的方法来手动触发构建和上传。
如果 wheel 构建由于无关原因失败,您可以单独重新运行它
在 GitHub Actions 上选择 Wheel builder,点击包含您要重新运行的构建的提交。左侧有一个 wheel 构建列表,选择您要重新运行的构建,然后在结果页面上点击逆时针箭头按钮。
在 cirrus 上,登录 cirrusci,查找 v2.1.0 标签并重新运行失败的作业。
3. 下载 wheels#
当所有 wheels 都成功构建并暂存后,使用 tools/download-wheels.py
脚本从 Anaconda 暂存目录下载它们
$ cd ../numpy
$ mkdir -p release/installers
$ python3 tools/download-wheels.py 2.1.0
4. 生成 README 文件#
这需要在所有安装程序下载完毕后,但在 pavement 文件更新以进行持续开发之前完成。
$ paver write_release
5. 上传到 PyPI#
使用 twine
上传到 PyPI。PyPI 最近的更改后,需要一个最新版本的 twine
,此处使用了版本 3.4.1
$ cd ../numpy
$ twine upload release/installers/*.whl
$ twine upload release/installers/*.gz # Upload last.
如果其中一条命令中途中断,您可能需要有选择地上传剩余文件,因为 PyPI 不允许同一个文件上传两次。源文件应该最后上传,以避免在 pip 用户在处理过程中访问文件时可能发生的同步问题,导致 pip 从源构建而不是下载二进制 wheel。PyPI 只允许一个源分发,这里我们选择了 zip 存档。
6. 将文件上传到 GitHub#
转到 numpy/numpy,应该有一个 v2.1.0 tag
,点击它并点击该标签的编辑按钮,将标题更新为 'v2.1.0 (<日期>)'。有两种添加文件的方法:使用可编辑文本窗口和作为二进制上传。首先编辑通过 pandoc 从 rst 版本转换而来的 release/README.md
。需要修复的地方:更新日志中的 PR 行(如果包含)会换行,需要取消换行,链接应更改为等宽文本。然后将内容复制到剪贴板并粘贴到文本窗口中。可能需要多次尝试才能使其看起来正确。然后
将
release/installers/numpy-2.1.0.tar.gz
作为二进制文件上传。将
release/README.rst
作为二进制文件上传。将
doc/changelog/2.1.0-changelog.rst
作为二进制文件上传。如果这是预发布版本,请勾选预发布按钮。
点击底部的
{Publish,Update} release
按钮。
7. 上传文档到 numpy.org(预发布版本跳过此步骤)#
注意
您将需要一个 GitHub 个人访问令牌来推送更新。
此步骤仅适用于最终发布版本,对于预发布版本和大多数补丁发布版本可以跳过。make merge-doc
将 numpy/doc
仓库克隆到 doc/build/merge
中,并用新文档更新它。
$ git clean -xdfq
$ git co v2.1.0
$ rm -rf doc/build # want version to be current
$ python -m spin docs merge-doc --build
$ pushd doc/build/merge
如果发布系列是新的,您需要在 doc/build/merge/index.html
首页的“insert here”注释后添加一个新部分。
$ gvim index.html +/'insert here'
此外,更新版本切换器 JSON 文件,以添加新版本并更新标记为 (stable)
和 preferred
的版本。
$ gvim _static/versions.json
然后运行 update.py
来更新 _static
中的版本
$ python3 update.py
您可以在浏览器中“试运行”新文档,以确保链接有效,尽管版本下拉菜单不会更改,它从 numpy.org
获取信息。
$ firefox index.html # or google-chrome, etc.
更新稳定链接并更新
$ ln -sfn 2.1 stable
$ ls -l # check the link
一旦一切看起来令人满意,就更新、提交并上传更改
$ git commit -a -m"Add documentation for v2.1.0"
$ git push [email protected]:numpy/doc
$ popd
8. 将维护分支重置为开发状态(预发布版本跳过此步骤)#
为下一个发布版本创建发布说明,并编辑它们以设置版本。这些说明将是骨架,内容很少。
$ git checkout -b begin-2.1.1 maintenance/2.1.x
$ cp doc/source/release/template.rst doc/source/release/2.1.1-notes.rst
$ gvim doc/source/release/2.1.1-notes.rst
$ git add doc/source/release/2.1.1-notes.rst
将新的发布说明添加到文档发布列表,并更新 pavement.py
中的 RELEASE_NOTES
变量
$ gvim doc/source/release.rst pavement.py
更新 pyproject.toml
中的 version
$ gvim pyproject.toml
提交结果
$ git commit -a -m"MAINT: Prepare 2.1.x for further development"
$ git push origin HEAD
前往 GitHub 并创建一个 PR。它应该会很快合并。
9. 在 numpy.org 上发布公告(预发布版本跳过此步骤)#
这假设您已经分叉了 numpy/numpy.org
$ cd ../numpy.org
$ git checkout main
$ git pull upstream main
$ git checkout -b announce-numpy-2.1.0
$ gvim content/en/news.md
对于所有发布,转到页面底部并添加一行链接。请参考之前的链接作为示例。
对于一个周期中的
*.0
版本,在顶部添加一个新部分,简要描述新功能,并将新闻链接指向它。
提交并推送
$ git commit -a -m"announce the NumPy 2.1.0 release"
$ git push origin HEAD
前往 GitHub 并创建一个 PR。
10. 向邮件列表宣布#
发布应在 numpy-discussion、scipy-devel 和 python-announce-list 邮件列表上宣布。查看以前的公告以获取基本模板。贡献者和 PR 列表与上面为发布说明生成的列表相同。如果您交叉发布,请确保 python-announce-list 是密送 (BCC),这样回复就不会发送到该列表。
11. 发布后更新主分支(预发布版本跳过此步骤)#
签出主分支并转发文档更改。如果程序发生变化或改进,您可能还需要更新这些说明。
$ git checkout -b post-2.1.0-release-update main
$ git checkout maintenance/2.1.x doc/source/release/2.1.0-notes.rst
$ git checkout maintenance/2.1.x doc/changelog/2.1.0-changelog.rst
$ git checkout maintenance/2.1.x .mailmap # only if updated for release.
$ gvim doc/source/release.rst # Add link to new notes
$ git status # check status before commit
$ git commit -a -m"MAINT: Update main after 2.1.0 release."
$ git push origin HEAD
前往 GitHub 并创建一个 PR。
分支演练#
本指南包含 NumPy 1.21.x 在 Linux 上分支的演练。命令可以复制到命令行中,但请务必将 1.21 和 1.22 替换为正确的版本。在创建分支之前,最好使 .mailmap
尽可能最新,这可能需要数周时间。
这应与 通用发布指南 一起阅读。
分支#
创建分支#
这仅在开始新的维护分支时才需要。由于 NumPy 现在依赖标签来确定版本,因此主分支中新开发周期的开始需要一个带注释的标签。操作如下:
$ git checkout main
$ git pull upstream main
$ git commit --allow-empty -m'REL: Begin NumPy 1.22.0 development'
$ git push upstream HEAD
如果因合并了新的 PR 而推送失败,请执行
$ git pull --rebase upstream
并重复推送。一旦推送成功,就打上标签。
$ git tag -a -s v1.22.0.dev0 -m'Begin NumPy 1.22.0 development'
$ git push upstream v1.22.0.dev0
然后创建新分支并推送
$ git branch maintenance/1.21.x HEAD^
$ git push upstream maintenance/1.21.x
准备主分支以进行进一步开发#
创建一个 PR 分支,为主分支的进一步开发做准备
$ git checkout -b 'prepare-main-for-1.22.0-development' v1.22.0.dev0
删除发布说明片段
$ git rm doc/release/upcoming_changes/[0-9]*.*.rst
创建新的发布说明骨架并添加到索引
$ cp doc/source/release/template.rst doc/source/release/1.22.0-notes.rst
$ gvim doc/source/release/1.22.0-notes.rst # put the correct version
$ git add doc/source/release/1.22.0-notes.rst
$ gvim doc/source/release.rst # add new notes to notes index
$ git add doc/source/release.rst
更新 pavement.py
并更新 RELEASE_NOTES
变量以指向新的说明。
$ gvim pavement.py
$ git add pavement.py
更新 cversions.txt
以添加当前版本。在这个早期阶段,应该没有新的哈希需要担心,只需按照之前的做法添加注释即可
$ gvim numpy/_core/code_generators/cversions.txt
$ git add numpy/_core/code_generators/cversions.txt
检查您的工作,提交并推送
$ git status # check work
$ git commit -m'REL: Prepare main for NumPy 1.22.0 development'
$ git push origin HEAD
现在创建一个拉取请求。