Django 是如何形成的?¶
本文档说明了如何发布 Django。
如果您进行了更改,请务必更新这些说明!这里的重点是描述性,而不是规定性,因此请随意简化或进行其他更改,但相应地更新本文档!
概述¶
您可能需要进行三种类型的发布
安全发布:披露和修复漏洞。这通常涉及两个或三个同时发布 - 例如 3.2.x、4.0.x,以及根据时间,可能还有 4.1.x。
常规版本发布:最终版本(例如 4.1)或错误修复更新(例如 4.1.1)。
预发布:例如 4.2 alpha、beta 或 rc。
相关步骤的简短版本如下
如果这是安全发布,则在实际发布前一周预先通知安全分发列表。
校对发行说明,查找组织和写作错误。起草一篇博客文章和电子邮件公告。
更新版本号并创建发布包。
将包上传到
djangoproject.com
服务器。验证包签名,检查是否可以安装它们,并确保最基本的功能。
将新版本上传到 PyPI。
在
djangoproject.com
上的管理员中声明新版本。发布博客文章并发送电子邮件公告。
发布后更新版本号。
有很多细节,所以请继续阅读。
先决条件¶
在开始之前,您需要一些东西。如果这是您的第一次发布,您需要与另一位发布者协调以将所有这些内容安排好,并写信给 Ops 邮件列表请求所需的访问权限和许可。
具有以下已安装工具的 Unix 环境(按字母顺序排列)
bash
git
GPG
make
man
哈希工具(通常在 Linux 上为
md5sum
、sha1sum
和sha256sum
,或在 macOS 上为md5
和shasum
)python
ssh
一个 GPG 密钥对。确保此密钥的私钥安全存储。公钥需要上传到您的 GitHub 帐户,以及运行“确认发布”作业的 Jenkins 服务器。
多个 GPG 密钥
如果您要使用的密钥不是您的默认签名密钥,则需要在下面显示的每个 GPG 签名命令中添加
-u you@example.com
,其中you@example.com
是您要使用的密钥关联的电子邮件地址。每个要发布的 Django 版本的干净 Python 虚拟环境,并安装了以下所需的 Python 包
$ python -m pip install build twine
访问 Django 在 PyPI 上的项目 以上传二进制文件,理想情况下具有额外权限来 撤销发布(如有必要)。按照 官方文档 创建一个项目范围的令牌,并像这样设置您的
$HOME/.pypirc
文件~/.pypirc
¶[distutils] index-servers = pypi django [pypi] username = __token__ password = # User-scoped or project-scoped token, to set as the default. [django] repository = https://upload.pypi.org/legacy/ username = __token__ password = # A project token.
访问 Django 在 Transifex 上的项目,并具有管理员角色。在 用户设置部分 生成一个 API 令牌,并像这样设置您的
$HOME/.transifexrc
文件~/.transifexrc
¶[https://www.transifex.com] rest_hostname = https://rest.api.transifex.com token = # API token
访问
djangoproject.com
服务器以上传文件(使用scp
)。以“站点维护者”身份访问
djangoproject.com
上的 Django 管理员。访问在 Django 论坛 - 公告类别 中创建帖子,并向以下邮件列表发送电子邮件
访问 GitHub 中的
django-security
存储库。除其他事项外,这还提供对预通知分发列表的访问权限(安全发布准备任务需要)。
预发布任务¶
在开始发布过程之前,需要处理一些事项。这些事情在发布前大约一周开始;大部分可以在发布前的任何时间完成。
安全发布前 10 天(或更多)¶
请求正在发布的安全问题的 CVE ID。每个问题一个 CVE ID,使用
Vendor: djangoproject
和Product: django
请求。使用
git format-patch
生成相关的(私有)补丁,一个用于main
分支,一个用于每个正在修补的稳定分支。
安全发布前一周¶
在安全发布前正好一周发送预通知。该电子邮件的模板和收件人列表位于私有的
django-security
GitHub wiki 中。将预通知收件人加入密件抄送,并确保包含相关的 CVE ID。附加所有相关的补丁(针对main
和稳定分支),并使用您将用于发布的密钥对电子邮件文本进行签名,使用以下命令$ gpg --clearsign --digest-algo SHA256 prenotification-email.txt
通知 django-announce 即将来临的安全发布,并发送如下通用消息
Notice of upcoming Django security releases (3.2.24, 4.2.10 and 5.0.2) Django versions 5.0.2, 4.2.10, and 3.2.24 will be released on Tuesday, February 6th, 2024 around 1500 UTC. They will fix one security defect with severity "moderate". For details of severity levels, see: https://docs.djangopy.cn/en/dev/internals/security/#how-django-discloses-security-issues
任何发布前几天¶
随着发布的临近,监视 Trac 以确保即将发布的版本中没有剩余的发布阻碍因素。
与其他合并者核实,确保他们没有对发布进行任何未提交的更改。
校对发行说明,包括查看联机版本以 捕获任何断开的链接 或 reST 错误,并确保发行说明包含正确的日期。
仔细检查发行说明中是否提到了任何标记为已弃用的 API 的弃用时间表,以及它们是否提到了 Python 版本支持的任何更改。
仔细检查发行说明索引中是否包含指向新版本说明的链接;这将在
docs/releases/index.txt
中。如果这是 功能发布,请确保已集成 Transifex 的翻译。这通常由单独的翻译管理者而不是发布者完成,但以下是步骤。此过程有点冗长,因此请务必留出 4-10 个小时来执行此操作,并且最好在发布日期前一两天计划此任务。
除了拥有已配置的 Transifex 帐户外,tx CLI 应该在您的
PATH
中可用。然后,您可以通过运行以下命令获取所有翻译$ python scripts/manage_translations.py fetch
此命令需要一些时间才能运行。完成后,仔细检查输出以查找潜在的错误和/或警告。如果存在一些错误和/或警告,则需要逐一调试和解决它们。
最近获取的翻译需要一些手动调整。首先,必须手动将
PO-Revision-Date
值更改为晚于POT-Creation-Date
。您可以使用类似以下的命令批量更新所有.po
文件(将差异与相关的稳定分支进行比较)$ git diff --name-only stable/5.0.x | grep "\.po" | xargs sed -ri "s/PO-Revision-Date: [0-9\-]+ /PO-Revision-Date: $(date -I) /g"
所有新的
.po
文件都应该手动仔细检查,以避免在没有任何新翻译的文件中提交更改。此外,“复数形式”中不应该有任何更改:如果有任何更改(通常西班牙语和法语会报告此类更改),则需要将其还原。最后,提交更改/添加的文件(包括
.po
和.mo
),并创建一个新的 PR,目标是对应版本的稳定分支(例如 更新 4.2 版本翻译的 PR)。-
$ cd docs $ make man $ man _build/man/django-admin.1 # do a quick sanity check $ cp _build/man/django-admin.1 man/django-admin.1
然后提交更改后的手册页面。
如果这是新系列的 alpha 版本,则从主分支创建一个新的稳定分支。例如,在发布 Django 4.2 时
$ git checkout -b stable/4.2.x origin/main $ git push origin -u stable/4.2.x:stable/4.2.x
同时,在稳定发布分支上的
docs/conf.py
中更新django_next_version
变量,使其指向新的开发版本。例如,在创建stable/4.2.x
时,在新分支上将django_next_version
设置为'5.0'
。如果这是新系列的“dot zero”版本,则从 django-docs-translations 存储库中的当前稳定分支创建一个新分支。例如,在发布 Django 4.2 时
$ git checkout -b stable/4.2.x origin/stable/4.1.x $ git push origin stable/4.2.x:stable/4.2.x
编写发布公告博文。您可以随时将其输入管理员并将其标记为无效。以下是一些示例:安全版本公告示例、常规版本公告示例、预发布公告示例。
实际发布版本¶
好的,这是有趣的部分,我们实际上要发布一个版本了!如果您要发布**多个版本**,请对每个版本重复这些步骤。
检查 Jenkins 是否对您要发布的版本显示绿色。在显示绿色之前,您可能不应该发布版本,并且您应该确保最新的绿色运行包含您要发布的更改。
清理此版本的发布说明。在
main
中进行这些更改,并回传到包含特定版本发布说明的所有分支。版本总是从发布分支开始,因此您应该确保您在最新的稳定分支上。此外,您应该为每个要发布的版本提供一个干净且专用的虚拟环境。例如
$ git checkout stable/4.1.x $ git pull
如果这是安全版本,请合并来自
django-security
的相应补丁。根据需要重新设置这些补丁的基础,使每个补丁在发布分支上成为一个简单的提交,而不是合并提交。为了确保这一点,请使用--ff-only
标志合并它们;例如$ git checkout stable/4.1.x $ git merge --ff-only security/4.1.x
(假设
security/4.1.x
是django-security
存储库中的一个分支,其中包含 4.1 系列中下一个版本的必要安全补丁。)如果 git 拒绝使用
--ff-only
合并,请切换到安全补丁分支并在要将其合并到的分支上重新设置其基础(git checkout security/4.1.x; git rebase stable/4.1.x
),然后切换回来并进行合并。确保每个安全修复的提交消息说明该提交是安全修复,并且将会有一个公告(安全提交示例)。更新发布版本的
django/__init__.py
中的版本号。有关VERSION
的详细信息,请参阅下面的设置 VERSION 元组的说明(提交示例)。如果这是预发布包,也更新
pyproject.toml
中的“Development Status” trove 分类器以反映这一点。rc
预发布不应该更改 trove 分类器(alpha 版本提交示例、beta 版本提交示例)。否则,请确保分类器设置为
Development Status :: 5 - Production/Stable
。
使用
git tag
标记发布版本。例如$ git tag --sign --message="Tag 4.1.1" 4.1.1
您可以运行
git tag --verify <tag>
检查您的工作。推送您的工作和新标签
$ git push $ git push --tags
通过运行
git clean -dfx
确保您的树绝对干净。运行
python -m build
生成发布包。这将在dist/
目录中创建发布包。生成发布包的哈希值
$ cd dist $ md5sum * $ sha1sum * $ sha256sum *
创建一个“checksums”文件,
Django-<<VERSION>>.checksum.txt
,其中包含哈希值和发布信息。从此模板开始,并插入正确的版本、日期、GPG 密钥 ID(来自gpg --list-keys --keyid-format LONG
)、发布管理者的 GitHub 用户名、发布 URL 和校验和This file contains MD5, SHA1, and SHA256 checksums for the source-code tarball and wheel files of Django <<VERSION>>, released <<DATE>>. To use this file, you will need a working install of PGP or other compatible public-key encryption software. You will also need to have the Django release manager's public key in your keyring. This key has the ID ``XXXXXXXXXXXXXXXX`` and can be imported from the MIT keyserver, for example, if using the open-source GNU Privacy Guard implementation of PGP: gpg --keyserver pgp.mit.edu --recv-key XXXXXXXXXXXXXXXX or via the GitHub API: curl https://github.com/<<RELEASE MANAGER GITHUB USERNAME>>.gpg | gpg --import - Once the key is imported, verify this file: gpg --verify <<THIS FILENAME>> Once you have verified this file, you can use normal MD5, SHA1, or SHA256 checksumming applications to generate the checksums of the Django package and compare them to the checksums listed below. Release packages ================ https://djangopy.cn/m/releases/<<MAJOR VERSION>>/<<RELEASE TAR.GZ FILENAME>> https://djangopy.cn/m/releases/<<MAJOR VERSION>>/<<RELEASE WHL FILENAME>> MD5 checksums ============= <<MD5SUM>> <<RELEASE TAR.GZ FILENAME>> <<MD5SUM>> <<RELEASE WHL FILENAME>> SHA1 checksums ============== <<SHA1SUM>> <<RELEASE TAR.GZ FILENAME>> <<SHA1SUM>> <<RELEASE WHL FILENAME>> SHA256 checksums ================ <<SHA256SUM>> <<RELEASE TAR.GZ FILENAME>> <<SHA256SUM>> <<RELEASE WHL FILENAME>>
签署校验和文件(
gpg --clearsign --digest-algo SHA256 Django-<version>.checksum.txt
)。这会生成一个签名的文档Django-<version>.checksum.txt.asc
,然后您可以使用gpg --verify Django-<version>.checksum.txt.asc
验证它。
使发布版本对公众可用¶
现在您已准备好实际发布版本了。为此
上传校验和文件
$ scp Django-A.B.C.checksum.txt.asc djangoproject.com:/home/www/www/media/pgp/Django-A.B.C.checksum.txt
(如果这是安全版本,则以下操作应在宣布的发布时间前 15 分钟完成,不得提前。)
将发布包上传到 djangoproject 服务器,将 A.B. 替换为相应的版本号,例如 4.1.x 版本的 4.1
$ scp Django-* djangoproject.com:/home/www/www/media/releases/A.B
如果这是新系列的 alpha 版本,则需要**首先**创建目录 A.B。
使用
pip
测试发布包是否可以正确安装。这是一种简单的方法(这仅测试二进制文件是否可用、是否可以正确安装以及迁移和开发服务器是否启动,但它可以捕获愚蠢的错误)$ RELEASE_VERSION='4.1.1' $ MAJOR_VERSION=`echo $RELEASE_VERSION| cut -c 1-3` $ python -m venv django-pip-tarball $ . django-pip-tarball/bin/activate $ python -m pip install https://djangopy.cn/m/releases/$MAJOR_VERSION/Django-$RELEASE_VERSION.tar.gz $ django-admin startproject test_tarball $ cd test_tarball $ ./manage.py --help # Ensure executable bits $ python manage.py migrate $ python manage.py runserver <CTRL+C> $ deactivate $ cd .. && rm -rf test_tarball && rm -rf django-pip-tarball $ python -m venv django-pip-wheel $ . django-pip-wheel/bin/activate $ python -m pip install https://djangopy.cn/m/releases/$MAJOR_VERSION/Django-$RELEASE_VERSION-py3-none-any.whl $ django-admin startproject test_wheel $ cd test_wheel $ ./manage.py --help # Ensure executable bits $ python manage.py migrate $ python manage.py runserver <CTRL+C> $ deactivate $ cd .. && rm -rf test_wheel && rm -rf django-pip-wheel
在 Jenkins 上运行 confirm-release 构建以验证校验和文件(例如,对 https://media.djangoproject.com/pgp/Django-4.2rc1.checksum.txt 使用
4.2rc1
)。将发布包上传到 PyPI(对于预发布版本,仅上传 wheel 文件)
$ twine upload dist/*
转到 管理员中的添加版本页面,准确输入与 tarball 名称中显示的新版本号相同(
Django-<version>.tar.gz
)。例如,输入“4.1.1”或“4.2rc1”等。如果版本是 LTS 分支的一部分,请将其标记出来。如果这是新系列的 alpha 版本,也为最终版本创建一个版本对象,确保版本日期字段为空,从而将其标记为未发布。例如,在为
4.2a1
创建版本对象时,也创建版本日期字段为空的4.2
。发布发布公告博文。
对于新版本发布(例如 4.1、4.2),通过在
docs.djangoproject.com
数据库中适当的DocumentRelease
对象上将is_default
标志翻转为True
来更新文档的默认稳定版本(这将自动将其对所有其他版本翻转为False
);您可以使用站点的管理员执行此操作。为每种具有前一个版本条目的语言创建新的
DocumentRelease
对象。通过复制在 django-docs-translations 存储库中来自当前稳定分支中运行命令manage_translations.py robots_txt
生成的结果来更新 djangoproject.com 的 robots.docs.txt 文件。例如,在发布 Django 4.2 时$ git checkout stable/4.2.x $ git pull $ python manage_translations.py robots_txt
将发布公告发布到 django-announce、django-developers、django-users 邮件列表和 Django 论坛。这应该包含指向公告博客文章的链接。
如果这是一个安全版本,请发送一封单独的邮件到 oss-security@lists.openwall.com。提供一个描述性的主题,例如,“Django”加上发行说明中的问题标题(包括 CVE ID)。邮件正文应包含漏洞详细信息,例如公告博客文章文本。包含指向公告博客文章的链接。
在
#django
IRC 频道的话题中添加指向博客文章的链接:/msg chanserv TOPIC #django new topic goes here
。
发布后¶
你快完成了!现在剩下的就是
再次更新
django/__init__.py
中的VERSION
元组,将其递增到下一个预期版本。例如,在发布 4.1.1 后,将VERSION
更新为VERSION = (4, 1, 2, 'alpha', 0)
。如有必要,在 Trac 的版本列表 中添加该版本(并在代码中更改
default_version
设置将其设置为默认版本,如果这是一个最终版本)。新的 X.Y 版本应在 alpha 版本之后添加,并且默认版本应在“点零”版本之后更新。如果这是一个最终版本
在 Trac 上的 Django 发布流程 中更新当前稳定分支并删除预发布分支。
更新 djangoproject.com 的下载页面(示例 PR)。
如果这是一个安全版本,请使用已解决问题的详细信息更新 安全问题档案。
新的稳定分支任务¶
在创建新的稳定分支(通常在 alpha 版本发布后)之后,有一些项目需要执行。其中一些任务不需要由发布者完成。
在
docs.djangoproject.com
数据库中为新版本的文档创建一个新的DocumentRelease
对象,并更新docs/fixtures/doc_releases.json
JSON 固定文件,以便没有访问权限的人员生产数据库的人员仍然可以运行文档网站的最新副本(示例 PR)。为新的功能版本创建一个存根发行说明。使用上一个功能版本的存根或复制上一个功能版本的内容,并删除大部分内容,只保留标题。
在
django.contrib.auth.hashers.PBKDF2PasswordHasher
中将默认的 PBKDF2 迭代次数增加大约 20%(选择一个整数)。运行测试,并使用新值更新 3 个失败的散列器测试。确保在发行说明中注明这一点(请参阅 4.1 发行说明以了解示例)。删除已达到其弃用周期结束的功能。为了清楚起见,每个删除操作都应在单独的提交中完成。在提交消息中,如果可能,请添加“refs #XXXX”到最初的弃用工单。
从文档中删除两个版本之前的
.. versionadded::
、.. versionchanged::
和.. deprecated::
注释。例如,在 Django 4.2 中,将删除 4.0 的注释。将新分支添加到 Read the Docs。由于自动生成的版本名称(“stable-A.B.x”)与 Read the Docs 中使用的版本名称(“A.B.x”)不同,因此请 创建工单 请求新版本。
在 PyPI 上请求新的分类器。例如
Framework :: Django :: 3.1
。更新当前正在开发的分支,并在 Trac 上的 Django 发布流程 中添加预发布分支。
关于设置 VERSION 元组的说明¶
Django 的版本报告由 django/__init__.py
中的 VERSION
元组控制。这是一个五元素元组,其元素为
主版本。
次版本。
微版本。
状态 - 可以是“alpha”、“beta”、“rc”或“final”之一。
系列号,用于按顺序运行的 alpha/beta/RC 包(例如,允许“beta 1”、“beta 2”等)。
对于最终版本,状态始终为“final”,系列号始终为 0。系列号为 0 且状态为“alpha”将报告为“pre-alpha”。
一些示例
(4, 1, 1, "final", 0)
→ “4.1.1”(4, 2, 0, "alpha", 0)
→ “4.2 pre-alpha”(4, 2, 0, "beta", 1)
→ “4.2 beta 1”