0
0

【GitHub Actions】自作Pythonパッケージを自動ビルドしてPyPIとGitHubリリースまで一気にデプロイする

Last updated at Posted at 2024-08-10

自作のライブラリをリリースするときに、ローカルでビルドして、TestPyPIにアップロードして確認して、PyPIにアップロードして、最後にタグ切ってリリースして・・・
面倒なのでGitHub Actionsでデプロイできるようにしました。

この記事で目指すこと

リモートにタグをpushした際に、自動でPyPIにパッケージをアップロードし、GitHubにリリースを作成する。

ローカルからtagをpushすると、、、

git tag vX.X.X
git push origin vX.X.X

以下順番で自動的にデプロイされる

  1. testPyPIへのアップロード
  2. PyPIへのアップロード
  3. GitHub上にリリースを追加しソースコードを配布

下記画像のようなワークフローを作成します。

Screenshot 2024-08-09 at 17.18.42.png

手順

準備

注意
パッケージングツールの設定ファイルとして setup.py ではなく、pyproject.toml を使用します。PEP-518により、モダンなPythonプロジェクトではpyproject.tomlの使用が推奨されています。

Pythonのパッケージを用意してPyPIとTestPyPIのプロジェクトとしてアップロードします。
すでに自作のライブラリがPyPI上にある場合は飛ばしてください。

下記のチュートリアルに従って、サンプルパッケージをTestPyPIとPyPIにアップロードします。
https://packaging.python.org/ja/latest/tutorials/packaging-projects/#creating-a-license

GitHub Actionsでワークフローファイルの作成

リポジトリ> Actions> set up a workflow yourself> 任意の名前でyamlファイル(今回はmain.yaml)を作成しcommit。空ファイルでOKです。

PyPIでPublishingの設定

従来、GitHub ActionsからPyPIにアップロードをするためにはPyPIでAPIトークンを作成し、GitHub側でそのトークンをSecretとして保持する必要がありました。

しかしPublishingを使用することで、事前に設定してある特定のサービス(および特定のユーザー、リポジトリなど)との接続の際に、一時的なトークンを発行、認証までを自動で行うことができます!

設定の簡単ですし、トークンの有効期限が短いのでセキュリティ的にもPublishingを使用する方が良さそうです。

PyPIのプロジェクトページからPublishing> Add a new publisherを選択します。
https://pypi.org/manage/project/[プロジェクト名]/settings/publishing/

以下画像のように記入し、Addします。

Screenshot 2024-08-09 at 17.54.30.png
2-4324-bfef-0471c4c39260.png)

TestPyPIを開き、同じようにPublisherを作成します。
Environment nameはPyPIとは別のものにします。

Screenshot 2024-08-09 at 18.00.54.png

GitHub Actionsでワークフローの設定

先ほど作成したyamlにワークフローを書いていきます。

1. タグがpushされたときにワークフローを開始する

name: Publish Python 🐍 distribution 📦 to PyPI and TestPyPI

on:
  push:
    tags:
      - 'v*.*.*'

2. ビルド

ビルドするためにはpyproject.tomlがリポジトリ上に存在する必要がありますので.gitignoreに含めないでください。

jobs:
  build:
    name: Build distribution 📦
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4 # コードを取得
    - name: Set up Python
      uses: actions/setup-python@v5 # Python環境のセットアップ
      with:
        python-version: "3.x"
    - name: Install pypa/build # ビルドツールをインストール
      run: >-
        python3 -m
        pip install
        build
        --user
    - name: Build a binary wheel and a source tarball
      run: python3 -m build # パッケージをビルド
    - name: Store the distribution packages # ビルド成果物をpython-package-distributionsという名前でdistディレクトリに一時的に保存
      uses: actions/upload-artifact@v4
      with:
        name: python-package-distributions
        path: dist/

3. TestPyPIへの公開

  publish-to-testpypi:
    name: Publish Python 🐍 distribution 📦 to TestPyPI
    needs:
    - build # ビルドジョブが完了した場合ジョブを開始する
    runs-on: ubuntu-latest

    environment:
      name: testpypi # Publisherに設定したenvironment nameを入力
      url: https://test.pypi.org/p/example-package-hanaosan0318 # プロジェクトURL

    permissions:
      id-token: write  # Publishingの権限を付与

    steps:
    - name: Download all the dists # 先ほど保存したビルド成果物をダウンロード
      uses: actions/download-artifact@v4
      with:
        name: python-package-distributions
        path: dist/
    - name: Publish distribution 📦 to TestPyPI # TestPyPIへ公開
      uses: pypa/gh-action-pypi-publish@release/v1
      with:
        repository-url: https://test.pypi.org/legacy/

4. PyPIへの公開

  publish-to-pypi:
    name: >-
      Publish Python 🐍 distribution 📦 to PyPI
    needs:
    - publish-to-testpypi # TestPyPIへの公開が完了した場合ジョブを開始する
    runs-on: ubuntu-latest
    environment:
      name: pypi # Publisherに設定したenvironment nameを入力
      url: https://pypi.org/p/example-package-hanaosan0318 # プロジェクトURL
    permissions:
      id-token: write

    steps:
    - name: Download all the dists
      uses: actions/download-artifact@v4
      with:
        name: python-package-distributions
        path: dist/
    - name: Publish distribution 📦 to PyPI
      uses: pypa/gh-action-pypi-publish@release/v1

5. リリースの作成

  github-release:
    name: >-
      Create GitHub Release with source code
    needs:
    - publish-to-pypi # PyPIへの公開が完了した場合ジョブを開始
    runs-on: ubuntu-latest
  
    permissions:
      contents: write # GitHubリリースを作成するための権限
  
    steps:
    - name: Checkout code
      uses: actions/checkout@v4 # コードを取得
  
    - name: Create GitHub Release
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # ワークフローが実行されるたびに自動的に生成される一時的なトークン
      run: >-
        gh release create
        '${{ github.ref_name }}'
        --repo '${{ github.repository }}'
        --notes "Release for version ${{ github.ref_name }}"

これでワークフローを定義することができました!

yamlファイルの全体は以下リンクから見られます。

デプロイしてみる

pyproject.tomlのversionを今回リリースバージョンに修正してpushしておきます。

pyproject.toml
[project]
name = "example_package_hanaosan0318"
version = "2.0.3" # リリースバージョンに変更
authors = [
  { name="Example Author", email="author@example.com" },
]

タグを作成しpushします。

git tag v2.0.3
git push origin v2.0.3

PyPIとTestPyPIにパッケージがアップロードされています。

Screenshot 2024-08-09 at 18.43.32.png

またリリースが作成され、ソースコードがzipとtar.gzで配布されていることが確認できるはずです。

Screenshot 2024-08-09 at 18.44.15.png

これでリモートにタグをpushした際に、自動でPyPIにパッケージをアップロードし、GitHubにリリースを作成することができました。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0