Webhook / GitHub Actions でビルドを起動

中級 約10分 最終更新 2026-09-09

SSGで作ったサイトは、コンテンツを更新しただけでは公開ページに反映されません。ShareDan CMSの外部連携を使うと、投稿やFAQの更新をきっかけにCIを起動し、ビルド・デプロイまでを自動化できます。このガイドでは、GitHub Actionsでの再ビルドと、汎用Webhookを自前のエンドポイントで受ける方法の両方を扱います。

前提:APIキーとサイトコードを取得済みで、クイックスタートのステップ2まで完了していること。

1. 外部連携を有効にする

管理画面の「サイト設定 › 外部連携」で、サイト単位に次の3種類の連携先を設定できます。配信はキューで非同期に実行され、失敗時はリトライし、配信ログに最終ステータスが記録されます。

  • Webhook:設定した webhook_url へイベントのJSONをPOSTします。任意の受け口(自前のAPIサーバーやサーバーレス関数)で受けられます。
  • GitHub Actions:保存したリポジトリ・ワークフロー・ブランチに対して workflow_dispatch を実行します。
  • Slack:Incoming Webhookでチャンネルに通知します。

2. 通知されるイベント

Webhook / GitHub Actions で選べる、再ビルド向けのイベントは次の11種類です(実際に選べる範囲は、サイトの「利用するコンテンツ」設定でさらに絞り込まれます)。

イベント発生タイミング
post.published 投稿の公開・予約公開の実行時
post.updated 公開済み投稿の本文・メタ情報の更新時
post.deleted 公開済み投稿の削除時
faq.published FAQの公開時
faq.updated FAQの更新・並び替え時
faq.deleted FAQの削除時
content.published 固定コンテンツの公開時
content.updated 固定コンテンツの更新時
form.updated フォーム定義の更新時
form.submitted フォームが送信された時
maintenance.changed メンテナンス状態の切り替え時

3. GitHub Actions を起動する

ビルド・デプロイを行うワークフローに on: workflow_dispatch: を必ず追加してください。これがないとCMS側からは起動できません。

.github/workflows/deploy.yml
name: Deploy

on:
  workflow_dispatch:

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      - run: npm ci
      - run: npm run build
      - run: npm run deploy

対象イベントが発生すると、CMSは保存済みのトークンを使って、GitHubの workflow dispatch API を { "ref": "<branch>" } を添えて呼び出します。

GitHub API
POST /repos/{owner}/{repo}/actions/workflows/{workflow}/dispatches HTTP/1.1
Host: api.github.com
Authorization: Bearer <保存済みトークン>
Content-Type: application/json

{"ref":"main"}
自動発火のトグルを確認:「公開時に自動実行する」(github_auto_dispatch)がOFFになっていると、対象イベントが発生しても自動では起動しません。自動再ビルドを期待する場合はONにしてください。

4. 汎用Webhook と署名検証

汎用Webhookでは、次の形のJSONが webhook_url へPOSTされます。eventは発生したイベント名、triggerは発火経路(コンテンツ更新などによる自動発火は auto、画面からの手動実行・テスト送信は manual)です。resourceはイベントに紐づくリソースがない場合は null になります。

request body
{
  "event": "post.published",
  "trigger": "auto",
  "site": {
    "code": "demo-cms",
    "name": "デモサイト",
    "url": "https://demo.example.com"
  },
  "resource": {
    "type": "post",
    "id": 42
  },
  "occurred_at": "2026-09-08T09:30:00+09:00"
}

シークレットを設定している場合、リクエストには X-ShareDan-Signature ヘッダーが付与されます。値は sha256= に続けて、生ボディを webhook_secret鍵でHMAC-SHA256した16進文字列です。受信側では、JSONへパースする前の生ボディで同じ計算をし、定数時間比較で検証してください。

server.ts
import crypto from 'node:crypto';
import express from 'express';

const app = express();

app.post(
  '/webhooks/sharedan',
  express.raw({ type: 'application/json' }), // 生ボディをBufferで受け取る(JSONパース前)
  (req, res) => {
    const signature = req.header('X-ShareDan-Signature') ?? '';
    const expected =
      'sha256=' +
      crypto.createHmac('sha256', process.env.CMS_WEBHOOK_SECRET!).update(req.body).digest('hex');

    const ok =
      signature.length === expected.length &&
      crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));

    if (!ok) {
      return res.status(401).send('invalid signature');
    }

    const payload = JSON.parse(req.body.toString('utf8')) as { event: string };
    // payload.event を見て CI を起動するなどの処理
    res.status(204).end();
  },
);

app.listen(3000);
ヒント:シークレットは管理画面からいつでも再発行(regenerate)できます。第三者からの不正なPOSTを弾くために、署名検証を通ったリクエストだけをCI起動につなげてください。
関連:CDN側のキャッシュを使っている場合は、再ビルドと合わせて該当パスのパージも必要です。キャッシュとパージの考え方を参照してください。大量コンテンツのサイトで変更分だけを再生成したい場合は、ここで起動したビルドの中で変更検知APIを使います。増分SSG — 変更検知APIで差分だけ再ビルドを参照してください。
FEEDBACK

このページはお役に立ちましたか?

改善要望・不具合・ドキュメントの分かりにくい点など、お気軽にお寄せください。いただいた内容は今後の改善に役立てます。

返信をご希望の場合のみご記入ください。

スパム対策(レートリミット・ハニーポット・送信速度チェック)はサーバ側で自動適用されます。