Django 如何形成?

此文件說明如何發布 Django。

如果進行變更,請務必更新這些說明! 這裡的重點是要有描述性,而不是規定性的,所以請隨意簡化或進行其他變更,但請務必相應地更新此文件!

概觀

您可能需要進行三種版本的發布

  • 安全性發布:揭露並修復漏洞。這通常會涉及兩個或三個同時發布的版本,例如 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. 驗證套件簽名、檢查它們是否可以安裝,並確保最低限度的功能。

  6. 將新版本上傳至 PyPI。

  7. djangoproject.com 上的管理介面中宣告新版本。

  8. 發布部落格文章並發送電子郵件公告。

  9. 發布後更新版本號碼。

有很多細節,所以請繼續閱讀。

先決條件

在開始之前,您需要一些東西。如果這是您第一次發布,您需要與另一位發布者協調以準備好所有這些東西,並寫信給 Ops 郵件列表請求所需的存取權限。

  • 具有以下工具 (按字母順序) 的 Unix 環境

    • bash

    • git

    • GPG

    • make

    • man

    • 雜湊工具 (通常是 Linux 上的 md5sumsha1sumsha256sum,或是 macOS 上的 md5shasum)

    • python

    • ssh

  • GPG 金鑰對。確保此金鑰的私密部分安全地儲存。公開部分需要上傳到您的 GitHub 帳戶,以及執行「確認發布」工作的 Jenkins 伺服器。

    多個 GPG 金鑰

    如果您要使用的金鑰不是您的預設簽署金鑰,您需要在下面顯示的每個 GPG 簽署命令中新增 -u you@example.com,其中 you@example.com 是與您要使用的金鑰關聯的電子郵件地址。

  • 每個要發布的 Django 版本都有一個乾淨的 Python 虛擬環境,並安裝了這些必要的 Python 套件

    $ python -m pip install build twine
    
  • 存取 PyPI 上的 Django 專案 以上傳二進位檔案,理想情況下具有額外的權限,以便在必要時撤回發布。依照官方文件建立專案範圍的令牌,並設定您的 $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.
    
  • 存取 Transifex 上的 Django 專案,具有管理員角色。在使用者設定區段中產生 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 天 (或以上)

  1. 請求要發布的安全性問題的 CVE ID。每個問題一個 CVE ID,並使用 Vendor: djangoprojectProduct: django 請求。

  2. 使用 git format-patch 產生相關的 (私有) 修補程式,每個修補程式針對 main 分支以及每個要修補的穩定分支。

在安全性發布前一週

  1. 在安全性發布前整整一週發出預先通知。該電子郵件的範本和收件人清單位於私有的 django-security GitHub Wiki 中。將預先通知收件人密件副本,並務必包含相關的 CVE ID。附加所有相關的修補程式 (目標為 main 和穩定分支),並使用您將用於發布的金鑰簽署電子郵件文字,使用類似以下的命令

    $ gpg --clearsign --digest-algo SHA256 prenotification-email.txt
    
  2. 使用一般訊息 (例如以下) 通知 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://django-docs.dev.org.tw/en/dev/internals/security/#how-django-discloses-security-issues
    

在任何發布前幾天

  1. 隨著發布接近,請查看 Trac 以確保即將發布的版本沒有任何發布阻礙。

  2. 與其他合併者確認他們沒有任何未提交的發布變更。

  3. 校對發布說明,包括查看線上版本以找出任何損壞的連結或 reST 錯誤,並確保發布說明包含正確的日期。

  4. 仔細檢查發布說明是否提及任何已標記為已棄用之 API 的棄用時程,以及是否提及 Python 版本支援中的任何變更。

  5. 仔細檢查發布說明索引是否包含指向新版本說明的連結;這將位於 docs/releases/index.txt 中。

  6. 如果這是功能發布,請確保已整合來自 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)。

  7. 更新 django-admin 手冊頁面:

    $ 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
    

    然後提交變更的手冊頁面。

  8. 如果這是新系列的 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
    

    同時,更新穩定發布分支上 docs/conf.py 中的 django_next_version 變數,以指向新的開發版本。例如,在建立 stable/4.2.x 時,將新分支上的 django_next_version 設定為 '5.0'

  9. 如果這是新系列的「點零」版本發布,請在 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
    
  10. 撰寫發布公告的部落格文章。您可以隨時將其輸入到管理介面中,並將其標記為非啟用狀態。以下是一些範例:安全性發布公告範例一般發布公告範例預發布公告範例

實際執行發布

好的,這是有趣的部分,我們將實際推出發布版本!如果您要發布多個版本,請針對每個版本重複這些步驟。

  1. 檢查 Jenkins 對於您要發布的版本是否為綠色。在它變成綠色之前,您可能不應該發布版本,並且您應該確保最新的綠色運行包含您要發布的變更。

  2. 清理此版本的發行說明。在 main 中進行這些變更,並將其回溯移植到所有包含特定版本發行說明的分支。

    1. 對於功能發布,請移除發行說明頂部的 UNDER DEVELOPMENT 標頭,移除 Expected 前綴,並在必要時更新發布日期(範例提交)。

    2. 對於修補程式發布,請移除所有發布版本的 Expected 前綴,並在必要時更新發布日期(範例提交)。

  3. 發布總是從發布分支開始,因此您應該確保您位於最新的穩定分支上。此外,您應該為每個要發布的版本準備一個乾淨且專用的虛擬環境。例如:

    $ git checkout stable/4.1.x
    $ git pull
    
  4. 如果這是安全性發布,請合併來自 django-security 的適當修補程式。根據需要重新設定這些修補程式的基準,使每個修補程式成為發布分支上的一個簡單提交,而不是合併提交。為了確保這一點,請使用 --ff-only 旗標合併它們;例如:

    $ git checkout stable/4.1.x
    $ git merge --ff-only security/4.1.x
    

    (這假設 security/4.1.xdjango-security 儲存庫中的分支,其中包含 4.1 系列下一個版本的必要安全性修補程式。)

    如果 git 拒絕使用 --ff-only 合併,請切換到 security-patch 分支,並將其基準設定在您即將合併的分支上(git checkout security/4.1.x; git rebase stable/4.1.x),然後切換回來並進行合併。請確保每個安全性修復的提交訊息都說明該提交是一個安全性修復,並且將會發布公告(範例安全性提交)。

  5. 更新 django/__init__.py 中用於發布的版本號碼。請參閱下方關於 VERSION設定 VERSION 元組的注意事項範例提交)。

    1. 如果這是預發布套件,也請更新 pyproject.toml 中的「開發狀態」分類器以反映這一點。 rc 預發布不應變更分類器(alpha 版本發布的範例提交beta 版本發布的範例提交)。

    2. 否則,請確保分類器設定為 Development Status :: 5 - Production/Stable

  6. 使用 git tag 標記發布版本。例如:

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

    您可以執行 git tag --verify <tag> 來檢查您的工作。

  7. 推送您的工作和新的標籤

    $ git push
    $ git push --tags
    
  8. 執行 git clean -dfx 來確保您有一個絕對乾淨的樹狀結構。

  9. 執行 python -m build 來產生發布套件。這將在 dist/ 目錄中建立發布套件。

  10. 產生發布套件的雜湊值

    $ cd dist
    $ md5sum *
    $ sha1sum *
    $ sha256sum *
    
  11. 建立一個「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://djangoproject.dev.org.tw/m/releases/<<MAJOR VERSION>>/<<RELEASE TAR.GZ FILENAME>>
    https://djangoproject.dev.org.tw/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>>
    
  12. 簽署校驗和檔案 (gpg --clearsign --digest-algo SHA256 Django-<version>.checksum.txt)。這會產生一個已簽署的文件,Django-<version>.checksum.txt.asc,然後您可以使用 gpg --verify Django-<version>.checksum.txt.asc 驗證它。

使發布版本可供大眾使用

現在您已準備好實際發布版本。要做到這一點:

  1. 上傳校驗和檔案

    $ scp Django-A.B.C.checksum.txt.asc djangoproject.com:/home/www/www/media/pgp/Django-A.B.C.checksum.txt
    

    (如果這是安全性發布,則以下內容應在發布公告時間前 15 分鐘完成,不得更早。)

  2. 將發布套件上傳到 djangoproject 伺服器,將 A.B. 替換為適當的版本號碼,例如,對於 4.1.x 版本,則使用 4.1

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

    如果這是新系列的 alpha 版本,您需要首先建立目錄 A.B。

  3. 使用 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://djangoproject.dev.org.tw/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://djangoproject.dev.org.tw/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
    
  4. 在 Jenkins 上執行 confirm-release 建置,以驗證校驗和檔案(例如,對於 https://media.djangoproject.com/pgp/Django-4.2rc1.checksum.txt 使用 4.2rc1)。

  5. 將發布套件上傳到 PyPI(對於預發布,僅上傳 wheel 檔案)

    $ twine upload dist/*
    
  6. 前往管理介面中的新增發布頁面,輸入新的發布號碼,該號碼必須與 tarball 的名稱中顯示的號碼完全相同(Django-<version>.tar.gz)。因此,例如,輸入「4.1.1」或「4.2rc1」等。如果發布是 LTS 分支的一部分,請標記它。

    如果這是新系列的 alpha 版本,也請為最終發布建立一個發布物件,確保「發布日期」欄位為空白,從而將其標記為未發布。例如,當建立 4.2a1 的發布物件時,也建立「發布日期」欄位為空白的 4.2

  7. 使公告發布版本的部落格文章上線。

  8. 對於新的版本發布(例如 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
    
  9. 將發布公告發佈到 django-announcedjango-developersdjango-users 郵件清單和 Django 論壇。這應該包含指向公告部落格文章的連結。

  10. 如果這是安全性發布,請向 oss-security@lists.openwall.com 發送單獨的電子郵件。提供一個描述性主旨,例如,「Django」加上發行說明中的問題標題(包括 CVE ID)。訊息本文應包括漏洞詳細資訊,例如,公告部落格文章的文字。包含指向公告部落格文章的連結。

  11. #django IRC 頻道的主題中加入指向部落格文章的連結:/msg chanserv TOPIC #django new topic goes here

發布後

你幾乎完成了!現在剩下要做的就是

  1. 再次更新 django/__init__.py 中的 VERSION 元組,遞增到下一個預期的發佈版本。例如,在發佈 4.1.1 之後,將 VERSION 更新為 VERSION = (4, 1, 2, 'alpha', 0)

  2. 如有必要,請在 Trac 的版本列表中新增發佈版本(如果是最終版本,則將其設為預設版本,方法是變更 code.djangoproject.com 的 trac.ini 中的 default_version 設定)。新的 X.Y 版本應在 alpha 版本之後新增,而預設版本應在「點零」版本之後更新。

  3. 如果這是一個最終版本

    1. 更新 Trac 上 Django 發布流程中的目前穩定分支,並移除預發佈分支。

    2. 更新 djangoproject.com 的下載頁面(範例 PR)。

  4. 如果這是安全性發布版本,請使用已解決問題的詳細資訊更新安全性問題存檔

新的穩定分支任務

在建立新的穩定分支之後(通常在 alpha 版本發佈之後),有一些項目需要執行。其中一些任務不需要由發布者完成。

  1. docs.djangoproject.com 資料庫中為新版本的文件建立新的 DocumentRelease 物件,並更新 docs/fixtures/doc_releases.json JSON 夾具,以便沒有權限存取生產資料庫的人員仍然可以執行最新副本的文件網站(範例 PR)。

  2. 為新的功能版本建立一個存根發佈說明。使用上一個功能版本的存根,或複製上一個功能版本的內容,並刪除大部分內容,只留下標題。

  3. django.contrib.auth.hashers.PBKDF2PasswordHasher 中的預設 PBKDF2 迭代次數增加約 20%(選擇一個整數)。執行測試,並使用新值更新 3 個失敗的雜湊器測試。請確保在發布說明中記錄這一點(請參閱 4.1 發布說明的範例)。

  4. 移除已達到棄用週期結束的功能。為了清楚起見,每次移除都應在單獨的提交中完成。在提交訊息中,如果可能,請在原始票證中新增「refs #XXXX」,其中開始了棄用。

  5. 從兩個版本前的文件中移除 .. versionadded::.. versionchanged::.. deprecated:: 註解。例如,在 Django 4.2 中,將移除 4.0 的註解。

  6. 將新分支新增至 Read the Docs。由於自動產生的版本名稱(「stable-A.B.x」)與 Read the Docs 中使用的版本名稱(「A.B.x」)不同,因此請建立票證以請求新版本。

  7. 在 PyPI 上請求新的分類器。例如 Framework :: Django :: 3.1

  8. 更新正在積極開發中的目前分支,並在 Trac 上 Django 發布流程中新增預發佈分支。

關於設定 VERSION 元組的注意事項

Django 的版本報告由 django/__init__.py 中的 VERSION 元組控制。這是一個五個元素的元組,其元素為

  1. 主要版本。

  2. 次要版本。

  3. 微版本。

  4. 狀態 — 可以是「alpha」、「beta」、「rc」或「final」其中之一。

  5. 用於按順序執行的 alpha/beta/RC 套件的系列號(例如,允許「beta 1」、「beta 2」等)。

對於最終版本,狀態始終為「final」,系列號始終為 0。狀態為「alpha」的系列號 0 將報告為「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」

返回頂部