CI/CD

手動デプロイ + データベース自動管理の CI/CD ワークフロー設計

Vercel の自動デプロイを無効化し、データベースのみを GitHub Actions で自動管理するワークフローの設計と実装方法を解説します。Google Console での OAuth 設定も含めた完全ガイド。

本記事では、Vercel の自動デプロイを無効化し、データベース管理のみを GitHub Actions で自動化するワークフローの設計と実装方法を解説します。

ワークフロー概要

設計方針

環境デプロイデータベースマイグレーション
issue-* ブランチ手動(Vercel ダッシュボード)自動作成・削除自動実行
develop ブランチ手動(Vercel ダッシュボード)固定(linto-staging)PR マージ時に自動実行
main ブランチ手動(Vercel ダッシュボード)固定(linto-production)手動(workflow_dispatch)

フロー図

[issue-123 ブランチにプッシュ]


┌─────────────────────────────────────┐
│ GitHub Actions: preview-db-setup    │
│ - DB 作成(linto-issue-123)         │
│ - マイグレーション実行               │
│ - Vercel 環境変数設定                │
└─────────────────────────────────────┘


┌─────────────────────────────────────┐
│ 手動: Google Console 設定           │
│ - redirect URI の追加               │
│ - JavaScript 生成元の追加            │
└─────────────────────────────────────┘


[Vercel ダッシュボードから手動デプロイ]


[issue-123 → develop にマージ]

    ├──▶ GitHub Actions: preview-db-delete
    │    - DB 削除(linto-issue-123)
    │    - Vercel 環境変数削除

    └──▶ GitHub Actions: staging-migrate
         - staging DB にマイグレーション実行

[develop → main にマージ]


[何も自動実行されない]


[手動で workflow_dispatch からマイグレーション実行]
[手動で Vercel ダッシュボードからデプロイ]

なぜこの設計なのか

根拠 1: デプロイの安全性

Vercel の自動デプロイを無効化することで:

  • 意図しないデプロイを防止: コードをプッシュするたびにデプロイされない
  • デプロイタイミングの制御: QA 完了後など、適切なタイミングでデプロイ可能
  • コスト最適化: 不要なビルド・デプロイを削減

根拠 2: データベースの一貫性

データベース操作のみを自動化することで:

  • マイグレーション忘れ防止: PR マージ時に自動でマイグレーション実行
  • 環境の分離: 各 PR に専用の DB を自動作成
  • クリーンアップの自動化: PR クローズ時に不要な DB を自動削除

根拠 3: 本番環境の保護

main ブランチでは何も自動実行しないことで:

  • 本番環境への誤デプロイ防止: 明示的な操作が必要
  • マイグレーションの事前確認: 手動実行により内容を確認可能
  • ロールバックの余地: 問題発生時に対応しやすい

実装手順

ステップ 1: Vercel の自動デプロイを無効化

vercel.json で全ブランチの自動デプロイを無効化します。

{
  "$schema": "https://openapi.vercel.sh/vercel.json",
  "git": {
    "deploymentEnabled": false
  }
}

根拠: Vercel 公式ドキュメントによると、git.deploymentEnabledfalse に設定することで、すべてのブランチの自動デプロイを無効化できます。これにより、Git プッシュによるデプロイが完全に停止し、手動デプロイのみが可能になります。

ステップ 2: 既存の GitHub Actions ワークフローを削除または無効化

デプロイを行っていた既存のワークフローを削除します:

# 削除するファイル
rm .github/workflows/preview-deploy.yml

ステップ 3: Preview DB セットアップワークフローの作成

.github/workflows/preview-db-setup.yml:

name: Preview DB Setup

on:
  push:
    branches:
      - 'issue-*'

# 環境変数(プロジェクト固有の値はここで定義)
env:
  TURSO_API_TOKEN: ${{ secrets.TURSO_API_TOKEN }}
  # プロジェクト固有の設定(ハードコード)
  VERCEL_PROJECT_NAME: linto-dev
  VERCEL_SCOPE_SLUG: naokiyazawas-projects
  TURSO_STAGING_DB: linto-staging
  TURSO_PREVIEW_GROUP: preview

jobs:
  setup-preview-db:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - name: Checkout
        uses: actions/checkout@v6

      - name: Setup Node.js
        uses: actions/setup-node@v6
        with:
          node-version: '24'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Install Vercel CLI
        run: npm install -g vercel@latest

      - name: Install Turso CLI
        run: curl -sSfL https://get.tur.so/install.sh | bash

      # ========================================
      # Step 1: Vercel からプロジェクト情報と環境変数を取得
      # ========================================
      - name: Pull Vercel environment
        run: |
          vercel link --yes --token=${{ secrets.VERCEL_TOKEN }}
          vercel env pull .env.local --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
        env:
          VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
          VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}

      # ========================================
      # Step 2: データベース名の生成
      # ========================================
      - name: Generate DB name from branch
        id: db_name
        run: |
          BRANCH="${GITHUB_REF_NAME}"
          # ブランチ名から DB 名を生成(小文字化、英数字とハイフンのみ、32文字以内)
          DB_NAME="linto-$(echo "$BRANCH" | tr '[:upper:]' '[:lower:]' | tr -cd '[:alnum:]-' | cut -c 1-32)"
          echo "name=$DB_NAME" >> $GITHUB_OUTPUT
          echo "Generated DB name: $DB_NAME"

      # ========================================
      # Step 3: データベースの存在確認
      # ========================================
      - name: Check if database exists
        id: db_check
        run: |
          if ~/.turso/turso db show ${{ steps.db_name.outputs.name }} > /dev/null 2>&1; then
            echo "exists=true" >> $GITHUB_OUTPUT
            echo "Database already exists"
          else
            echo "exists=false" >> $GITHUB_OUTPUT
            echo "Database does not exist"
          fi

      # ========================================
      # Step 4: データベースの作成(初回のみ)
      # ========================================
      - name: Create Preview Database
        if: steps.db_check.outputs.exists == 'false'
        run: |
          echo "Creating database from staging..."
          ~/.turso/turso db create ${{ steps.db_name.outputs.name }} \
            --from-db ${{ env.TURSO_STAGING_DB }} \
            --group ${{ env.TURSO_PREVIEW_GROUP }}

      # ========================================
      # Step 5: データベース URL の取得
      # ========================================
      - name: Get Database URL
        id: db_url
        run: |
          DB_URL=$(~/.turso/turso db show ${{ steps.db_name.outputs.name }} --url)
          echo "url=$DB_URL" >> $GITHUB_OUTPUT
          echo "Database URL: $DB_URL"

      # ========================================
      # Step 6: マイグレーションの実行
      # ========================================
      - name: Run migrations
        env:
          TURSO_DATABASE_URL: ${{ steps.db_url.outputs.url }}
          TURSO_AUTH_TOKEN: ${{ secrets.TURSO_GROUP_TOKEN }}
        run: |
          # Vercel から取得した環境変数を読み込み(マイグレーションに必要な値)
          set -a
          source .env.local
          set +a
          # DB URL は Preview 用に上書き
          export TURSO_DATABASE_URL="${{ steps.db_url.outputs.url }}"
          export TURSO_AUTH_TOKEN="${{ secrets.TURSO_GROUP_TOKEN }}"
          npm run db:migrate

      # ========================================
      # Step 7: Preview URL の生成
      # ========================================
      - name: Generate Preview URL
        id: preview_url
        run: |
          # ブランチ名を URL セーフな形式に変換
          BRANCH_SLUG=$(echo "${{ github.ref_name }}" | tr '[:upper:]' '[:lower:]' | tr -cd '[:alnum:]-')
          # Vercel の Preview URL 形式: {project}-git-{branch}-{scope}.vercel.app
          PREVIEW_URL="https://${{ env.VERCEL_PROJECT_NAME }}-git-${BRANCH_SLUG}-${{ env.VERCEL_SCOPE_SLUG }}.vercel.app"
          echo "url=$PREVIEW_URL" >> $GITHUB_OUTPUT
          echo "Preview URL: $PREVIEW_URL"

      # ========================================
      # Step 8: Vercel 環境変数の設定
      # ========================================
      - name: Set Vercel environment variables
        env:
          VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
        run: |
          # プロジェクト ID を vercel.json から取得
          PROJECT_ID=$(cat .vercel/project.json | jq -r '.projectId')

          # TURSO_DATABASE_URL
          curl -X POST "https://api.vercel.com/v10/projects/$PROJECT_ID/env?upsert=true" \
            -H "Authorization: Bearer $VERCEL_TOKEN" \
            -H "Content-Type: application/json" \
            -d '{
              "key": "TURSO_DATABASE_URL",
              "value": "${{ steps.db_url.outputs.url }}",
              "type": "encrypted",
              "target": ["preview"],
              "gitBranch": "${{ github.ref_name }}"
            }'

          # BETTER_AUTH_URL
          curl -X POST "https://api.vercel.com/v10/projects/$PROJECT_ID/env?upsert=true" \
            -H "Authorization: Bearer $VERCEL_TOKEN" \
            -H "Content-Type: application/json" \
            -d '{
              "key": "BETTER_AUTH_URL",
              "value": "${{ steps.preview_url.outputs.url }}",
              "type": "plain",
              "target": ["preview"],
              "gitBranch": "${{ github.ref_name }}"
            }'

          # NEXT_PUBLIC_SITE_URL
          curl -X POST "https://api.vercel.com/v10/projects/$VERCEL_PROJECT_ID/env?upsert=true" \
            -H "Authorization: Bearer $VERCEL_TOKEN" \
            -H "Content-Type: application/json" \
            -d '{
              "key": "NEXT_PUBLIC_SITE_URL",
              "value": "${{ steps.preview_url.outputs.url }}",
              "type": "plain",
              "target": ["preview"],
              "gitBranch": "${{ github.ref_name }}"
            }'

          echo "Vercel environment variables set for branch: ${{ github.ref_name }}"

      # ========================================
      # Step 8: サマリーの出力
      # ========================================
      - name: Output summary
        run: |
          echo "## Preview Database Setup Complete" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "| Item | Value |" >> $GITHUB_STEP_SUMMARY
          echo "|------|-------|" >> $GITHUB_STEP_SUMMARY
          echo "| Database | \`${{ steps.db_name.outputs.name }}\` |" >> $GITHUB_STEP_SUMMARY
          echo "| Branch | \`${{ github.ref_name }}\` |" >> $GITHUB_STEP_SUMMARY
          echo "| Preview URL | \`${{ steps.preview_url.outputs.url }}\` |" >> $GITHUB_STEP_SUMMARY
          echo "| Created | ${{ steps.db_check.outputs.exists == 'false' && 'Yes' || 'No (already existed)' }} |" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "### Next Steps" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "1. **Google Console で OAuth 設定を追加**:" >> $GITHUB_STEP_SUMMARY
          echo "   - JavaScript 生成元: \`${{ steps.preview_url.outputs.url }}\`" >> $GITHUB_STEP_SUMMARY
          echo "   - リダイレクト URI: \`${{ steps.preview_url.outputs.url }}/api/auth/callback/google\`" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "2. **Vercel ダッシュボードから手動デプロイ**" >> $GITHUB_STEP_SUMMARY

根拠:

  • Turso CLI の db create --from-db コマンドは、既存のデータベースから即座にブランチを作成できます(公式ドキュメント参照)
  • Vercel API の POST /projects/{idOrName}/env エンドポイントは、gitBranch パラメータを指定することでブランチ固有の環境変数を設定できます
  • upsert=true により、既存の環境変数がある場合は更新されます

Vercel 環境変数の重要な動作

Vercel はブランチがマージまたは削除されても、ブランチ固有の環境変数を自動的に削除しません。

これは Vercel の仕様であり、以下の理由が考えられます:

  1. デプロイメントの独立性: 古いデプロイメントは引き続きアクセス可能であり、環境変数が必要
  2. 意図しない削除の防止: 重要な設定が誤って削除されることを防ぐ
  3. ブランチの再作成: 同名のブランチを再作成した場合に設定を再利用可能

そのため、preview-db-delete.yml ワークフローで 明示的に環境変数を削除する必要があります

設定される環境変数(3 つ):

環境変数用途
TURSO_DATABASE_URLPreview DB の接続 URL
BETTER_AUTH_URLBetter Auth のベース URL
NEXT_PUBLIC_SITE_URLサイトの公開 URL

これらはすべて gitBranch パラメータでブランチに紐づけられており、PR クローズ時に一括削除されます。

ステップ 4: Preview DB 削除ワークフローの作成

.github/workflows/preview-db-delete.yml:

name: Preview DB Delete

on:
  pull_request:
    types: [closed]
    branches: [develop]

jobs:
  delete-preview-db:
    # issue-* ブランチからの PR のみ対象
    if: startsWith(github.head_ref, 'issue-')
    runs-on: ubuntu-latest
    timeout-minutes: 5
    steps:
      - name: Install Turso CLI
        run: curl -sSfL https://get.tur.so/install.sh | bash

      # ========================================
      # Step 1: データベース名の生成
      # ========================================
      - name: Generate DB name from branch
        id: db_name
        run: |
          BRANCH="${{ github.head_ref }}"
          DB_NAME="linto-$(echo "$BRANCH" | tr '[:upper:]' '[:lower:]' | tr -cd '[:alnum:]-' | cut -c 1-32)"
          echo "name=$DB_NAME" >> $GITHUB_OUTPUT

      # ========================================
      # Step 2: データベースの削除
      # ========================================
      - name: Delete Preview Database
        env:
          TURSO_API_TOKEN: ${{ secrets.TURSO_API_TOKEN }}
        run: |
          ~/.turso/turso db destroy ${{ steps.db_name.outputs.name }} --yes || true
          echo "Database deleted: ${{ steps.db_name.outputs.name }}"

      # ========================================
      # Step 3: Vercel 環境変数の削除
      # ========================================
      # 注意: Vercel はブランチがマージ/削除されても環境変数を自動削除しない
      # そのため、手動で削除する必要がある
      - name: Get and delete Vercel environment variables
        env:
          VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
          VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
          BRANCH_NAME: ${{ github.head_ref }}
        run: |
          # ブランチに紐づく全ての環境変数 ID を取得
          ENV_IDS=$(curl -s "https://api.vercel.com/v9/projects/$VERCEL_PROJECT_ID/env" \
            -H "Authorization: Bearer $VERCEL_TOKEN" \
            | jq -r --arg branch "$BRANCH_NAME" '.envs[] | select(.gitBranch == $branch) | .id')

          if [ -z "$ENV_IDS" ]; then
            echo "No environment variables found for branch: $BRANCH_NAME"
            exit 0
          fi

          # 各環境変数を削除
          for ENV_ID in $ENV_IDS; do
            echo "Deleting environment variable: $ENV_ID"
            curl -X DELETE "https://api.vercel.com/v9/projects/$VERCEL_PROJECT_ID/env/$ENV_ID" \
              -H "Authorization: Bearer $VERCEL_TOKEN"
          done

          echo "All environment variables deleted for branch: $BRANCH_NAME"

      # ========================================
      # Step 4: サマリーの出力
      # ========================================
      - name: Output summary
        run: |
          echo "## Preview Database Deleted" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "| Item | Value |" >> $GITHUB_STEP_SUMMARY
          echo "|------|-------|" >> $GITHUB_STEP_SUMMARY
          echo "| Database | \`${{ steps.db_name.outputs.name }}\` |" >> $GITHUB_STEP_SUMMARY
          echo "| Branch | \`${{ github.head_ref }}\` |" >> $GITHUB_STEP_SUMMARY
          echo "| Env Variables | Deleted (TURSO_DATABASE_URL, BETTER_AUTH_URL, NEXT_PUBLIC_SITE_URL) |" >> $GITHUB_STEP_SUMMARY

ステップ 5: Staging マイグレーションワークフローの作成

.github/workflows/staging-migrate.yml:

name: Staging Migration

on:
  pull_request:
    types: [closed]
    branches: [develop]

# プロジェクト固有の設定
env:
  VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
  VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}

jobs:
  migrate-staging:
    # マージされた場合のみ実行(クローズのみは除外)
    if: github.event.pull_request.merged == true
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - name: Checkout
        uses: actions/checkout@v6
        with:
          ref: develop  # マージ後の develop を取得

      - name: Setup Node.js
        uses: actions/setup-node@v6
        with:
          node-version: '24'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Install Vercel CLI
        run: npm install -g vercel@latest

      # ========================================
      # Vercel から環境変数を取得してマイグレーション実行
      # ========================================
      - name: Pull Vercel environment and run migrations
        run: |
          # Vercel プロジェクトをリンク
          vercel link --yes --token=${{ secrets.VERCEL_TOKEN }}

          # Preview 環境の環境変数を取得(Staging は Preview のデフォルト)
          vercel env pull .env.local --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}

          # 環境変数を読み込んでマイグレーション実行
          set -a
          source .env.local
          set +a
          npm run db:migrate

      - name: Output summary
        run: |
          echo "## Staging Migration Complete" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "Migration applied to staging database." >> $GITHUB_STEP_SUMMARY

根拠: github.event.pull_request.merged == true の条件により、PR が実際にマージされた場合のみワークフローが実行されます。単にクローズされた場合(マージせずに閉じた場合)は実行されません。

ステップ 6: Production マイグレーションワークフローの作成(手動実行)

.github/workflows/production-migrate.yml:

name: Production Migration

on:
  workflow_dispatch:
    inputs:
      confirm:
        description: 'Type "migrate" to confirm'
        required: true
        type: string

# プロジェクト固有の設定
env:
  VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
  VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}

jobs:
  migrate-production:
    # 確認入力が正しい場合のみ実行
    if: github.event.inputs.confirm == 'migrate'
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - name: Checkout
        uses: actions/checkout@v6
        with:
          ref: main  # main ブランチを明示的に指定

      - name: Setup Node.js
        uses: actions/setup-node@v6
        with:
          node-version: '24'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Install Vercel CLI
        run: npm install -g vercel@latest

      # ========================================
      # Vercel から環境変数を取得してマイグレーション実行
      # ========================================
      - name: Pull Vercel environment and run migrations
        run: |
          # Vercel プロジェクトをリンク
          vercel link --yes --token=${{ secrets.VERCEL_TOKEN }}

          # Production 環境の環境変数を取得
          vercel env pull .env.local --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}

          # 環境変数を読み込んでマイグレーション実行
          set -a
          source .env.local
          set +a
          npm run db:migrate

      - name: Output summary
        run: |
          echo "## Production Migration Complete" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "Migration applied to production database." >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "**Next Step**: Deploy manually from Vercel dashboard" >> $GITHUB_STEP_SUMMARY

根拠: workflow_dispatch イベントにより、GitHub Actions の UI から手動でワークフローを実行できます。inputs で確認入力を要求することで、誤実行を防止します。

必要な GitHub Secrets

Vercel に環境変数が登録済みの場合、vercel env pull コマンドで取得できるため、GitHub Secrets は最小限で済みます。

必須の GitHub Secrets(5 つのみ)

Secret 名説明取得方法
VERCEL_TOKENVercel API トークンVercel Settings > Tokens
VERCEL_ORG_IDVercel 組織/ユーザー ID.vercel/project.jsonorgId
VERCEL_PROJECT_IDVercel プロジェクト ID.vercel/project.jsonprojectId
TURSO_API_TOKENTurso API トークン(DB 作成・削除用)Turso Dashboard
TURSO_GROUP_TOKENPreview グループの認証トークンturso group tokens create preview

従来比較: 17 → 5 に削減

項目従来の方法最適化後
Vercel 認証VERCEL_TOKEN のみVERCEL_TOKEN + ORG_ID + PROJECT_ID
Turso Staging/Production URLGitHub Secrets に登録vercel env pull で取得
Turso Staging/Production TokenGitHub Secrets に登録vercel env pull で取得
Better Auth SecretGitHub Secrets に登録vercel env pull で取得
Google OAuth 認証情報GitHub Secrets に登録vercel env pull で取得
各種 URLGitHub Secrets に登録vercel env pull で取得

根拠: Vercel CLI の vercel env pull コマンドは、プロジェクトに設定された環境変数をローカルファイル(.env.local)にエクスポートします。GitHub Actions 内でこのコマンドを実行することで、Vercel に登録済みの環境変数を再利用できます。

VERCEL_ORG_ID と VERCEL_PROJECT_ID の取得方法

ローカルで vercel link を実行すると、.vercel/project.json が生成されます:

# プロジェクトをリンク
vercel link

# 生成されたファイルを確認
cat .vercel/project.json

出力例:

{
  "orgId": "team_xxxxxxxxxxxxxxxx",
  "projectId": "prj_yyyyyyyyyyyyyyyy"
}

これらの値を GitHub Secrets に登録してください。

Note: .vercel/project.json をリポジトリにコミットしておけば、vercel link を省略できますが、GitHub Secrets として保持する方が安全です。

Vercel に登録が必要な環境変数

Vercel ダッシュボードで以下の環境変数を設定してください:

Production 環境:

環境変数
TURSO_DATABASE_URLlibsql://linto-production-xxx.turso.io
TURSO_AUTH_TOKENProduction DB のトークン
BETTER_AUTH_SECRET32 文字以上のシークレット
BETTER_AUTH_URLhttps://your-domain.vercel.app
GOOGLE_CLIENT_IDGoogle OAuth クライアント ID
GOOGLE_CLIENT_SECRETGoogle OAuth クライアントシークレット
NEXT_PUBLIC_SITE_URLhttps://your-domain.vercel.app

Preview 環境(デフォルト):

環境変数
TURSO_DATABASE_URLlibsql://linto-staging-xxx.turso.io
TURSO_AUTH_TOKENStaging DB のトークン
BETTER_AUTH_SECRETProduction と同じ値
BETTER_AUTH_URL(ブランチ固有で上書きされる)
GOOGLE_CLIENT_IDGoogle OAuth クライアント ID
GOOGLE_CLIENT_SECRETGoogle OAuth クライアントシークレット
NEXT_PUBLIC_SITE_URL(ブランチ固有で上書きされる)

Note: issue-* ブランチでは、TURSO_DATABASE_URLBETTER_AUTH_URLNEXT_PUBLIC_SITE_URL が GitHub Actions によってブランチ固有の値で上書きされます。

Vercel スコープスラッグの確認方法

Vercel の Preview URL は以下の形式で生成されます:

https://{project-name}-git-{branch-name}-{scope-slug}.vercel.app

スコープスラッグの確認手順:

  1. Vercel ダッシュボードでプロジェクトを選択
  2. 任意のブランチの Preview デプロイメントを確認
  3. URL から {scope-slug} 部分を特定

例: https://linto-dev-git-issue-123-naokiyazawas-projects.vercel.app

  • project-name: linto-dev
  • branch-name: issue-123
  • scope-slug: naokiyazawas-projects

Google Console OAuth 設定(手動)

Preview 環境で OAuth 認証を動作させるには、各 Preview URL に対して Google Console で設定を追加する必要があります

なぜ手動設定が必要なのか

Google OAuth では、セキュリティ上の理由から:

  1. 承認済みの JavaScript 生成元: OAuth フローを開始できるドメインを制限
  2. 承認済みのリダイレクト URI: OAuth コールバックを受け取れる URL を制限

これらは Google Console で事前に登録する必要があり、API で動的に追加することはできません。

設定手順

ステップ 1: Google Cloud Console にアクセス

  1. Google Cloud Console にログイン
  2. プロジェクトを選択
  3. API とサービス認証情報 に移動
  4. OAuth 2.0 クライアント ID をクリック

ステップ 2: JavaScript 生成元を追加

承認済みの JavaScript 生成元 セクションで URI を追加 をクリック:

https://{project-name}-git-{branch-name}-{scope-slug}.vercel.app

例:

https://linto-dev-git-issue-123-naokiyazawas-projects.vercel.app

ステップ 3: リダイレクト URI を追加

承認済みのリダイレクト URI セクションで URI を追加 をクリック:

https://{project-name}-git-{branch-name}-{scope-slug}.vercel.app/api/auth/callback/google

例:

https://linto-dev-git-issue-123-naokiyazawas-projects.vercel.app/api/auth/callback/google

ステップ 4: 保存

保存 をクリックして設定を反映します。

注意: 設定の反映には数分かかる場合があります。

GitHub Actions のサマリーを活用

preview-db-setup ワークフローの実行後、Actions タブの Summary に必要な URL が表示されます:

### Next Steps

1. **Google Console で OAuth 設定を追加**:
   - JavaScript 生成元: `https://linto-dev-git-issue-123-naokiyazawas-projects.vercel.app`
   - リダイレクト URI: `https://linto-dev-git-issue-123-naokiyazawas-projects.vercel.app/api/auth/callback/google`

2. **Vercel ダッシュボードから手動デプロイ**

この情報をコピーして Google Console に貼り付けることで、設定ミスを防げます。

PR クローズ時の注意

PR がクローズされたら、Google Console から該当する URL を手動で削除してください。放置しても動作に影響はありませんが、不要な設定が蓄積します。

Tip: Google Console では最大 100 個のリダイレクト URI を登録できます。定期的にクリーンアップすることを推奨します。

手動デプロイの方法

Vercel ダッシュボードからのデプロイ

  1. Vercel ダッシュボード にログイン
  2. プロジェクトを選択
  3. Deployments タブに移動
  4. 右上の Deploy ボタンをクリック
  5. Deploy from Git Branch を選択
  6. デプロイしたいブランチを選択
  7. Deploy をクリック

Vercel CLI からのデプロイ(オプション)

# Preview デプロイ
vercel --prod=false

# Production デプロイ
vercel --prod

ファイル構成

.github/
└── workflows/
    ├── preview-db-setup.yml      # issue-* プッシュ時: DB 作成 + マイグレーション
    ├── preview-db-delete.yml     # PR クローズ時: DB 削除
    ├── staging-migrate.yml       # develop マージ時: staging マイグレーション
    └── production-migrate.yml    # 手動実行: production マイグレーション

vercel.json                       # 自動デプロイ無効化設定

運用フロー

新機能開発時

# 1. issue ブランチを作成
git checkout -b issue-123

# 2. コードを変更してプッシュ
git push origin issue-123
# → GitHub Actions が自動で:
#   - DB 作成(linto-issue-123)
#   - マイグレーション実行
#   - Vercel 環境変数設定(TURSO_DATABASE_URL, BETTER_AUTH_URL, NEXT_PUBLIC_SITE_URL)

# 3. GitHub Actions の Summary を確認
# → 表示された Preview URL と callback URL をコピー

# 4. Google Console で OAuth 設定を追加(手動)
# → 承認済みの JavaScript 生成元: https://linto-dev-git-issue-123-xxx.vercel.app
# → 承認済みのリダイレクト URI: https://linto-dev-git-issue-123-xxx.vercel.app/api/auth/callback/google

# 5. Vercel ダッシュボードから手動でデプロイ
# → Preview 環境で動作確認

# 6. PR を作成して develop にマージ
# → GitHub Actions が自動で:
#   - Preview DB 削除
#   - Vercel 環境変数削除
#   - Staging DB にマイグレーション実行

# 7. Google Console から OAuth 設定を削除(手動・任意)
# → 不要になった Preview URL を削除

本番リリース時

# 1. develop → main の PR を作成してマージ
# → 何も自動実行されない

# 2. GitHub Actions から Production Migration を手動実行
# → Actions タブ → Production Migration → Run workflow

# 3. Vercel ダッシュボードから手動で Production デプロイ

トラブルシューティング

DB が作成されない

# Turso CLI で手動確認
turso db list
turso db show linto-issue-123

マイグレーションが失敗する

# ローカルで同じ環境変数を設定してテスト
export TURSO_DATABASE_URL=<url>
export TURSO_AUTH_TOKEN=<token>
npm run db:migrate

Vercel 環境変数が設定されない

# Vercel CLI で確認
vercel env ls --environment=preview --git-branch=issue-123

Google OAuth で「redirect_uri_mismatch」エラー

このエラーは、Google Console に登録された URI と実際のリダイレクト先が一致しない場合に発生します。

確認ポイント:

  1. 承認済みのリダイレクト URI に正確な URL が登録されているか確認:

    https://linto-dev-git-issue-123-naokiyazawas-projects.vercel.app/api/auth/callback/google
  2. URL の末尾にスラッシュがないことを確認(/google/ ではなく /google

  3. プロトコルが https:// であることを確認

  4. 設定後、数分待ってから再試行

Google OAuth で「access_denied」エラー

確認ポイント:

  1. 承認済みの JavaScript 生成元 に Preview URL が登録されているか確認
  2. OAuth 同意画面でテストユーザーとして登録されているか確認(外部公開前の場合)

Preview URL が正しく生成されない

GitHub Actions のログで VERCEL_SCOPE_SLUGVERCEL_PROJECT_NAME が正しく設定されているか確認:

# GitHub Secrets の設定を確認
# Settings → Secrets and variables → Actions

よくある間違い:

  • VERCEL_SCOPE_SLUG にプロジェクト名を入れている
  • VERCEL_PROJECT_NAME にスコープスラッグを入れている

Vercel の実際の Preview URL を確認して、正しい値を設定してください。

まとめ

このワークフロー設計により:

メリット説明
デプロイの安全性手動デプロイにより意図しないデプロイを防止
DB の自動管理PR ごとに専用 DB を自動作成・削除
マイグレーション忘れ防止PR マージ時に自動でマイグレーション実行
本番環境の保護main ブランチでは明示的な操作が必要
コスト最適化不要なビルド・デプロイを削減

自動化される処理

タイミング処理内容
issue-* へのプッシュDB 作成、マイグレーション、Vercel 環境変数設定
PR クローズ(develop へ)Preview DB 削除、Vercel 環境変数削除
PR マージ(develop へ)Staging DB マイグレーション

手動で行う処理

タイミング処理内容
issue-* プッシュ後Google Console で OAuth 設定を追加
issue-* プッシュ後Vercel ダッシュボードから Preview デプロイ
PR クローズ後Google Console から OAuth 設定を削除(任意)
develop マージ後Vercel ダッシュボードから Staging デプロイ
main マージ後Production マイグレーション(workflow_dispatch)
main マージ後Vercel ダッシュボードから Production デプロイ

データベース管理の自動化と、デプロイの手動制御を両立することで、安全かつ効率的な開発フローを実現できます。

注意: OAuth 認証を使用する場合、各 Preview 環境に対して Google Console での手動設定が必要です。この手順を省略すると、Preview 環境でのログイン機能が動作しません。

目次

ワークフロー概要設計方針フロー図なぜこの設計なのか根拠 1: デプロイの安全性根拠 2: データベースの一貫性根拠 3: 本番環境の保護実装手順ステップ 1: Vercel の自動デプロイを無効化ステップ 2: 既存の GitHub Actions ワークフローを削除または無効化ステップ 3: Preview DB セットアップワークフローの作成Vercel 環境変数の重要な動作ステップ 4: Preview DB 削除ワークフローの作成ステップ 5: Staging マイグレーションワークフローの作成ステップ 6: Production マイグレーションワークフローの作成(手動実行)必要な GitHub Secrets必須の GitHub Secrets(5 つのみ)従来比較: 17 → 5 に削減VERCEL_ORG_ID と VERCEL_PROJECT_ID の取得方法Vercel に登録が必要な環境変数Vercel スコープスラッグの確認方法Google Console OAuth 設定(手動)なぜ手動設定が必要なのか設定手順ステップ 1: Google Cloud Console にアクセスステップ 2: JavaScript 生成元を追加ステップ 3: リダイレクト URI を追加ステップ 4: 保存GitHub Actions のサマリーを活用PR クローズ時の注意手動デプロイの方法Vercel ダッシュボードからのデプロイVercel CLI からのデプロイ(オプション)ファイル構成運用フロー新機能開発時本番リリース時トラブルシューティングDB が作成されないマイグレーションが失敗するVercel 環境変数が設定されないGoogle OAuth で「redirect_uri_mismatch」エラーGoogle OAuth で「access_denied」エラーPreview URL が正しく生成されないまとめ自動化される処理手動で行う処理