nikkie-ftnextの日記

イベントレポートや読書メモを発信

PyPIのTrusted Publishersを よ う や く 設定しました。APIトークンの管理不要でリリースできる!

完全に理解したこちらを解題します

PyPIのTrusted Publishersが影響するのは、PyPIにパッケージを公開しているPython使いです。
APIトークンを使う方法から切り替えるのをおすすめします。

目次

これまで:PyPIAPIトークンを使って、GitHubでリリースを作ったらPyPIに公開!

こちらの記事に書いています。

GitHub Actionsの抜粋です。
https://github.com/ftnext/sphinx-revealjs-copycode/blob/v0.1.0/.github/workflows/publish.yml

on:
  release:
    types: [published]

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      # 省略
      - name: Publish package
        uses: pypa/gh-action-pypi-publish@release/v1
        with:
          password: ${{ secrets.PYPI_API_TOKEN }}

これから:PyPIでTrusted Publishersを設定!!

これまでの方法からAPIトークンが不要になります。
GitHubでリリースを作ったらPyPIに公開されるのは変わりません。

もともとAPIトークンの管理を煩雑に感じていました。
上記記事の「ちょっとしたお悩み:Actionのシークレットは2回設定しています」より

  • これから初めてPyPIに公開する場合、PyPIにプロジェクトがないのでスコープをやむなく「アカウント全体(全プロジェクト)」にしています
  • PyPIへの初回公開が成功した場合、スコープをプロジェクトに絞ったトークンを再度作り、シークレットの設定値を更新します

Trusted Publishers自体は聞いたことはありました。
ただどういうものかがよく分からず、設定を後回しにしてきました。
やってみた今なら言えます、設定はPyPI上でフォーム入力だけ! APIトークンが不要になってめっちゃ便利!

既存のプロジェクト

公式ドキュメントは画像付きで参考になります(英語ですが、翻訳と合わせて)

  1. PyPIで既存のプロジェクトにアクセス
  2. プロジェクトのサイドバーからpublisherを追加

なんと、これだけです!

GitHubリポジトリ以外からもpublishできるようですが、今の私は使わないので取り上げていません)

新規プロジェクト

こちらも公式ドキュメントに画像があります

https://pypi.org/manage/account/publishing/ からpending publisherを追加します

  • PyPIのパッケージ名
  • publishするGitHub Action
    • 既存プロジェクトと同じ項目です

GitHub Actionsから初回公開できると、通常のpublisherとなりました

GitHub Actionsの変更

上記の抜粋を変更して示します

on:
  release:
    types: [published]

jobs:
  publish:
    runs-on: ubuntu-latest
+    environment: pypi
+    permissions:
+      id-token: write

    steps:
      # 省略
      - name: Publish package
        uses: pypa/gh-action-pypi-publish@release/v1
-        with:
-          password: ${{ secrets.PYPI_API_TOKEN }}
  • environmentPyPIのpublisherのフォームに入力したものです
    • GitHub Actionsって環境(environment)1って概念があったんですね
  • id-tokenがwriteできる権限2を付けます
    • OpenID Connect (OIDC) トークンをフェッチします。 これには id-token: write が必要です。3
  • pypa/gh-action-pypi-publishアクションに渡すトークンは不要なので削除
    • passwordが指定されていないときtrusted publisherとして動くみたいでした。賢い!

例:https://github.com/ftnext/sphinx-revealjs-copycode/commit/9c479a1a40debbcdb0e4e7a3354a8346c48cc256

終わりに

「なんだかよく分からないな」と後回しにしていたPyPIのTrusted Publishersをついに設定しました。
設定だけなら簡単で、APIトークンの管理が不要になり、GitHubでのリリース作成を契機にGitHub ActionsでPyPIに公開し続けられています!

  • PyPIでpublisherを追加するフォームを入力(既存プロジェクトも新規プロジェクトも)
  • GitHub Actionsのワークフローを変更(environmentとpermissionsを追加)

みんなも設定しよう!

Trusted Publishersの仕組みにはOIDCなど絡むようで、今の私には「魔法のよう」を超える理解はありません(より安全になってるんだと思ってます)。
少しずつでも理解を深められたらと思います