Next.js: GitHub Actions を使用した CI/CD
最終更新:2026-08-26
CI/CD は開発チームにとっての「自動操縦装置」のようなものです — すべてのコミットが自動的に品質ゲートを通過し、合格したコードだけが本番環境にデプロイされます。
1. 学習内容
- 完全な GitHub Actions ワークフローを設計する:Lint → テスト → ビルド → デプロイ
- 並列マトリックス戦略を使用して、Node.js 18、20、22 で同時にテストを実行する
vercel-actionを使用して Vercel に自動デプロイする- マルチステージ Dockerfile を記述して 358MB のスタンドアロンイメージをビルドする
- GitHub Secrets の環境変数と PR プレビューデプロイメントの管理
2. あるテクニカルマネージャーの実話
(1) 課題:手動デプロイ — 午前 3 時になってもまだターミナルを見つめている
Bob は TaskFlow チームのテクニカルリードで、10,000 人以上のユーザーにサービスを提供する SaaS プラットフォームを 5 人のメンバーで保守しています。毎週金曜日のリリースプロセスは次のようなものです:
"Alice が PR をマージ → Bob に通知 → Bob がローカルでテストを実行 → テストが通ったら手動で
vercel deploy --prodをクリック → 10 分間ターミナルを見つめる → デプロイ成功を確認 → チームにメッセージを送信"
先週、Bob は npm run build の前に最新コードをプルするのを忘れたため、誤って古いバージョンをデプロイしてしまいました。5 分後にはユーザーがログインできなくなり、変更をロールバックするのにさらに 15 分かかりました。カスタマーサービスには 100 件以上の苦情が寄せられました。
| 課題 | 影響 |
|---|---|
| 手動デプロイ | 人為的エラーの発生率が高い(リリースの 30% に問題あり) |
| 自動アクセス制御テストなし | 欠陥のあるコードでも本番環境に到達可能 |
| 環境不一致 | ローカルでは動作するが本番環境でエラーが発生 |
| PR プレビューなし | マージ前に結果を確認できない |
(2) GitHub Actions ソリューション
Bob は 3 つの自動化された組み立てラインを設計しました:
# PR が作成されるたび → 自動 lint + テスト + ビルド
# main にマージ → 自動ビルド + Vercel にデプロイ
# 毎日明け方 → 自動 Docker イメージビルド
(3) 成果
| 項目 | 手動デプロイ | CI/CD 自動化 |
|---|---|---|
| リリース時間 | 30 分 | 8 分 |
| 人為的エラー | 30% | < 1% |
| PR レビュー効率 | コードのみ | コード + プレビュー URL |
| デプロイ頻度 | 週 1 回 | 1 日 5 回 |
3. GitHub Actions の基礎
Actions は GitHub に組み込まれた CI/CD プラットフォームで、YAML ファイルを使用してワークフローを定義します。
graph LR
A[git push] --> B[GitHub Actions]
B --> C[イベント トリガー]
C --> D[ジョブ 並列/直列]
D --> E[ステップ]
E --> F[Actions マーケットプレイス コンポーネント]
style B fill:#cce5ff
style D fill:#d4edda
| 概念 | 説明 | 例 |
|---|---|---|
| Workflow | 1 つの YAML ファイル = 1 つの自動化プロセス | .github/workflows/test.yml |
| Event | ワークフローをトリガーするイベント | push、pull_request、schedule |
| Job | 一連のステップ(並列または依存関係あり) | lint → test → deploy |
| Step | 単一のコマンドまたは Action | npm run lint、actions/checkout |
| Runner | 実行環境 | ubuntu-latest、windows-latest |
(1) ワークフローファイルの構造
# .github/workflows/ci.yml
name: CI Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
env:
NODE_VERSION: '20'
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- run: npm ci
- run: npm run lint
test:
needs: [lint]
runs-on: ubuntu-latest
strategy:
matrix:
node-version: ['18', '20', '22']
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm test
- run: npm run test:coverage
- uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
build:
needs: [test]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- run: npm ci
- run: npm run build
- uses: actions/upload-artifact@v4
with:
name: build-output
path: .next/
4. test.yml: 並列マトリックステスト
graph TB
A[Git Push / PR] --> B[lint]
B --> C[test 18.x]
B --> D[test 20.x]
B --> E[test 22.x]
C --> F[build]
D --> F
E --> F
F --> G[ビルド成果物のアップロード]
style A fill:#cce5ff
style C fill:#d4edda
style D fill:#d4edda
style E fill:#d4edda
(1) 完全な test.yml
# .github/workflows/test.yml
name: Test Suite
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
lint:
name: Lint Check
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: 依存関係のインストール
run: npm ci
- name: TypeScript 型チェック
run: npx tsc --noEmit
- name: ESLint チェック
run: npm run lint
- name: Prettier チェック
run: npx prettier --check "src/**/*.{ts,tsx}"
unit-and-integration:
name: ユニットテスト & 統合テスト
needs: [lint]
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
matrix:
node-version: ['18', '20', '22']
fail-fast: false
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: test
POSTGRES_PASSWORD: test
POSTGRES_DB: testdb
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: 依存関係のインストール
run: npm ci
- name: Prisma クライアントの生成
run: npx prisma generate
- name: データベースマイグレーションの実行
run: npx prisma migrate deploy
env:
DATABASE_URL: postgresql://test:test@localhost:5432/testdb
- name: ユニットテストの実行
run: npm run test
env:
DATABASE_URL: postgresql://test:test@localhost:5432/testdb
- name: 統合テストの実行
run: npm run test:integration
env:
DATABASE_URL: postgresql://test:test@localhost:5432/testdb
- name: カバレッジのアップロード
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
flags: unittests
name: codecov-node-${{ matrix.node-version }}
e2e:
name: E2E テスト
needs: [lint]
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: 依存関係のインストール
run: npm ci
- name: Playwright ブラウザのインストール
run: npx playwright install --with-deps chromium
- name: E2E テストの実行
run: npx playwright test --project=chromium
env:
TEST_DATABASE_URL: ${{ secrets.TEST_DATABASE_URL }}
- uses: actions/upload-artifact@v4
if: failure()
with:
name: playwright-report
path: playwright-report/
retention-days: 7
build:
name: ビルドチェック
needs: [unit-and-integration]
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run build
- uses: actions/upload-artifact@v4
with:
name: next-build
path: .next/
retention-days: 1
▶ サンプル: マトリックス並列テスト結果
# GitHub Actions コンソール出力
Job: unit-and-integration (node-version: 18.x) ✓ 3m 12s
Job: unit-and-integration (node-version: 20.x) ✓ 2m 58s
Job: unit-and-integration (node-version: 22.x) ✓ 3m 05s
Summary:
✓ lint (1 job) 0m 45s
✓ unit-and-integration (3 jobs) 3m 12s
✓ e2e (1 job) 4m 30s
✓ build (1 job) 1m 20s
5. deploy.yml: Vercel への自動デプロイ
| デプロイメント環境 | トリガー条件 | 対象 |
|---|---|---|
| プレビュー | PR 作成/更新 | プレビューブランチにデプロイ |
| 本番 | main にマージ | 本番環境の更新 |
| ステージング | リリースタグ | リリース前の検証 |
(1) Vercel デプロイ設定
# .github/workflows/deploy.yml
name: Deploy to Vercel
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
jobs:
deploy-preview:
name: プレビューのデプロイ
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- name: Vercel CLI のインストール
run: npm install --global vercel@latest
- name: Vercel 環境のプル
run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
- name: プロジェクト成果物のビルド
run: vercel build --token=${{ secrets.VERCEL_TOKEN }}
- name: Vercel プレビューにデプロイ
run: |
vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }} > deployment-url.txt
echo "PREVIEW_URL=$(cat deployment-url.txt)" >> $GITHUB_ENV
- name: PR にプレビュー URL をコメント
uses: thollander/actions-comment-pull-request@v2
with:
message: |
🚀 **プレビューデプロイメント準備完了**
| 環境 | URL |
|:-----------|:----|
| プレビュー | ${{ env.PREVIEW_URL }} |
| ブランチ | ${{ github.head_ref }} |
_このコメントはプッシュのたびに自動更新されます。_
deploy-production:
name: 本番環境へのデプロイ
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
needs: [deploy-preview]
runs-on: ubuntu-latest
timeout-minutes: 15
environment: production
steps:
- uses: actions/checkout@v4
- name: Vercel CLI のインストール
run: npm install --global vercel@latest
- name: Vercel 環境のプル
run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
- name: プロジェクト成果物のビルド
run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
- name: Vercel 本番環境にデプロイ
run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
- name: デプロイ成功を通知
uses: slackapi/slack-github-action@v1
with:
payload: |
{
"text": "✅ 本番デプロイメント完了: ${{ github.repository }}@${{ github.sha }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
6. Docker イメージビルド(マルチステージ、358 MB)
セルフホストデプロイメントでは、CI で Docker イメージを自動ビルドする必要があります。
(1) マルチステージ Dockerfile
# Dockerfile — Next.js 16 スタンドアロンビルドイメージ
# フェーズ 1: 依存関係のインストール(キャッシュレイヤーを使用)
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --only=production && \
npm cache clean --force
# フェーズ 2: ビルド(.next 成果物を生成)
FROM node:20-alpine AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NEXT_TELEMETRY_DISABLED=1
RUN npm run build
# フェーズ 3: 実行(最小化イメージ ~358MB)
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
RUN addgroup --system --gid 1001 nodejs && \
adduser --system --uid 1001 nextjs
COPY --from=build /app/public ./public
COPY --from=build --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=build --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
CMD ["node", "server.js"]
(2) Docker ビルド Action
# .github/workflows/docker.yml
name: Docker Build & Push
on:
push:
tags: ['v*']
schedule:
- cron: '0 2 * * 0' # 毎週日曜日早朝 2 時
jobs:
docker:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- name: QEMU のセットアップ
uses: docker/setup-qemu-action@v3
- name: Docker Buildx のセットアップ
uses: docker/setup-buildx-action@v3
- name: GitHub Container Registry にログイン
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Docker メタデータ
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha,format=short
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
- name: ビルドとプッシュ
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
▶ サンプル: Docker イメージビルドの出力
# ビルドログ
#1 [deps 1/1] RUN npm ci --only=production
#1 DONE 15.2s
#2 [build 1/4] COPY --from=deps /app/node_modules ./node_modules
#2 DONE 0.1s
#3 [build 2/4] COPY . .
#3 DONE 0.3s
#4 [build 3/4] RUN npm run build
#4 DONE 28.5s
#5 [runner 1/6] COPY --from=build /app/public ./public
#5 DONE 0.1s
#6 Exporting layers
#6 DONE 3.2s
# イメージサイズの分析
ghcr.io/myorg/taskflow:latest 358 MB
7. 環境変数とシークレット管理
graph TB
A[GitHub Secrets] --> B[Actions Runtime]
B --> C[Vercel Token]
B --> D[データベース URL]
B --> E[API キー]
B --> F[Slack Webhook]
C --> G[Vercel にデプロイ]
D --> H[テスト実行]
E --> I[ビルド時に注入]
F --> J[デプロイ通知]
style A fill:#cce5ff
style B fill:#d4edda
| 環境変数名 | 目的 | ソース |
|---|---|---|
VERCEL_TOKEN |
Vercel API 認証 | GitHub Secrets |
VERCEL_ORG_ID |
Vercel チーム ID | Vercel ダッシュボード |
VERCEL_PROJECT_ID |
Vercel プロジェクト ID | Vercel ダッシュボード |
DATABASE_URL |
データベース接続 | GitHub Secrets |
CODECOV_TOKEN |
カバレッジのアップロード | Codecov ウェブサイト |
SLACK_WEBHOOK_URL |
デプロイ通知 | Slack アプリ設定 |
(1) GitHub Secrets の設定
# GitHub リポジトリ → Settings → Secrets and variables → Actions → 追加
gh secret set VERCEL_TOKEN --body "your-vercel-token"
gh secret set DATABASE_URL --body "postgresql://user:pass@host:5432/db"
gh secret set SLACK_WEBHOOK_URL --body "https://hooks.slack.com/services/..."
(2) 環境分離戦略
# 異なる環境での変数オーバーライド
jobs:
test:
env:
DATABASE_URL: postgresql://test:test@localhost:5432/testdb
NODE_ENV: test
deploy-preview:
environment: preview
env:
DATABASE_URL: ${{ secrets.PREVIEW_DATABASE_URL }}
NEXT_PUBLIC_API_URL: ${{ vars.PREVIEW_API_URL }}
deploy-production:
environment: production
env:
DATABASE_URL: ${{ secrets.PROD_DATABASE_URL }}
NEXT_PUBLIC_API_URL: https://api.taskflow.io
8. PR プレビューデプロイメントワークフロー
PR プレビューを使用すると、開発者はマージ前に変更の効果をプレビューできます。
graph TB
A[開発者が PR を作成] --> B[Actions が deploy-preview をトリガー]
B --> C[Vercel がプレビューデプロイメントを作成]
C --> D[プレビュー URL を生成]
D --> E[ボットが PR にリンクをコメント]
E --> F[レビュアーがプレビューで検証]
F -->|承認| G[main にマージ]
G --> H[Actions が deploy-production をトリガー]
style A fill:#cce5ff
style F fill:#fff3cd
style H fill:#d4edda
▶ サンプル: 完全な PR プレビュー + クリーンアップワークフロー
上記の YAML 設定を指定されたファイルパスに保存してください。設定は次回のサーバー再起動時に有効になります。
# .github/workflows/preview.yml
name: PR Preview
on:
pull_request:
types: [opened, synchronize, closed]
jobs:
preview:
if: github.event.action != 'closed'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Vercel プレビューにデプロイ
id: deploy
run: |
npx vercel --token=${{ secrets.VERCEL_TOKEN }} \
--scope=${{ secrets.VERCEL_ORG_ID }} \
--confirm > preview-url.txt
echo "url=$(cat preview-url.txt)" >> $GITHUB_OUTPUT
- name: URL をコメント
uses: actions/github-script@v7
with:
script: |
const url = '${{ steps.deploy.outputs.url }}'
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `🚀 **プレビューがデプロイされました**\n\n${url}\n\n_コミット: ${context.sha}_`
})
cleanup:
if: github.event.action == 'closed'
runs-on: ubuntu-latest
steps:
- name: Vercel プレビューを削除
run: |
npx vercel remove \
taskflow-git-${GITHUB_HEAD_REF//\//-} \
--token=${{ secrets.VERCEL_TOKEN }} \
--yes --scope=${{ secrets.VERCEL_ORG_ID }} || true
セクション: name、on、jobs。
9. 完全な例: TaskFlow 完全 CI/CD パイプライン
# .github/workflows/full-pipeline.yml
# ============================================
# TaskFlow 完全 CI/CD 組み立てライン
# ============================================
name: TaskFlow Full Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
release:
types: [published]
env:
NODE_VERSION: '20'
PNPM_VERSION: '9'
jobs:
# === フェーズ 1: 品質アクセス制御 ===
quality-gate:
name: 品質ゲート
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- name: TypeScript チェック
run: pnpm typecheck
- name: ESLint + Prettier
run: pnpm lint && pnpm format:check
- name: カバレッジ付きユニットテスト
run: pnpm test:coverage
- name: カバレッジのアップロード
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: false
# === フェーズ 2: 統合テスト ===
integration:
name: 統合テスト
needs: [quality-gate]
runs-on: ubuntu-latest
timeout-minutes: 20
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: taskflow
POSTGRES_PASSWORD: taskflow
POSTGRES_DB: taskflow_test
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: npx prisma generate
- run: npx prisma migrate deploy
env:
DATABASE_URL: postgresql://taskflow:taskflow@localhost:5432/taskflow_test
- name: 統合テスト
run: pnpm test:integration
env:
DATABASE_URL: postgresql://taskflow:taskflow@localhost:5432/taskflow_test
- name: E2E テスト
run: npx playwright install --with-deps chromium && pnpm test:e2e
env:
DATABASE_URL: postgresql://taskflow:taskflow@localhost:5432/taskflow_test
# === フェーズ 3: ビルド ===
build:
name: アプリケーションのビルド
needs: [integration]
runs-on: ubuntu-latest
timeout-minutes: 15
outputs:
image-tag: ${{ steps.meta.outputs.tags }}
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm build
- name: Docker イメージのビルド
if: github.event_name == 'push'
uses: docker/build-push-action@v5
with:
context: .
load: true
tags: taskflow:ci-${{ github.sha }}
- name: ビルド成果物の保存
uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: |
.next/
public/
package.json
# === フェーズ 4: デプロイメント ===
deploy:
name: デプロイ
needs: [build]
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: production
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- name: Vercel にデプロイ
run: |
npx vercel deploy --prod \
--token=${{ secrets.VERCEL_TOKEN }} \
--scope=${{ secrets.VERCEL_ORG_ID }}
- name: Slack に通知
uses: slackapi/slack-github-action@v1
with:
payload: |
{
"text": "✅ TaskFlow が本番環境にデプロイされました\nコミット: ${{ github.sha }}\n実行者: ${{ github.actor }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
- name: Lighthouse CI の実行
run: npx lhci autorun
env:
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_TOKEN }}
❓ よくある質問
vercel-action と Vercel CLI のどちらが優れていますか?vercel-action(amondnet/vercel-action)は一般的な CLI 操作をラップしますが、アップデートが遅れる場合があります。Vercel CLI(npm install -g vercel)を直接使用することをお勧めします。Actions で run: vercel deploy --prod --token=... を使用することで、より柔軟性が高く、常に最新バージョンを使用できます。actions/secrets-scanning を使用して誤ったコミットを検出します。actions/cache を使用して node_modules と .next/cache をキャッシュします。(2) 独立したジョブを並列実行します。(3) fail-fast: false を使用して、単一バージョンの失敗がパイプライン全体のキャンセルを引き起こさないようにします。(4) npm の代わりに pnpm を使用します(インストールが高速です)。(5) リポジトリが大きい場合はランナーをセルフホストします。📖 まとめ
- GitHub Actions ワークフローは、Event → Jobs → Steps の 3 層構造で構成されます。YAML ファイルは
.github/workflows/に配置します。 strategy.matrixで Node 18/20/22 の並列テストを実装し、複数の LTS バージョンにわたる互換性を同時に検証します。vercel deploy --prodコマンドを Actions に統合して自動デプロイを実現できます。PR プレビューはactions/github-scriptコメント URL からアクセスできます。- マルチステージ Docker ビルド(deps → build → runner)によりイメージサイズを約 358MB に抑えます。
output: 'standalone'が前提条件です。 - GitHub Secrets は機密変数を安全に保存し、
environmentフィールドで開発、プレビュー、本番の環境分離を実現します。 - CI 最適化の 3 つの主要戦略:依存関係のキャッシュ、ジョブの並列化、npm の代わりに pnpm を使用する。
📝 練習問題
-
基本問題 (⭐):
.github/workflows/ci.ymlを作成し、Lint、Test、Build の 3 つの直列ジョブを含め、mainへのpushごとにトリガーするようにします。 -
応用問題 (⭐⭐): プロジェクトに完全な Vercel 自動デプロイパイプラインをセットアップします:(1) GitHub Secrets に
VERCEL_TOKENを設定する。(2) PR プレビューと本番デプロイを実装するdeploy.ymlを記述する。(3) プレビュー URL が PR コメントに表示されることを確認する。 -
発展問題 (⭐⭐⭐): マルチ環境 CI/CD パイプライン(dev → staging → production)を実装します:(1) 各環境に独自のデータベースとシークレットを持たせる。(2) dev ブランチは自動的に dev 環境にデプロイされる。(3) main ブランチは自動的に staging にデプロイされる。(4) 本番環境へのデプロイには手動承認が必要。(5) デプロイ成功後に webhook 経由で Slack チャンネルに通知する。