維護者資訊#

發佈#

本節說明如何準備主要/次要版本、候選發行版 (RC) 或錯誤修復版本。我們遵循 PEP440 來制定版本方案並指示不同類型的發佈。我們的慣例是遵循「major.minor.micro」方案,儘管實際上主要版本和次要版本之間沒有根本區別,而微發佈是錯誤修復版本。

我們採用了以下發佈排程

  • 主要/次要版本每 6 個月發佈一次,通常在 5 月和 11 月。這些版本的編號為 X.Y.0,並且前面會有一個或多個候選發行版本 X.Y.0rcN

  • 錯誤修復版本會在主要/次要版本之間根據需要進行發佈,並且僅適用於最後一個穩定版本。這些版本的編號為 X.Y.Z

準備工作

  • 確認里程碑中標記的所有封鎖器都已解決,並且里程碑中標記的其他問題可以延後處理。

  • 確保已處理發佈中標記的棄用、FIXME 和 TODO。

  • 對於主要/次要最終版本,請確保已完成「發佈重點」頁面作為可執行範例,並檢查其 HTML 渲染是否正確。它應該從 scikit-learn 新版本的新增內容檔案中連結。

權限

  • 發佈管理員必須是 scikit-learn/scikit-learn 儲存庫的維護者,才能在 pypi.orgtest.pypi.org 上發佈(透過手動觸發專用的 Github Actions 工作流程)。

  • 發佈管理員必須是 conda-forge/scikit-learn-feedstock 儲存庫的維護者,才能在 conda-forge 上發佈。可以透過編輯第一個發佈提取請求中的 recipe/meta.yaml 檔案來變更此設定。

參考步驟#

假設我們正在準備發佈 1.6.0rc1

第一個 RC 理想情況下應視為功能凍結。每個即將到來的候選發行版和之後的最終發行版都應僅包含次要文件變更和錯誤修復。任何主要增強功能或新功能都應排除在外。

  • 直接在主儲存庫中建立發佈分支 1.6.X,其中 X 實際上是字母 X,而不是佔位符1.6 的最終和後續錯誤修復版本的開發也應在此分支下使用不同的標籤進行。

    git fetch upstream main
    git checkout upstream/main
    git checkout -b 1.6.X
    git push --set-upstream upstream 1.6.X
    
  • 建立以 1.6.X 分支為目標的 PR。將以下發佈檢查表複製到此 PR 的描述中,以追蹤進度。

    * [ ] Update the sklearn dev0 version in main branch
    * [ ] Set the version number in the release branch
    * [ ] Check that the wheels for the release can be built successfully
    * [ ] Merge the PR with `[cd build]` commit message to upload wheels to the staging repo
    * [ ] Upload the wheels and source tarball to https://test.pypi.org
    * [ ] Create tag on the main repo
    * [ ] Confirm bot detected at https://github.com/conda-forge/scikit-learn-feedstock
          and wait for merge
    * [ ] Upload the wheels and source tarball to PyPI
    * [ ] Update news and what's new date in main branch
    * [ ] Backport news and what's new date in release branch
    * [ ] Announce on mailing list and on LinkedIn, Bluesky, Twitter
    
  • main 建立以 main 為目標的 PR,以遞增 sklearn/__init__.py 中的 dev0 __version__ 變數。這表示當我們處於候選發行版期間時,最新的穩定版本比 main 分支落後兩個版本,而不是一個。在此以 main 為目標的 PR 中,您還應該在 doc/whats_new/ 目錄下包含一個新的新增內容檔案,以便我們為下一個版本準備變更日誌。

  • 在發佈分支中,將 sklearn/__init__.py 中的版本號碼 __version__ 變更為 1.6.0rc1

  • 使用 [cd build] 提交標記觸發 wheel 建置器。另請參閱 wheel 建置器的工作流程執行

    git commit --allow-empty -m "[cd build] Trigger wheel builder workflow"
    

    注意

    [cd build] 中的縮寫 CD 代表 持續交付,並指用於產生發佈成品(二進位和原始碼套件)的自動化。這可以視為 CI 的延伸,CI 代表 持續整合。GitHub Actions 上的 CD 工作流程也用於自動建立每晚建置,並發佈 scikit-learn 開發分支的套件。另請參閱 安裝每晚建置

  • 一旦所有 CD 工作在 PR 中成功完成,請使用提交訊息中的 [cd build] 標記合併它。這次結果將上傳到暫存區。然後您應該可以使用 PyPI 發佈工作流程的「執行工作流程」表單,將產生的成品(.tar.gz.whl 檔案)上傳到 https://test.pypi.org/

    警告

    此 PR 應使用重新建立基準模式而不是常用的壓縮模式合併,因為我們希望保持 1.6.X 分支中的歷史記錄接近主分支的歷史記錄,這將有助於未來錯誤修復版本的發佈。

    此外,如果在合併時,包含 [cd build] 標記的最後一次提交是空的,則不會觸發 CD 工作。在這種情況下,您可以直接在 1.6.X 分支中推送一個包含標記的提交以觸發它們。

  • 如果上述步驟都順利完成,請謹慎地為發佈建立新標籤。只有在您幾乎確定發佈已準備就緒時才應執行此操作,因為在主儲存庫中新增新標籤可能會觸發某些自動化流程。

    git tag -a 1.6.0rc1  # in the 1.6.X branch
    git push git@github.com:scikit-learn/scikit-learn.git 1.6.0rc1
    

    警告

    不要使用 github 介面發佈版本作為建立標籤的方式,因為它會自動向所有追蹤儲存庫的使用者傳送通知,即使網站尚未更新且 wheels 尚未上傳。

  • 確認機器人已在 conda-forge feedstock 儲存庫 conda-forge/scikit-learn-feedstock 上偵測到標籤。如果沒有,請提交針對 rc 分支的發佈 PR。

  • 再次觸發 PyPI 發佈工作流程,但這次是將成品上傳到真正的 https://pypi.org/。為此,請在「執行工作流程」表單中將 testpypi 替換為 pypi

    或者,可以從本機收集產生的二進位 wheel 套件和原始碼壓縮檔,並將它們全部上傳到 PyPI。

    從本機上傳成品#

    在發佈標籤處取出並執行以下命令。

    rm -r dist
    python -m pip install -U wheelhouse_uploader twine
    python -m wheelhouse_uploader fetch \
      --version 1.6.0rc1 --local-folder dist scikit-learn \
      https://pypi.anaconda.org/scikit-learn-wheels-staging/simple/scikit-learn/
    

    這些命令會下載累積在 anaconda.org 託管服務上的暫存區中的所有二進位套件,並將它們放入您本機的 ./dist 資料夾中。檢查 ./dist 資料夾的內容:它應該包含所有 wheels 以及原始碼壓縮檔 .tar.gz。請確保該資料夾中沒有開發人員版本或舊版本的 scikit-learn 套件。在上傳到 PyPI 之前,您可以先測試上傳到 test.pypi.org

    twine upload --verbose --repository-url https://test.pypi.org/legacy/ dist/*
    

    然後一次將所有內容上傳到 pypi.org

    twine upload dist/*
    

假設我們正在準備發佈 1.6.0

  • main 分支建立一個新分支,然後從 1.6.X 開始互動式重新建立基準,以選取需要向後移植的提交。

    git rebase -i upstream/1.6.X
    

    這將開啟一個互動式重新建立基準,其中包含 git-rebase-todo,其中包含 main 上的所有最新提交。在此階段,您必須至少與其他人執行此互動式重新建立基準(以免忘記某些內容並避免疑慮)。

    • 請勿移除行,而是將 pick 替換為 drop 來捨棄提交。

    • 針對錯誤修復版本要挑選的 commit,通常會加上 FIXCIDOC 的前綴。它們至少應包含所有已合併的 PR 中,被標記為此版本里程碑的 commit。

    • 針對錯誤修復版本要 drop 的 commit,通常會加上 FEATMAINTENHAPI 的前綴。不包含它們的原因是為了避免行為上的改變 (這應該只發生在主要/次要版本中)。

    • 在 drop 或 pick commit 之後,**不要結束**,而是將 git-rebase-todo 訊息的內容貼到 PR 中。這個檔案位於 .git/rebase-merge/git-rebase-todo

    • 儲存並結束以開始互動式變基。在必要時解決合併衝突。

  • 建立以 1.6.X 分支為目標的 PR。將以下發佈檢查表複製到此 PR 的描述中,以追蹤進度。

    * [ ] Set the version number in the release branch
    * [ ] Check that the wheels for the release can be built successfully
    * [ ] Merge the PR with `[cd build]` commit message to upload wheels to the staging repo
    * [ ] Upload the wheels and source tarball to https://test.pypi.org
    * [ ] Create tag on the main repo
    * [ ] Confirm bot detected at https://github.com/conda-forge/scikit-learn-feedstock
          and wait for merge
    * [ ] Upload the wheels and source tarball to PyPI
    * [ ] Update news and what's new date in main branch
    * [ ] Backport news and what's new date in release branch
    * [ ] Update symlink for stable in https://github.com/scikit-learn/scikit-learn.github.io
    * [ ] Publish to https://github.com/scikit-learn/scikit-learn/releases
    * [ ] Announce on mailing list and on LinkedIn, Bluesky, Twitter
    * [ ] Update SECURITY.md in main branch
    
  • 在發布分支中,將 sklearn/__init__.py 中的版本號 __version__ 更改為 1.6.0

  • 使用 [cd build] 提交標記觸發 wheel 建置器。另請參閱 wheel 建置器的工作流程執行

    git commit --allow-empty -m "[cd build] Trigger wheel builder workflow"
    

    注意

    [cd build] 中的縮寫 CD 代表 持續交付,並指用於產生發佈成品(二進位和原始碼套件)的自動化。這可以視為 CI 的延伸,CI 代表 持續整合。GitHub Actions 上的 CD 工作流程也用於自動建立每晚建置,並發佈 scikit-learn 開發分支的套件。另請參閱 安裝每晚建置

  • 一旦所有 CD 工作在 PR 中成功完成,請使用提交訊息中的 [cd build] 標記合併它。這次結果將上傳到暫存區。然後您應該可以使用 PyPI 發佈工作流程的「執行工作流程」表單,將產生的成品(.tar.gz.whl 檔案)上傳到 https://test.pypi.org/

    警告

    此 PR 應使用重新建立基準模式而不是常用的壓縮模式合併,因為我們希望保持 1.6.X 分支中的歷史記錄接近主分支的歷史記錄,這將有助於未來錯誤修復版本的發佈。

    此外,如果在合併時,包含 [cd build] 標記的最後一次提交是空的,則不會觸發 CD 工作。在這種情況下,您可以直接在 1.6.X 分支中推送一個包含標記的提交以觸發它們。

  • 如果上述步驟都順利完成,請謹慎地為發佈建立新標籤。只有在您幾乎確定發佈已準備就緒時才應執行此操作,因為在主儲存庫中新增新標籤可能會觸發某些自動化流程。

    git tag -a 1.6.0  # in the 1.6.X branch
    git push git@github.com:scikit-learn/scikit-learn.git 1.6.0
    

    警告

    不要使用 github 介面發佈版本作為建立標籤的方式,因為它會自動向所有追蹤儲存庫的使用者傳送通知,即使網站尚未更新且 wheels 尚未上傳。

  • 確認機器人已在 conda-forge feedstock 儲存庫 conda-forge/scikit-learn-feedstock 上偵測到標籤。如果沒有,請提交針對 main 分支的發布 PR。

  • 再次觸發 PyPI 發佈工作流程,但這次是將成品上傳到真正的 https://pypi.org/。為此,請在「執行工作流程」表單中將 testpypi 替換為 pypi

    或者,可以從本機收集產生的二進位 wheel 套件和原始碼壓縮檔,並將它們全部上傳到 PyPI。

    從本機上傳工件#

    在發佈標籤處取出並執行以下命令。

    rm -r dist
    python -m pip install -U wheelhouse_uploader twine
    python -m wheelhouse_uploader fetch \
      --version 1.6.0 --local-folder dist scikit-learn \
      https://pypi.anaconda.org/scikit-learn-wheels-staging/simple/scikit-learn/
    

    這些命令會下載累積在 anaconda.org 託管服務上的暫存區中的所有二進位套件,並將它們放入您本機的 ./dist 資料夾中。檢查 ./dist 資料夾的內容:它應該包含所有 wheels 以及原始碼壓縮檔 .tar.gz。請確保該資料夾中沒有開發人員版本或舊版本的 scikit-learn 套件。在上傳到 PyPI 之前,您可以先測試上傳到 test.pypi.org

    twine upload --verbose --repository-url https://test.pypi.org/legacy/ dist/*
    

    然後一次將所有內容上傳到 pypi.org

    twine upload dist/*
    
  • main 分支中,編輯 doc/whats_new 目錄中的相應檔案,以更新發布日期,連結發布重點範例,並新增貢獻者姓名清單。假設先前主要/次要版本中上次發布的標籤是 1.5.2,那麼您可以使用以下命令來檢索貢獻者姓名清單

    git shortlog -s 1.5.2.. |
      cut -f2- |
      sort --ignore-case |
      tr "\n" ";" |
      sed "s/;/, /g;s/, $//" |
      fold -s
    

    然後在發布分支中 cherry-pick 它。

  • main 分支中,編輯 doc/templates/index.html 以變更首頁中的「新聞」部分,以及發布月份。不要忘記移除舊的項目(兩年前或三次發布前的項目)並更新「進行中的開發」項目。然後在發布分支中 cherry-pick 它。

  • 更新 scikit-learn/scikit-learn.github.ioversionwarning.js 裡的 stable 的符號連結和 latestStable 變數。

    cd /tmp
    git clone --depth 1 --no-checkout git@github.com:scikit-learn/scikit-learn.github.io.git
    cd scikit-learn.github.io
    echo stable > .git/info/sparse-checkout
    git checkout main
    rm stable
    ln -s 1.6 stable
    sed -i "s/latestStable = '.*/latestStable = '1.6';/" versionwarning.js
    git add stable versionwarning.js
    git commit -m "Update stable to point to 1.6"
    git push origin main
    
  • scikit-learn/scikit-learn 上發布版本,並在郵件列表和社交網路上宣布。請記得在發布說明中加入變更日誌的連結。理想情況下,只有在 PyPI 和 conda-forge 上都可使用該套件,且網站為最新狀態時,才執行此步驟。

  • 更新 SECURITY.md 以反映最新支援的版本 1.6.0

假設我們正在準備發布版本 1.5.3

  • main 分支建立一個新分支,然後從 1.5.X 開始互動式變基,以選取需要 backport 的 commit。

    git rebase -i upstream/1.5.X
    

    這將開啟一個互動式重新建立基準,其中包含 git-rebase-todo,其中包含 main 上的所有最新提交。在此階段,您必須至少與其他人執行此互動式重新建立基準(以免忘記某些內容並避免疑慮)。

    • 請勿移除行,而是將 pick 替換為 drop 來捨棄提交。

    • 針對錯誤修復版本要挑選的 commit,通常會加上 FIXCIDOC 的前綴。它們至少應包含所有已合併的 PR 中,被標記為此版本里程碑的 commit。

    • 針對錯誤修復版本要 drop 的 commit,通常會加上 FEATMAINTENHAPI 的前綴。不包含它們的原因是為了避免行為上的改變 (這應該只發生在主要/次要版本中)。

    • 在 drop 或 pick commit 之後,**不要結束**,而是將 git-rebase-todo 訊息的內容貼到 PR 中。這個檔案位於 .git/rebase-merge/git-rebase-todo

    • 儲存並結束以開始互動式變基。在必要時解決合併衝突。

  • 建立一個目標為 1.5.X 分支的 PR。將下列發布檢查清單複製到此 PR 的描述中,以追蹤進度。

    * [ ] Set the version number in the release branch
    * [ ] Check that the wheels for the release can be built successfully
    * [ ] Merge the PR with `[cd build]` commit message to upload wheels to the staging repo
    * [ ] Upload the wheels and source tarball to https://test.pypi.org
    * [ ] Create tag on the main repo
    * [ ] Confirm bot detected at https://github.com/conda-forge/scikit-learn-feedstock
          and wait for merge
    * [ ] Upload the wheels and source tarball to PyPI
    * [ ] Update news and what's new date in main branch
    * [ ] Backport news and what's new date in release branch
    * [ ] Publish to https://github.com/scikit-learn/scikit-learn/releases
    * [ ] Announce on mailing list and on LinkedIn, Bluesky, Twitter
    * [ ] Update SECURITY.md in main branch
    
  • 在發布分支中,將 sklearn/__init__.py 中的版本號 __version__ 更改為 1.5.3

  • 使用 [cd build] 提交標記觸發 wheel 建置器。另請參閱 wheel 建置器的工作流程執行

    git commit --allow-empty -m "[cd build] Trigger wheel builder workflow"
    

    注意

    [cd build] 中的縮寫 CD 代表 持續交付,並指用於產生發佈成品(二進位和原始碼套件)的自動化。這可以視為 CI 的延伸,CI 代表 持續整合。GitHub Actions 上的 CD 工作流程也用於自動建立每晚建置,並發佈 scikit-learn 開發分支的套件。另請參閱 安裝每晚建置

  • 一旦所有 CD 工作在 PR 中成功完成,請使用提交訊息中的 [cd build] 標記合併它。這次結果將上傳到暫存區。然後您應該可以使用 PyPI 發佈工作流程的「執行工作流程」表單,將產生的成品(.tar.gz.whl 檔案)上傳到 https://test.pypi.org/

    警告

    此 PR 應以變基模式合併,而不是常用的 squash 模式,因為我們希望保持 1.5.X 分支中的歷史記錄與主分支的歷史記錄接近,這將有助於未來錯誤修復版本的發布。

    此外,如果合併時,最後一個包含 [cd build] 標記的 commit 是空的,則不會觸發 CD 作業。在這種情況下,您可以直接在 1.5.X 分支中推送一個帶有標記的 commit 以觸發它們。

  • 如果上述步驟都順利完成,請謹慎地為發佈建立新標籤。只有在您幾乎確定發佈已準備就緒時才應執行此操作,因為在主儲存庫中新增新標籤可能會觸發某些自動化流程。

    git tag -a 1.5.3  # in the 1.5.X branch
    git push git@github.com:scikit-learn/scikit-learn.git 1.5.3
    

    警告

    不要使用 github 介面發佈版本作為建立標籤的方式,因為它會自動向所有追蹤儲存庫的使用者傳送通知,即使網站尚未更新且 wheels 尚未上傳。

  • 確認機器人已在 conda-forge feedstock 儲存庫 conda-forge/scikit-learn-feedstock 上偵測到標籤。如果沒有,請提交針對 main 分支的發布 PR。

  • 再次觸發 PyPI 發佈工作流程,但這次是將成品上傳到真正的 https://pypi.org/。為此,請在「執行工作流程」表單中將 testpypi 替換為 pypi

    或者,可以從本機收集產生的二進位 wheel 套件和原始碼壓縮檔,並將它們全部上傳到 PyPI。

    從本機上傳工件#

    在發佈標籤處取出並執行以下命令。

    rm -r dist
    python -m pip install -U wheelhouse_uploader twine
    python -m wheelhouse_uploader fetch \
      --version 1.5.3 --local-folder dist scikit-learn \
      https://pypi.anaconda.org/scikit-learn-wheels-staging/simple/scikit-learn/
    

    這些命令會下載累積在 anaconda.org 託管服務上的暫存區中的所有二進位套件,並將它們放入您本機的 ./dist 資料夾中。檢查 ./dist 資料夾的內容:它應該包含所有 wheels 以及原始碼壓縮檔 .tar.gz。請確保該資料夾中沒有開發人員版本或舊版本的 scikit-learn 套件。在上傳到 PyPI 之前,您可以先測試上傳到 test.pypi.org

    twine upload --verbose --repository-url https://test.pypi.org/legacy/ dist/*
    

    然後一次將所有內容上傳到 pypi.org

    twine upload dist/*
    
  • main 分支中,編輯 doc/whats_new 目錄中的相應檔案,以更新發布日期並新增貢獻者姓名清單。假設先前主要/次要版本中上次發布的標籤是 1.6.0,那麼您可以使用以下命令來檢索貢獻者姓名清單

    git shortlog -s 1.6.0.. |
      cut -f2- |
      sort --ignore-case |
      tr "\n" ";" |
      sed "s/;/, /g;s/, $//" |
      fold -s
    

    然後在發布分支中 cherry-pick 它。

  • main 分支中,編輯 doc/templates/index.html 以變更首頁中的「新聞」部分,以及發布月份。然後在發布分支中 cherry-pick 它。

  • scikit-learn/scikit-learn 上發布版本,並在郵件列表和社交網路上宣布。請記得在發布說明中加入變更日誌的連結。理想情況下,只有在 PyPI 和 conda-forge 上都可使用該套件,且網站為最新狀態時,才執行此步驟。

  • 更新 SECURITY.md 以反映最新支援的版本 1.5.3

更新作者列表#

本節介紹如何更新scikit-learn 背後的人們。首先,在 GitHub 上建立一個具有 read:org 權限的經典權杖。然後執行以下指令碼,並在出現提示時輸入權杖

cd build_tools
make authors  # Enter the token when prompted

合併 Pull Requests#

當 PR 在 GitHub 上合併時,個別的 commit 會被壓縮。在合併之前

  • 如果需要,可以編輯產生的 commit 標題。請注意,這預設會重新命名 PR 標題。

  • 詳細描述 (包含所有 commit 的標題) 可以編輯或刪除。

  • 對於有多位程式碼貢獻者的 PR,必須注意保留詳細描述中的 Co-authored-by: name <name@example.com> 標籤。這將把 PR 標記為具有多位共同作者。程式碼貢獻是否足夠重要以值得列為共同作者,由維護者自行決定,如同在 what’s new 項目中一樣。

scikit-learn.org 網站#

scikit-learn 網站 (https://scikit-learn.dev.org.tw) 託管在 GitHub 上,但很少需要手動更新,方法是推送到 scikit-learn/scikit-learn.github.io 儲存庫。大多數更新都可以透過推送到 main (適用於 /dev) 或發布分支 A.B.X 來完成,Circle CI 會從這些分支自動建置和上傳文件。

實驗性功能#

sklearn.experimental 模組是在 0.21 版中引入的,其中包含可能會在沒有棄用週期的情況下變更的實驗性功能和估計器。

若要建立實驗性模組,請參閱 enable_halving_search_cv.pyenable_iterative_imputer.py 的內容。

注意

這些是 0.24 版中的永久連結,其中這些估計器仍然是實驗性的。它們在您閱讀時可能已經穩定,因此使用永久連結。請參閱以下關於從實驗性轉為穩定的說明。

請注意,公開的導入路徑必須指向公開的子套件 (如 sklearn/ensemblesklearn/impute),而不僅僅是一個 .py 模組。此外,導入的 (私有) 實驗性功能必須位於公開子套件的子模組/子套件中,例如 sklearn/ensemble/_hist_gradient_boosting/sklearn/impute/_iterative.py。這是為了讓 pickle 在未來不再是實驗性功能時仍然可以正常運作。

為了避免類型檢查器 (例如 mypy) 錯誤,應在父模組中使用 if typing.TYPE_CHECKING 檢查來直接導入實驗性估計器。如需範例,請參閱 sklearn/ensemble/__init__.pysklearn/impute/__init__.py。 也請撰寫基本測試,遵循 test_enable_hist_gradient_boosting.py 中的測試。

請確保您撰寫的每個使用者介面程式碼都明確提及該功能是實驗性的,並新增 # noqa 註解以避免與 PEP8 相關的警告

# To use this experimental feature, we need to explicitly ask for it
from sklearn.experimental import enable_iterative_imputer  # noqa
from sklearn.impute import IterativeImputer

為了使文件正確呈現,請在 doc/conf.py 中匯入 enable_my_experimental_feature,否則 Sphinx 將無法偵測和匯入對應的模組。請注意,使用 from sklearn.experimental import * 是無效的

注意

某些實驗性的類別和函式可能未包含在 sklearn.experimental 模組中,例如 sklearn.datasets.fetch_openml

一旦功能變得穩定,請從 scikit-learn 程式碼庫中移除所有 enable_my_experimental_feature 的引用,並將 enable_my_experimental_feature 改為僅引發警告的空操作,如 enable_hist_gradient_boosting.py 中所示。該檔案應永久保留,因為我們不希望破壞使用者的程式碼;我們只是透過警告來鼓勵他們移除該匯入。此外,請記得相應地更新測試,請參閱 test_enable_hist_gradient_boosting.py