发布版本#

以下指南包含有关如何准备 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 building summary .

  • Windows

    我们在 Windows 上构建 32 位和 64 位 wheels.支持 Windows 7,8 和 10.我们使用 mingw-w64 toolchain , 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 .看起来,从 travis-ci OSX 10.9 虚拟机针对 Python.org 安装程序中的 Python 进行构建时,可以安全地构建 OSX >= 10.6 的二进制 wheels;

  • Windows 构建使用 mingw-w64 toolchain ;

  • 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 keyring 文档.

生成作者/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 编辑等.确定日期后,创建一个新的 maintenance/x.y.z 分支,在主分支中为下一个版本添加新的空发行说明,并更新 Trac Milestones.

确保当前分支可以正确构建软件包#

当 PR 标题以 REL 开头时,CI 会构建 wheels.发布前的最后一个 PR 应该这样标记,并且所有测试都应该通过.您也可以这样做:

git clean -fxdq
python setup.py bdist_wheel
python setup.py sdist

有关构建过程本身的详细信息,最好阅读下面的"分步指南".

备注

以下步骤将针对 beta 版本,候选发布版本和最终发布版本重复执行.

检查弃用#

the release branch is made 之前,应该检查所有应该删除的已弃用代码是否已实际删除,并且所有新的弃用代码都在文档字符串或弃用警告中说明了代码将被删除的版本.

检查 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 不匹配".

  3. numpy/_core/include/numpy/numpyconfig.h 将需要一个新的 NPY_X_Y_API_VERSION 宏,其中 X 和 Y 是发布版本的主要版本号和次要版本号.只有在 include 文件中的某些函数或宏已被弃用时,才需要将该宏给定的值从上一个版本增加.

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 staging repository for NumPy .这些命令可以复制到命令行中,但请务必将 2.1.0 替换为正确的版本.这应该与 general release guide 一起阅读.

设施准备#

在开始制作发布版本之前,请使用 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 # 用于分类器和最低版本检查.

在针对 main 的普通 PR 中进行这些更改,并在必要时进行反向移植.在提交摘要的标题行末尾添加 [wheel build] ,以便运行 wheel 构建来测试更改.我们目前在第一个 Python rc 发布后,一旦 manylinux 和 cibuildwheel 支持,就会发布新 Python 版本的 wheel.对于 Python 3.11,我们能够在 rc1 发布后一周内发布.

反向移植 Pull Request#

已标记为此次发布的变更必须反向移植到 maintenance/2.1.x 分支.

更新 2.1.0 里程碑#

查看具有 2.1.0 里程碑的问题/PR,要么将它们推迟到以后的版本,要么删除里程碑.您可能需要添加一个里程碑.

创建发布 PR#

通常需要更新或创建四个文档用于发布 PR:

  • 变更日志

  • 发布说明

  • .mailmap 文件

  • .pyproject.toml 文件

这些更改应该在针对维护分支的普通 PR 中进行.提交标题应包含一个 [wheel build] 指令,以测试 wheel 是否构建成功.其他小的,杂项的修复可能属于此 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 存储库中的 fork.如果您没有 fork 存储库,而是简单地在本地克隆了存储库,则可能需要进行调整.您还可以编辑 .git/config 并添加 upstream (如果它尚未存在).

1. 准备发布提交#

检出发布的 branch,确保它是最新的,并清理存储库:

$ 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

标记 release 并推送 tag. 这需要对 numpy 存储库的写入权限:

$ git tag -a -s v2.1.0 -m"NumPy 2.1.0 release"
$ git push upstream v2.1.0

如果由于错误需要删除 tag:

$ git tag -d v2.1.0
$ git push --delete upstream v2.1.0

2. 构建 wheels#

在此过程开始时标记构建将通过 cibuildwheel 触发 wheel 构建,并将 wheels 和 sdist 上传到 staging 仓库.github actions 上的 CI 运行(适用于所有基于 x86 和 macOS arm64 的 wheels)大约需要 1 1/4 小时.cirrus 上的 CI 运行(适用于 aarch64 和 M1)花费的时间更少.您可以在 staging repository 检查上传的文件,但请注意,它与您看到的正在运行的作业没有密切同步.

如果希望手动触发 wheel 构建,您可以这样做:

  • 在 github actions -> Wheel builder 中,有一个 “Run workflow” 按钮,点击它并选择要构建的标签

  • 在 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 (<date>). 有两种添加文件的方式,使用可编辑的文本窗口和作为二进制上传.首先编辑使用 pandoc 从 rst 版本转换而来的 release/README.md .需要修复的内容:如果包含来自 changelog 的 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 repo 克隆到 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'

此外,更新 version-switcher 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 git@github.com: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 上发布公告(预发布版本跳过)#

这假设您已经 fork 了 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. 发布后更新 main(预发布版本跳过)#

检出 main 并向前移植文档更改.如果程序已经更改或改进,您可能还需要更新这些说明:

$ 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.

分支演练#

本指南包含在 Linux 上分支 NumPy 1.21.x 的演练.这些命令可以复制到命令行中,但请务必将 1.21 和 1.22 替换为正确的版本.最好在创建分支之前尽可能地更新 .mailmap ,这可能需要几周时间.

这应该与 general release guide 一起阅读.

分支#

创建分支#

仅在启动新的维护分支时才需要此操作.因为 NumPy 现在依赖于标签来确定版本,所以 main 分支中新开发周期的开始需要一个带注释的标签.具体操作如下:

$ 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

为进一步开发准备 main 分支#

创建一个 PR 分支,为进一步开发准备 main:

$ 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

现在创建一个 pull request.