Contentful の Webhook を GitHub Action をトリガーして、記事更新したらブログのリビルドを走らせる
/ 7 min read
Table of Contents
このブログは Astro で作成されたフロントエンドに合わせて、記事コンテンツは Contentful というヘッドレス CMS で管理しています。 ソースコードの管理やデプロイには、GitHub と GitHub Actions を使用しています。 Contentful を利用して静的サイトを構築することで、柔軟かつスケーラブルなコンテンツ管理を実現しながら、高速な静的サイトを構築できます。 ただし、コンテンツはビルド時に取得されるため、コンテンツを更新する際にはサイトの再ビルドが必要です。
Contentful には、コンテンツ更新時に Webhook を呼び出す機能があり、これを GitHub Actions の repository_dispatch 機能と組み合わせることで、自動的にリビルドを行うことが可能です!
GitHub Action を更新する
GitHub Actions を Webhook 経由で実行するには、対象のワークフローに repository_dispatch トリガーを設定する必要があります。 このブログのデプロイ用 GitHub Actions ワークフローのトリガー設定は以下の通りです:
name: Deploy to GitHub Pages
on: push: branches: - main workflow_dispatch: repository_dispatch: types: [contentful_publish]設定されたトリガーは、次の 3 つです:
- main ブランチへのプッシュ時
- マニュアル実行(workflow_dispatch)
- 特定のワークフローに対して手動実行できます
- Webhook による実行 (repository_dispatch)
- レポジトリ全体に対してイベントを発行することで、対象のワークフローが実行されます
repository_dispatch では、特定の types を指定することができます。Webhook を呼び出す際に event_type を指定すれば、ワークフローを特定のイベントにだけ反応させることが可能です。 なお、types を設定しない場合、そのワークフローはすべての repository_dispatch イベント(event_type を含むまたは省略されたもの)に反応します。
GitHub の Personal Access Token を用意する
Webhook を使って GitHub Actions を実行するには、認証用のトークンが必要です。 このトークンには、GitHub アカウントで発行した Personal Access Token(PAT) を使用します。 以下の手順で、細分化されたスコープを持つ Fine-grained Personal Access Token を作成します。
GitHub のメニューから GitHub > Settings > Developer Settings > Personal access token にアクセスし、 Generate new token をクリックして新しい Tokens (fine-grained) を作成します。
次の内容を設定します:
- リポジトリのアクセス権限
- 対象リポジトリを選択(すべてのリポジトリを選ぶことも可能ですが、必要なリポジトリのみに限定する方が安全です)
- Repository permissions から
- Actions: Read and Write
- Metadata: Read-only
- Workflows: Read and Write
- Content: Read and Write
Fine-grained Personal Access Token とは、その名の通り「アクセス権限を細かく制限できるトークン」であり、セキュリティを高めたい場合に推奨されます。 トークンを作成したら、その場で必ずコピーしてメモしておきましょう。セキュリティ上の理由から、トークンは一度しか表示されません!
Contentful の Webhook を設定する
まず、Contentful の スペース設定(Settings) から Webhooks にアクセスします。(右上のユーザーアイコンの横にある「歯車マーク」から入ります)
新規 Webhook を作成して、下記の設定を行います:
- Name: わかりやすい名前をつけてください
- URL:
- POST
- https://api.github.com/repos/ユーザー名/レポジトリ名/dispatches
- 末尾に ”/” を付けないように気をつけてください
- Content Events:
- Webhook を発火させるコンテンツイベントを選択します
- 一般的には以下のイベントで問題ありません
- Publish, Unpublish, Archive, Unarchive, Create, Save
- 公開済みコンテンツは「Unpublish」してからでないと「Delete」できないため、Delete ではサイトのリビルドは不要と考えてよいです
- Headers:
- (Add Custom Header)カスタムヘッダーを追加
- Accept
- application/vnd.github.everest-preview+json
- User-Agent
- contentful-webhook (任意の識別名)
- Accept
- (Add secret header)シークレットヘッダーを追加
- Authorization
- token PAT
- *token のあとにスペースを入れ、前述の PAT を設定します
- Authorization
- (Add Custom Header)カスタムヘッダーを追加
- Payload
- Customize the webhook payload を選択
- {“event_type”: “contentful_publish”} のように event_type を指定
- event_type の値(例:contentful_publish)は、GitHub Actions 側の repository_dispatch に設定した types と一致している必要があります
Webhook を保存した後、同じ設定画面の「Activity Log」 タブからその中に発火履歴とリクエスト/レスポンス内容を確認できます。
これで設定が完了です!Contentful のコンテンツを更新して、Webhook が正しく動作し、GitHub Actions が実行されるか確認してみましょう。
なんで workflow_dispatch を使わないの?
実は、GitHub Actions のワークフローは workflow_dispatch を使って手動で実行できるだけでなく、 外部から API を通じて呼び出すことも可能です。
以下のエンドポイントに POST すればワークフローを発火できます:
https://api.github.com/repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatchesworkflow_dispatch を外部サービスから使うには、以下のような制約や注意点があります:
- ワークフロー ID やファイル名の指定が必要
- workflow_dispatch は 特定のワークフローファイルを直接指定しないと動作しません
- 呼び出し側(Contentful)に設定するときに知っておく必要があります
- また、ワークフロー ID が変わるたびにその設定を更新する必要があります
- トリガーは柔軟性に欠ける
- event_type を渡すことができず、トリガー条件の振り分けができません
- マルチイベント対応には不向きです
どちらの方法も GitHub API 経由でトークン付きの認証が必要です。そのため、両方とも実装可能ですが、 Contentful のような外部サービスから使うには、シンプルで拡張性の高い repository_dispatch がより適しているというのが結論です。