🛠️

Next.js × GitHub Actions × Git Submoduleで複数サイトを効率よく管理・デプロイする

に公開

企業向けのブランドサイトや多店舗展開のWebサイトでは、複数リポジトリで同じ基盤(base)を使いまわす構成が必要になることがあります。この記事では、

Next.js + GitHub Actions + Git Submodule を組み合わせて、
1つの共通ベースリポジトリを複数のブランドに自動反映&デプロイ する構成を解説します。

本記事では Kuroco front にデプロイしています。


仕様

  • 共通の base リポジトリsubmodule として各ブランドに追加
  • base に更新があれば、各ブランド側に repository_dispatch を送信
  • 各ブランドでサブモジュール更新 → 自動ビルド → デプロイ(KurocoFrontなど)

各リポジトリ構成

brand_a/
├─ base/ ← サブモジュール(git submodule)
├─ .github/workflows/
│   ├─ update-submodule.yml
│   └─ build.yml
brand_base/
├─ .github/workflows/
│   └─ notify.yml

1. サブモジュールの追加

git submodule add https://github.com/your-org/brand_base.git base
git commit -m "add base submodule"
git push origin develop

2. ブランド側リポジトリにActionsを追加

update-submodule.yml

name: Update submodule based on base branch

on:
  repository_dispatch:
    types: [update-base]

jobs:
  update-base:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout target branch
        uses: actions/checkout@v4
        with:
          ref: ${{ github.event.client_payload.target_branch }}
          submodules: recursive
          token: ${{ secrets.SUBMODULE_PAT }}
          fetch-depth: 0

      - name: Update submodule to latest
        run: |
          git submodule update --remote --merge
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git commit -am "chore: update base submodule [skip ci]"
          git push origin ${{ github.event.client_payload.target_branch }}

🔎 SUBMODULE_PAT は Personal Access Token(PAT)で、リポジトリへの repo 権限が必要です。


build.yml(ビルド&デプロイ)

name: Build and Deploy SPA to KurocoFront

on:
  push:
    branches:
      - main
      - develop

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: recursive
          token: ${{ secrets.SUBMODULE_PAT }}
          fetch-depth: 0

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"

      - name: Install pnpm
        run: npm install -g pnpm

      - name: Install dependencies
        run: |
          cd base
          pnpm install

      - name: Build
        run: |
          cd base
          pnpm build

      - name: Zip
        run: |
          cd base/out
          zip -r ../../out.zip .

      - name: Deploy
        uses: diverta/workflow-webhook@v3
        env:
          webhook_url: "https://your-api-url/direct/menu/github/"
          webhook_secret: ${{ secrets.DEPLOY_SECRET }}
          data: '{"single_zip":"1","domain":"your-site.kuroco-front.app","run_id":"${{ github.run_id }}","hash":"${{ github.sha }}"}'

3. base 側の通知ワークフロー(notify.yml)

name: Notify repos of base update

on:
  push:
    branches:
      - main
      - develop

jobs:
  dispatch-update:
    runs-on: ubuntu-latest
    steps:
      - name: Send update event to brand repos
        run: |
          BRANCH_NAME=${GITHUB_REF#refs/heads/}
          for REPO in brand_a brand_b brand_c; do
            curl -X POST https://api.github.com/repos/your-org/$REPO/dispatches \
              -H "Accept: application/vnd.github+json" \
              -H "Authorization: token ${{ secrets.SUBMODULE_PAT }}" \
              -d "{\"event_type\":\"update-base\",\"client_payload\":{\"target_branch\":\"$BRANCH_NAME\"}}"
          done

dispatch 先の各リポジトリには update-submodule.yml が必要です。


4. Personal Access Token(SUBMODULE_PAT)の作成手順

  1. GitHub右上のアイコンから Settings > Developer Settings に進む
  2. 左メニューの Personal access tokens > Tokens (classic) を選択
  3. 「Generate new token」 をクリック

設定例:

  • Note: submodule-push-token など
  • Expiration: 任意
  • Scopes: repo にチェック(privateリポジトリ含むすべてにアクセス可能)
  1. トークンが生成されたらコピーし、brand_base リポジトリの Settings > Secrets > Actions に登録
  • Name: SUBMODULE_PAT
  • Value: 上記で生成したトークン

このトークンは notify.ymlrepository_dispatch を実行する際の認証に使用されます。


5. よくあるエラーと対策

エラー 原因 解決策
401 Unauthorized token 無効または未設定 secrets.SUBMODULE_PAT を確認(PATの repo 権限)
Failed to parse URL from undefined/... 環境変数が未設定 .env または Actions の env にURLを設定
update-submodule.yml が発火しない 対象ブランチにファイルが存在しない develop/main 両方に workflow があるか確認

補足:サブモジュール更新で build.yml を誤発火させない方法

update-submodule.yml の push に以下を含めることで build をスキップできます:

git commit -am "update base submodule [skip ci]"

GitHub Actions は skip ci 付きのコミットでは push イベントを無視します。


まとめ

  • サブモジュールを使えば1つの base を複数リポジトリに展開できる
  • repository_dispatch + update-submodule + build の3ステップで自動化が完成
  • PAT と環境変数管理が鍵 🔐

最後に

この記事では、Next.js + GitHub Actions + Git Submodule を活用した 多リポジトリ CI/CD パターン を紹介しました。ご活用くださいませ 🙌

Discussion