发布版本#

以下指南包含如何准备 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 密钥环 文档。

生成作者/PR 列表#

您将需要一个个人访问令牌 https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/,以便脚本可以访问 GitHub NumPy 仓库。

  • gitpython (pip)

  • pygithub (pip)

发布了什么#

  • 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

该过程分为三个步骤。

  1. 如果 API 已更改,请在 numpy/core/meson.build 中递增 C_API_VERSION。仅当针对当前 API 编译的任何代码都向后兼容上一个发布的 NumPy 版本时,API 才未更改。对 C 结构或公共接口的任何添加都将使新 API 不向后兼容。

  2. 如果第一步中的 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”。

  3. 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 file

  • The 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.pydoc/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-docnumpy/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

现在创建一个拉取请求。