前言
還在手動打包上傳 PyPI?GitHub Actions 自動化真香~!
在《Python 程式碼一鍵轉流程圖》一文裡,我介紹了我的開源專案 PyFlowchart。過去這段時間裡,已經有好幾位小夥伴為這個專案提出了建議,或者報告了 Bug 啦。在這幾位朋友的幫助下,專案也迭代了幾個版本了。之前,這個專案每次版本更新,我都需要做很多寫程式碼意外的麻煩工作:
- 在 GitHub 上 publish 一個 release,
- 手動打包上傳 PyPI。
這個過程非常反人類,release 一個版本要做兩個工作。更可怕的是,打包上傳 PyPI 的工作十分模版化(鄙人拙作《如何用 pip 安裝自己寫的包》一文介紹了這個過程)。我覺得作為開發者,不應該把時間浪費在這種套路工作上。
於是我想去了過去我寫過一篇叫做《還在手動發部落格?GitHub Actions自動化真香》的文章,大致介紹了我是如何利用 GitHub Actions 自動更新部落格網站的。所以,今回,我嘗試用 GitHub Actions 搭建了一套釋出新版本時,自動打包上傳 PyPI ? 的工作流程。
現在,釋出新的版本時,就只需在 GitHub 上新建一個 Release。GitHub Actions 會自動幫我完成構建、打包、上傳 PyPI 的工作。
本文就介紹如何利用 GitHub Actions 自動釋出 Python 包到 PyPI。
(注:我在 PyFlowchart 專案中使用的實現和下文略有不同,我根據需求做了一些修改,如果你感興趣,可以看一看我的實現:github.com/cdfmlr/pyfl…
下文大部分內容主要參(fan)考(yi)自 PyPA 的文章《Publishing package distribution releases using GitHub Actions CI/CD workflows》
GitHub Actions CI/CD 允許在 GitHub 平臺上特定的事件發生時自動執行一系列的命令。用這個就可以做設定一個響應 push 事件的工作流程。本文將展示如何當有 git push 時釋出一個新的 Python 包發行版(到 PyPI)。我們將使用到 pypa/gh-action-pypi-publish GitHub Action。
注意:這個教程假設你已經有在 GitHub 上有一個 Python 專案,並且你知道如何構建包,並把它釋出到 PyPI。
在 GitHub 上儲存 token
在本文中,我們會把專案上傳到 PyPI 和 TestPyPI。所以需要生成兩份獨立的 token,並把它們儲存到 GitHub 的倉庫設定中。
我們開始吧!?
- 訪問 pypi.org/manage/acco… ,建立一個新的 API token。 如果你已經在 PyPI 裡釋出過你的專案了,那麼你應該把 token 的範圍(token scope) 限定為只能操作這個專案的。你可以把新 token 命名為
GitHub Actions CI/CD —project-org/project-repo
之類的,方便辨識。生成 token 後不要關閉瀏覽器頁面—— token 只會顯示一次。 - 在另一個瀏覽器選項卡或視窗中,開啟 GitHub 上你的專案頁面,點選
Settings
選項卡,然後點選左側邊欄裡的 Secrets 。 - 建立一個新的 sercret,命令為
PYPI_API_TOKEN
,然後複製貼上第一步生成的 token。 - 訪問 test.pypi.org/manage/acco… ,重複之前的步驟,把 TestPyPI 的 token 儲存成
TEST_PYPI_API_TOKEN
。
注意:如果你還沒有 TestPyPI 賬號,你應該註冊一個。TestPyPI 和 PyPI 的賬號不共通哦。
建立 workflow
GitHub CI/CD 工作流程(workflow)是用 YAML 格式的檔案儲存到倉庫的 .github/workflows/
目錄裡的。
我們建立一個 .github/workflows/publish-to-test-pypi.yml
檔案。
我們將從一個有意義的名稱開始,然後定義觸發 GitHub 執行此工作流程的事件:
name: Publish Python ? distributions ? to PyPI and TestPyPI
on: push
複製程式碼
定義工作流程的工作環境
現在,我們來為工作(job)新增初始設定。這個過程將執行我們稍後定義的命令。在這裡,我們將使用Ubuntu 18.04:
jobs:
build-n-publish:
name: Build and publish Python ? distributions ? to PyPI and TestPyPI
runs-on: ubuntu-18.04
複製程式碼
簽出專案,構建發行版
然後,在該 build-n-publish
部分下新增以下內容:
steps:
- uses: actions/checkout@master
- name: Set up Python 3.7
uses: actions/setup-python@v1
with:
python-version: 3.7
複製程式碼
這些操作會把我們的專案原始碼下載到 CI 執行容器裡,然後安裝並啟用 Python 3.7 環境。
現在,我們就可以從原始碼構建 dist 了。在此示例中,我們將使用build
包,所以假設專案裡已正確設定 pyproject.toml
(請參見 PEP 517 / PEP 518)。
(注:emmm,其實這裡不寫 pyproject.toml
問題也不大)
提示:你可以使用任何其他方法來構建發行版,只要將準備好上傳的包儲存到 dist/
資料夾中即可。
將下面的程式碼加到 steps
裡:
- name: Install pypa/build
run: >-
python -m
pip install
build
--user
- name: Build a binary wheel and a source tarball
run: >-
python -m
build
--sdist
--wheel
--outdir dist/
.
複製程式碼
釋出到 PyPI 和 TestPyPI
最後,新增如下程式碼:
- name: Publish distribution ? to Test PyPI
uses: pypa/gh-action-pypi-publish@master
with:
password: ${{ secrets.TEST_PYPI_API_TOKEN }}
repository_url: https://test.pypi.org/legacy/
- name: Publish distribution ? to PyPI
if: startsWith(github.ref, 'refs/tags')
uses: pypa/gh-action-pypi-publish@master
with:
password: ${{ secrets.PYPI_API_TOKEN }}
複製程式碼
這兩個 step 呼叫了 pypa/gh-action-pypi-publish GitHub Action:
第一個步驟無條件地將 dist/
資料夾的內容上傳到TestPyPI。第二個步驟將其內容上傳到 PyPI,這一步只會對被打了標籤(git tag)的提交執行。
完事,收工!
現在,每當你將打了標籤(tag)的提交 push 到 GitHub 上時,此工作流程都會將其釋出到 PyPI。同時,對於任意 push ,它都會將其打包釋出到 TestPyPI,這對於提供 alpha 測試版本以及確保釋出渠道保持健康非常有用!
by("CDFMLR", "2021-01-17")
# 啊,今天昆明都下雪了,家裡巨冷。。。
# See you ❄️
複製程式碼