自動リリース
このページで分かること
- 自動リリースの仕組み(Atmosphereアカウントがリリースの記録を持ち、GitHubがワークフローを識別し、リリースサービスが検証して書き込む)と、前提条件(公開のGitHubリポジトリなど)
release setupによる設定から、ワークフローの承認、リリースの承認までの手順と、Changesetsとの連携- リリースサービスが確かめる内容、資格情報ごとの権限の範囲、エラーへの対処、自動公開の取り消し
このページの目次
自動リリースは、バージョンのタグをプッシュしたとき、またはGitHub Actionsのワークフローを手動で開始したときに、サンドボックス型プラグインをビルドして公開します。パッケージのプロフィールとリリースのレコードは、引き続き自分のAtmosphereアカウントが所有します。GitHubが承認済みのワークフローを識別し、リリースサービスがビルドを検証して、範囲を絞った委任を通じてリリースを書き込みます。リポジトリには、Atmosphereアカウントの資格情報を保存しません。
自分のコンピューターから始めるリリースには、emdash-plugin publishを使います。GitHub Actionsでリリースをビルドして公開したい場合は、このガイドを使います。
前提条件
始める前に、次のものを用意します。
- サンドボックス型のEmDashプラグインを含む、公開のGitHubリポジトリ。
- 開発用の依存パッケージとしてインストールした
@emdash-cms/plugin-cli。CLIで作成したプラグインには、最初から含まれています。 slug、publisher、license、作者、セキュリティの連絡先を含む、有効なemdash-plugin.jsonc。repoに正規のGitHubのURLを設定するか、対話形式のセットアップで検出されたGitHubのリモートを確認します。package.jsonのバージョン。レジストリ専用のプラグインではemdash-plugin.jsoncのバージョン。publisherで指定したAtmosphereアカウント。- パスキーに対応したブラウザー。リリースの承認には、ユーザーの本人確認が必要です。
ワークフローを設定する前に、マニフェストの確認を実行します。
pnpm exec emdash-plugin validate
自動リリースの設定
-
パッケージを所有するAtmosphereアカウントで、プラグインのCLIにサインインします。
pnpm exec emdash-plugin login alice.example.comCLIは、このローカルの公開用のセッションをプロジェクトの外に保存します。GitHub Actionsがこのセッションを受け取ることはありません。
-
プラグインのディレクトリで、パッケージのプロフィールを準備し、ワークフローを生成します。
pnpm exec emdash-plugin release setupこのコマンドは、
emdash-plugin.jsoncからパッケージのメタデータを読み取ります。パッケージのプロフィールがない場合は、作成するかどうかを尋ねます。プロフィールはあるものの、委任によるリリースの設定がない場合は、既存のパッケージのメタデータを保ったまま、その設定を追加するかどうかを尋ねます。モノレポでは、プラグインのパッケージの中でコマンドを実行するか、
--dir <plugin-directory>を渡します。マニフェストにrepoがない場合、セットアップはGitHubのoriginリモートを検出し、リポジトリの入力欄にあらかじめ入れておきます。セットアップでは、リリースに承認が必要になる条件を尋ねられます。
- When plugin permissions increase(プラグインの権限が増えたとき)がデフォルトです。宣言したアクセスが最新のリリースより広がったとき、そのリリースは承認を待ちます。
- For every release(すべてのリリース)では、すべてのバージョンで承認が必要になります。
サインインしているAtmosphereアカウントが、最初の承認者になります。プロフィールは、パッケージを正規のGitHubリポジトリのURLにも結び付け、検証可能な来歴(provenance)を必須にします。
ワークフローのファイルがすでにある場合は、プロフィールの手順だけを実行します。
pnpm exec emdash-plugin profile setupパッケージのプロフィールを公開したあと、このコマンドは、手動でリリースする場合とGitHub Actionsでリリースする場合のコマンドを表示します。
対話形式でないターミナルでは、
--yesを渡してデフォルトの承認の方針を受け入れます。マニフェストからもGitのリモートからもリポジトリが得られない場合は--repository <https-url>を、すべてのリリースで承認を必須にする場合は--confirmation alwaysを渡します。 -
生成されたワークフローを確認してコミットします。
このコマンドは
.github/workflows/emdash-release.ymlを作成します。ファイルをプッシュすることはなく、--forceを渡さない限り既存のワークフローを置き換えることもありません。リポジトリに
.changeset/config.jsonがある場合、対話形式のセットアップでは Follow Changesets releases(Changesetsのリリースに合わせる)が選択肢に表示されます。Changesetsがemdash-plugin.jsoncを含むパッケージをリリースすると、再利用可能なEmDashのワークフローが同じバージョンを公開します。後述の方法で、既存のChangesetsのワークフローにつなぎます。それ以外の場合、生成されたワークフローは、<slug>@<version>に一致するパッケージのタグで実行されます。どちらの形も手動での実行に対応しており、--trigger changesets|tags|manualで明示的に選択できます。ワークフローは、各ジョブに必要な
contents、id-token、attestationsの権限だけを与えます。サードパーティのActionはコミットの完全な識別子で固定し、ファイルを生成したプラグインCLIと同じバージョンを実行し、各パッケージをマニフェストから特定し、プラグインのバンドルを1つビルドし、そのバイト列そのものに対するGitHubのビルドの来歴を作成して、両方のファイルをEmDashのリリース用のActionに渡します。ワークフローはリポジトリのルートに置かれ、そのリポジトリにあるすべてのプラグインのパッケージで共有されます。入れ子になったパッケージから
release setupを実行しても、.github/workflows/emdash-release.ymlはルートに書き込まれます。 -
リリースサービスのダッシュボードを開き、同じAtmosphereアカウントでサインインします。
「Authorize publishing」を選択します。アカウントのプロバイダーが、委任する権限を正確に表示します。保持される許可では、パッケージのリリースのレコードの作成と、パッケージや掲載用画像のblobのアップロードができます。パッケージのプロフィールの作成や編集、リリースの更新や削除、ほかのコレクションへの書き込みはできません。
-
リリースのワークフローを開始します。
Changesetsを使う場合は、バージョンのプルリクエストをマージし、その公開のジョブが完了するのを待ちます。Changesets Actionは、リリースしたパッケージを再利用可能なEmDashのワークフローに渡します。通常のnpmパッケージは無視され、
emdash-plugin.jsoncを含むパッケージは、同じバージョンがEmDashに公開されます。パッケージのタグをきっかけにする場合は、バージョンのタグを作る前にパッケージのバージョンを更新します。次のコマンドで
1.2.3のリリースが始まります。git tag gallery@1.2.3 git push origin gallery@1.2.3リポジトリのGitHub Actionsのページで「Run workflow」を選択しても開始できます。
-
リポジトリのrefの範囲ごとに、最初の実行で承認します。
サービスは、接続のリクエストを作成する前に、実行元のパッケージのプロフィールにGitHubのリポジトリが書かれていることを確認します。Actionは、GitHubのジョブの概要にリンクを書き込んで待機します。リンクを開き、リポジトリ、ワークフローのファイル、ブランチまたはタグ、環境を確認します。
タグで開始した実行では、「All package version tags」(パッケージのすべてのバージョンのタグ)か「Only this tag」(このタグだけ)を選びます。手動での実行では、そのブランチを初めて使うときに承認を求められます。別のタグやブランチの範囲を確認すると、既存の範囲を残したまま、その範囲がリポジトリの接続に追加されます。サービスは、GitHubのリポジトリと所有者のID、承認されたrefと環境を保存します。後から追加したパッケージは、署名されたプロフィールに同じリポジトリが書かれている場合にだけ、これらの範囲を再利用します。
以前のバージョンで生成したワークフローで作られたパッケージの承認は、元のパッケージに限定されたままです。一致しないパッケージやrefが最初に現れた時点で、リポジトリの接続が求められます。サービスが既存のパッケージの承認を自動的に広げることはありません。
-
必要な場合は、リリースを承認します。
プラグインの権限を広げるリリースや、すべてのリリースで承認を求めるように設定したプロフィールのリリースは、「Awaiting approval」(承認待ち)の状態になります。Actionの出力またはリリースのダッシュボードから、承認用のURLを開きます。承認するアカウントにまだパスキーがない場合は登録し、権限の変更を確認して、リリースを承認または却下します。
Actionのデフォルトの設定では、リリースが「Awaiting approval」になった時点で成功として終了します。サービス側のワークフローはブラウザーでの判断を待ち続け、承認後に公開します。
やさしい解説
自動リリースでは、GitHubにタグをプッシュすると、GitHub Actionsがプラグインをビルドし、EmDashのリリースサービスが中身を検証してから、自分のAtmosphereアカウントにリリースを書き込みます。リポジトリにはAtmosphereアカウントの資格情報を保存しません。最初の1回はブラウザーでワークフローを承認し、権限が増えるリリースのときはパスキーで承認します。
Changesetsのワークフローとの連携
生成された .github/workflows/emdash-release.yml は、Changesets Actionが出力する公開済みパッケージのJSONを、workflow_call で受け取ります。既存のChangesetsのジョブに出力を追加し、それに依存するジョブからEmDashのワークフローを呼び出します。既存のジョブやステップが別のIDを使っている場合は、release と changesets を置き換えます。
Changesets Action v2は、published-packages という出力を使います。Changesets CLI v3を使うワークフローには、次のジョブの出力と呼び出し側のジョブを追加します。
jobs:
release:
# Keep the existing runner, permissions, and steps.
outputs:
published: ${{ steps.changesets.outputs.published }}
published-packages: ${{ steps.changesets.outputs['published-packages'] }}
publish-emdash-plugins:
needs: release
if: needs.release.outputs.published == 'true'
uses: ./.github/workflows/emdash-release.yml
with:
published-packages: ${{ needs.release.outputs['published-packages'] }}
permissions:
contents: read
id-token: write
attestations: write
Changesets Action v1は、キャメルケースの publishedPackages というステップの出力を使います。Changesets CLI v2を使うワークフローでは、次の式を使います。
jobs:
release:
# Keep the existing runner, permissions, and steps.
outputs:
published: ${{ steps.changesets.outputs.published }}
published-packages: ${{ steps.changesets.outputs.publishedPackages }}
publish-emdash-plugins:
needs: release
if: needs.release.outputs.published == 'true'
uses: ./.github/workflows/emdash-release.yml
with:
published-packages: ${{ needs.release.outputs['published-packages'] }}
permissions:
contents: read
id-token: write
attestations: write
バージョンのプルリクエストとパッケージの公開は、引き続きChangesetsに任せます。EmDashを呼び出すジョブは、Changesetsが published: true を報告したときだけ実行されます。EmDash専用の非公開パッケージの場合は、.changeset/config.json で privatePackages.version と privatePackages.tag の両方を true にします。関係のない非公開のアプリケーションやテスト用のフィクスチャーは、ignore に追加します。
パッケージの追加
パッケージのソースのディレクトリで、そのパッケージのプロフィールを準備します。ルートにある既存のワークフローと、リポジトリの接続が再利用されます。
pnpm exec emdash-plugin profile setup --dir packages/comments
Changesetsを使う場合は、パッケージをchangesetに追加し、そのバージョンのプルリクエストをマージします。パッケージのタグをきっかけにする場合は、パッケージのバージョンを更新して、そのタグをプッシュします。
git tag comments@1.0.0
git push origin comments@1.0.0
ワークフローは、comments を1つの emdash-plugin.jsonc に対応付け、選択したバージョンを確認し、成果物のアップロードを受け付ける前に、署名されたプロフィールに接続済みのリポジトリが書かれていることを検証します。パッケージIDの重複やバージョンの不一致は、アテステーション(attestation)の前に失敗します。
リリースサービスが検証すること
サービスは、リリースを書き込む前に次の確認を済ませます。
- GitHubのOpenID Connect(OIDC)トークンに、認可されたリポジトリ、所有者、ワークフロー、ref、環境、コミット、実行、GitHubがホストするランナーが示されている。
- パッケージのプロフィールが存在し、公開者が署名しており、委任によるリリースの設定を含み、同じ正規のGitHubリポジトリが書かれている。
- 要求されたパッケージとバージョンが、ビルドされたプラグインのバンドルと一致する。
- パッケージのチェックサムが、アップロードされたバイト列と一致する。
- GitHubの来歴が、同じバンドル、リポジトリ、ワークフロー、コミット、実行を対象にしている。
- リリースのレコードで宣言されたアクセスが、バンドルのマニフェストと一致する。
- そのバージョンのレコードがまだ存在しない。
- 必要なパスキーによる承認が、検証結果そのものと、現在のプロフィールの版を対象にしている。
Actionは、サービスを呼び出すたびに新しいGitHubのOIDCトークンを要求します。バンドルと来歴のファイルは、ワークフローが認可されたあとでのみ、非公開の一時的なストレージに入ります。サービスは、検証済みのパッケージと画像のバイト列を公開者の個人データサーバー(PDS)にアップロードし、そこにリリースのレコードを作成して、検証済みの来歴を、チェックサムで指定する変更不可のURLで公開します。
権限の境界
資格情報は、それぞれ1つの役割だけを持ちます。
| 資格情報 | 使う側 | 権限 |
|---|---|---|
| ローカルのCLIのOAuthセッション | emdash-plugin profile setup |
ローカルで確認したあと、公開者が所有するパッケージのプロフィールを作成または更新する。 |
| GitHubのOIDCトークン | リリース用のAction | 1回のGitHubのワークフローの実行をサービスに対して識別する。AT Protocolへの書き込み権限は与えない。 |
| リリースサービスへの委任 | リリースサービス | パッケージのリリースのレコードを作成し、必要なblobをアップロードする。 |
| 公開者のアプリケーションのセッション | リリースのダッシュボード | ワークフローの接続を認可し、委任による公開を取り消す。 |
| 承認者のセッションとパスキー | 承認ページ | チェックサムに結び付いた1件のリリースの検証を承認または却下する。 |
| Cloudflare AccessのID | サービスの運用者のコンソール | ホストされたサービスを運用する。公開者や承認者を表すものではない。 |
サービスは、公開者の状態と承認者の状態を別々に保存します。自分のリリースを見るためにサインインしても運用者のアクセス権は得られず、運用者のIDで公開者としてリリースを承認することもできません。
Actionの動作
生成されたワークフローは、apps/release-action のActionを使います。このActionは、ビルドされたバンドルとSigstoreの来歴そのものの組み合わせか、チェックサムに結び付いたHTTPSの成果物の取得元を含む互換用の release-file のどちらかを受け付けます。release-file を、バンドルや来歴の入力と組み合わせないでください。
標準の生成されたワークフローは、次の入力を渡します。それぞれの値が何を認可するのかを推測せずに生成されたファイルを確認できるように、ここに示します。
| 入力 | 値 |
|---|---|
service-url |
リリースサービスのHTTPSのオリジン。 |
publisher-did |
パッケージのプロフィールとリリースを所有するDID。 |
bundle-file |
emdash-plugin release prepare が作る1つのtarball。 |
provenance-file |
actions/attest-build-provenance が出力する bundle-path そのもの。 |
Actionは、次の値を出力します。
| 出力 | 意味 |
|---|---|
connection-url |
初回の実行でワークフローを承認するためのブラウザー用URL。 |
intent-id |
リリースのインテント(intent)の識別子。 |
state |
公開済み、終了、または awaiting_approval の状態。 |
approval-url |
パスキーによる承認が必要な場合のブラウザー用URL。 |
release-uri |
公開されたリリースのAT URI。 |
release-cid |
公開されたリリースのレコードのCID。 |
reason-code |
終了したインテントの理由を示す、変わらないコード。 |
省略可能な入力、URLを取得元にする独自のワークフロー、ポーリングの制御、出力の正確な動作については、Actionのリファレンスを参照してください。
トラブルシューティング
PACKAGE_PROFILE_REQUIRED
パッケージのプロフィールがない、委任によるリリースの設定がない、正規でないリポジトリのURLを使っている、またはGitHubのワークフローとは別のリポジトリが書かれている状態です。
公開者のアカウントでローカルでプロフィールのセットアップを実行し、ワークフローをもう一度開始します。
pnpm exec emdash-plugin profile setup
この確認は、サービスがバンドルや来歴のアップロードを受け付ける前に実行されます。
公開のリポジトリが必要
GitHubは、非公開(private)と社内(internal)のリポジトリには非公開のSigstoreの信頼ルートを使います。リリースの検証の仕組みは、現在、公開のGitHubの来歴だけを信頼します。リリースのワークフローを公開のリポジトリに移すか、emdash-plugin publish でローカルから公開します。
WORKLOAD_NOT_ALLOWED
GitHubのリポジトリ、所有者、ワークフローのファイル、ref、環境のいずれかが、承認済みのワークフローの方針と一致しません。リリースのダッシュボードを開き、意図した範囲で新しいワークフローの接続を承認します。
PROFILE_FETCH_FAILED
サービスが、公開者のPDSからプロフィールを検証できませんでした。アカウントのプロバイダーが利用できるようになってから再試行します。プロフィールが削除または変更された場合は、emdash-plugin profile setup を実行します。
POLL_TIMEOUT
ワークフローの承認、リリースの承認、公開のいずれかが完了する前に、Actionが timeout-minutes に達しました。再実行する前に、リリースのダッシュボードでインテントの状態を確認します。同じGitHub Actionsの実行を再実行すると、その実行のべき等キー(idempotency key)が再利用されます。
自動公開の取り消し
リリースのダッシュボードで「Turn off automated publishing」を選択します。取り消すと、保持されていたリリースの委任が消去されます。既存のパッケージのプロフィール、リリース、モデレーションのラベル、インストール済みのプラグイン、ダッシュボードへのログインは変わりません。
次の自動リリースの前に、公開をもう一度接続し、ワークフローをあらためて承認します。
関連ドキュメント
- バンドルと公開では、ローカルからの公開とバンドルの検証を説明しています。
- マニフェストでは、パッケージのメタデータと宣言するアクセスを定義しています。
- 権限(Capabilities)とセキュリティでは、リリースの承認とインストールのときに確認する権限を説明しています。
- プラグインレジストリでは、検索、モデレーション、インストール時の検証を説明しています。