Django 是如何形成的?

本文档解释了如何释放Django。

Please, keep these instructions up-to-date if you make changes! 这里的重点是描述性的,而不是规定性的,所以请随意简化或以其他方式进行更改,但是 相应地更新此文档!

概述

您可能需要进行三种类型的发布:

  • 安全发布:披露和修复漏洞。这通常包括两个或三个同时发布的版本--例如3.2.x、4.0.x,根据时间的不同,可能还会发布4.1.x。

  • 常规版本发布:最终版本(如4.1)或错误修复更新(如4.1.1)。

  • 预发布:例如4.2 Alpha、Beta或RC。

所涉及步骤的简短版本是:

  1. 如果这是安全发布,请在实际发布前一周预先通知安全分发列表。

  2. 校对发行说明,查找组织和书写错误。起草博客文章和电子邮件通知。

  3. 更新版本号并创建发布包。

  4. 将包上载到 djangoproject.com 服务器。

  5. 验证包(S)签名,检查它们是否可以安装,并确保最低限度的功能。

  6. 将新版本上载到pypi。

  7. 在上的管理中声明新版本 djangoproject.com .

  8. 发布日志并发送电子邮件通知。

  9. 发布后更新版本号。

有很多细节,请继续阅读。

先决条件

在开始之前,您需要一些东西:

  • 一把GPG钥匙。如果要使用的密钥不是默认签名密钥,则需要添加 -u you@example.com 下面的每个GPG签名命令,其中 you@example.com 是与您要使用的密钥关联的电子邮件地址。您还需要添加 -i you@example.com 发送到 twine 打电话。

  • 安装一些必需的Python包:

    $ python -m pip install wheel twine
    
  • 访问Django在PyPI上的项目。属性创建项目范围内的令牌。 official documentation 并设置您的 $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.
    
  • 访问 djangoproject.com 上传文件的服务器。

  • 访问上的管理员 djangoproject.com 作为“现场维护人员”。

  • 访问Post to django-announce .

  • 如果这是安全发行版,请访问预通知分发列表。

如果这是您的第一个版本,您将需要与另一个版本发布者协调,以将所有这些事情整理好。

发布前任务

在开始发布过程之前,需要注意一些项目。这些工作大约在发布前一周开始;大部分工作可以在实际发布前的任何时间完成:

  1. 如果这是一个安全发布,发送预先通知 一星期 在释放之前。该电子邮件的模板和收件人列表是私有的 django-security Github维基密件抄送预通知收件人。使用发布时使用的密钥签署电子邮件,并包括 CVE IDs (要求供应商:DjangOproject,产品:Django)和正在修复的每个问题的补丁。也, notify django-announce 即将发布的安全性声明。

  2. 随着发布的临近,请观察trac以确保没有发布拦截器留给即将发布的版本。

  3. 与其他合并者核对,以确保他们没有任何未提交的版本更改。

  4. 校对发行说明,包括查看在线版本以 catch any broken links 或其他错误,并确保发行说明包含正确的日期。

  5. 仔细检查发行说明中是否提到了被否决的任何API的否决时间线,以及是否提到了Python版本支持中的任何更改。

  6. 再次检查发行说明索引是否有指向新发行说明的链接;这将在 docs/releases/index.txt .

  7. 如果这是一个功能版本,请确保已经集成了来自Tamerfex的翻译。这通常是由单独的翻译经理而不是发布者完成的,但以下是步骤。前提是您有一个Tamerfex帐户:

    $ python scripts/manage_translations.py fetch
    

    然后提交更改/添加的文件(两者 .po.mo )。有时会出现需要调试的验证错误,因此避免在需要发布之前立即执行此任务。

  8. Update the django-admin manual page

    $ 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
    

    然后提交更改的手册页。

  9. 如果这是新系列的Alpha版本,请从Main创建一个新的稳定分支。例如,在发布Django 4.2时:

    $ git checkout -b stable/4.2.x origin/main
    $ git push origin -u stable/4.2.x:stable/4.2.x
    

    同时,更新 django_next_version 中的变量 docs/conf.py 在稳定发布分支上指向新的开发版本。例如,在创建 stable/4.2.x ,设置 django_next_version'5.0' 在新的分支机构。

  10. 如果这是新系列的“点零”版本,请从 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
    

准备发布

撰写发布的公告日志。您可以随时将其输入管理员,并将其标记为不活动。以下是几个例子: `example security release announcement`_ _, `example regular release announcement`_ _, `example pre-release announcement`_ _.

实际滚动释放

好吧,这是有趣的部分,我们实际上推出了一个版本!

  1. 检查 `Jenkins`_ _对于您要发布的版本是绿色的。你可能不应该发布一个直到它是绿色的。

  2. 发布总是从一个发布分支开始,所以你应该确保你在一个稳定的分支上并且是最新的。例如:

    $ git checkout stable/4.1.x
    $ git pull
    
  3. 如果这是安全版本,请合并来自 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系列下一版本所需的安全补丁的Repo。)

    如果Git拒绝与 --ff-only ,切换到安全补丁分支,并将其重新设置为您要将其合并到的分支 (git checkout security/4.1.x; git rebase stable/4.1.x ),然后切换回并执行合并。确保每个安全修补程序的提交消息说明该提交是一个安全修补程序,并且随后会发出通知 (example security commit )。

  4. 对于功能版本,请删除 UNDER DEVELOPMENT 在发布说明的顶部添加标题,并在下一行添加发布日期。对于补丁程序版本,请删除 Expected 如有必要,添加前缀并更新发布日期。在特定版本的发行说明所在的所有分支上进行此更改。

  5. 更新中的版本号 django/__init__.py 发布。请看 notes on setting the VERSION tuple 以下为详细信息 VERSION .

  6. 如果这是预发布包,请在中更新“开发状态”trove分类器 setup.cfg 以反映这一点。否则,请确保分类器设置为 Development Status :: 5 - Production/Stable .

  7. 使用以下命令标记版本 git tag 。例如:

    $ git tag --sign --message="Tag 4.1.1" 4.1.1
    

    你可以通过运行来检查你的工作 git tag --verify <tag> .

  8. 推动你的工作,包括标签: git push --tags .

  9. 确保你有一棵绝对干净的树 git clean -dfx .

  10. 运行 make -f extras/Makefile 生成发布包。这将在 dist/ 目录。

  11. 生成版本包的哈希:

    $ cd dist
    $ md5sum *
    $ sha1sum *
    $ sha256sum *
    
  12. 创建一个“校验和”文件, 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://www.djangoproject.com/m/releases/<<MAJOR VERSION>>/<<RELEASE TAR.GZ FILENAME>>
    https://www.djangoproject.com/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>>
    
  13. 签署校验和文件 (gpg --clearsign --digest-algo SHA256 Django-<version>.checksum.txt )这将生成已签名的文档, Django-<version>.checksum.txt.asc 然后您可以使用 gpg --verify Django-<version>.checksum.txt.asc .

如果要发布多个版本,请对每个版本重复这些步骤。

向公众发布

现在你已经准备好把释放装置放在那里了。这样做:

  1. 将发布包(S)上传到djangoproject服务器,用适当的版本号替换A.B.,例如4.1x版本:

    $ scp Django-* djangoproject.com:/home/www/www/media/releases/A.B
    

    如果这是一个新系列的alpha版本,则需要创建目录a.B。

  2. 上传校验和文件(S):

    $ scp Django-A.B.C.checksum.txt.asc djangoproject.com:/home/www/www/media/pgp/Django-A.B.C.checksum.txt
    
  3. 使用以下命令测试发行包是否正确安装 pip 。这里有一种方法:

    $ RELEASE_VERSION='4.1.1'
    $ MAJOR_VERSION=`echo $RELEASE_VERSION| cut -c 1-3`
    
    $ python -m venv django-pip
    $ . django-pip/bin/activate
    $ python -m pip install https://www.djangoproject.com/m/releases/$MAJOR_VERSION/Django-$RELEASE_VERSION.tar.gz
    $ deactivate
    $ python -m venv django-pip-wheel
    $ . django-pip-wheel/bin/activate
    $ python -m pip install https://www.djangoproject.com/m/releases/$MAJOR_VERSION/Django-$RELEASE_VERSION-py3-none-any.whl
    $ deactivate
    

    这只是测试tarballs是否可用(即重定向是否启动)以及它们是否正确安装,但它会捕获愚蠢的错误。

  4. 运行 `confirm-release`__ 以Jenkins为基础验证校验和文件(S)(例如,使用 4.2rc1 适用于https://media.djangoproject.com/pgp/Django-4.2rc1.checksum.txt).

  5. 将发布包上传到PYPI(对于预发布,仅上传轮子文件):

    $ twine upload -s dist/*
    
  6. 转到 `Add release page in the admin`_ _,输入与tarball名称中显示的完全相同的新版本号 (Django-<version>.tar.gz )。例如,输入“4.1.1”或“4.2rc1”等。如果版本是LTS分支的一部分,则将其标记为“4.1.1”。

    如果这是新系列的Alpha版本,还要为 final 释放,确保 Release date 字段为空,因此将其标记为 unreleased 。例如,为创建Release对象时 4.2a1 ,还可以创建 4.2 释放日期字段为空。

  7. 使发布的博客文章实时发布。

  8. 对于新版本(例如4.1、4.2),通过翻转 is_default 标志为 True 在适当的情况下 DocumentRelease 对象中的 docs.djangoproject.com 数据库(这会自动将其翻转到 False 对于所有其他用户);您可以使用站点的管理员来完成此操作。

    创造新 DocumentRelease objects for each language that has an entry for the previous release. Update djangoproject.com's `robots.docs.txt`__ 通过将条目复制到 manage_translations.py robots_txt 中的当前稳定分支 django-docs-translations 存储库。例如,在发布Django 4.2时:

    $ git checkout stable/4.2.x
    $ git pull
    $ python manage_translations.py robots_txt
    
  9. 将发布公告发布到|Django-宣告|、django-developers|Django-User|邮件列表和Django论坛。这应该包括一个到公告博客帖子的链接。

  10. 如果这是安全发布,请单独发送电子邮件至oss-security@lists.openwall.com。提供一个描述性主题,例如,“Django”加上发行说明中的问题标题(包括CVE ID)。博文正文应包括公告正文、漏洞详情等。包括公告博客文章的链接。

  11. 在的主题中添加指向博客文章的链接 #django IRC通道: /msg chanserv TOPIC #django new topic goes here .

释放后

你快完成了!现在只剩下:

  1. 更新 VERSION 元组输入 django/__init__.py 再一次,递增到下一个预期的版本。例如,在发布4.1.1之后,更新 VERSIONVERSION = (4, 1, 2, 'alpha', 0)

  2. 添加发布 Trac's versions list 如果需要(并通过更改 default_version 设置在代码:djangoproject.com的 `trac.ini`_ _,如果是最终版本)。新的X.Y版本应该在alpha版本之后添加,默认版本应该在“dotzero”发布之后更新。

  3. 如果是最终版本,请更新当前的稳定分支,并删除 Django release process 在Trac上。

  4. 如果这是一个安全版本,请更新 安全问题档案 解决问题的细节。

新的稳定分支任务

在创建一个新的稳定分支之后(通常在alpha发布之后),有几个项目需要在时间内完成。其中一些任务不需要由发布者完成。

  1. 创建新的 DocumentRelease 对象中 docs.djangoproject.com 新版本文档的数据库,并更新 docs/fixtures/doc_releases.json JSON夹具,因此没有访问生产数据库的人仍然可以运行docs站点的最新副本。

  2. 为新功能版本创建存根发行说明。使用上一个功能发布版本的存根,或者复制上一个功能版本的内容,删除大部分只留下标题的内容。

  3. 增加中的默认PBKDF2迭代次数 django.contrib.auth.hashers.PBKDF2PasswordHasher 大约20%(挑一个整数)。运行测试,并使用新值更新3个失败的散列器测试。确保在发行说明中注明这一点(有关示例,请参阅4.1发行说明)。

  4. 删除已达到其折旧周期结束的功能。为清晰起见,每次删除都应单独提交。在提交消息中,将“refs XXXX”添加到原始记录单中,如果可能,将在原始记录单中开始取消预测。

  5. 移除 .. versionadded::.. versionadded:: ,以及 .. deprecated:: 两个版本之前的文档中的注释。例如,在Django 4.2中,4.0的注释将被删除。

  6. 将新分支添加到 Read the Docs 。由于自动生成的版本名称(“STRATE-A.B.x”)不同于在读取文档中使用的版本名称(“A.B.x”), create a ticket 正在请求新版本。

  7. Request the new classifier on PyPI <https://github.com/pypa/trove-classifiers/issues/29> _. 例如 Framework :: Django :: 3.1 .

  8. 更新Active Development下的当前分支,并在 Django release process 在Trac上。

关于设置版本元组的说明

Django的版本报告由 VERSION 元组 django/__init__.py . 这是一个五元素元组,其元素为:

  1. 主要版本。

  2. 次要版本。

  3. 微版本。

  4. 状态——可以是“alpha”、“beta”、“rc”或“final”之一。

  5. 序列号,用于按顺序运行的alpha/beta/rc包(例如允许“beta 1”、“beta 2”等)。

对于最终版本,状态始终为“最终”,序列号始终为0。状态为“alpha”的序列号0将报告为“pre alpha”。

一些例子:

  • (4, 1, 1, "final", 0) →“4.1.1”

  • (4, 2, 0, "alpha", 0) →“4.2Pre-Alpha”

  • (4, 2, 0, "beta", 1) →“4.2测试版1”