GitHub ActionsでCI後にVercel自動デプロイ

概要

Next.js 16プロジェクトでGitHub Actionsを使い、CIが通過した後だけVercelにデプロイする仕組みを構築する。

Vercelはgithubと連携し、pushされた時点でデプロイされるので、今回はブランチを分けるのではなく、circle ciのdeployジョブを使って、デプロイするようにした。

構成:

  • ciジョブ:型チェック・リント・ビルド (テストは省略)
  • deployジョブ:ci通過後、mainへのpush時のみ実行

ステップ1:VercelのIgnore Build Stepを設定

Vercelダッシュボード → Project → Settings → Build & Deployment → Ignore Build Step → “Don’t build anything”

これでpush時のVercel自動デプロイが無効になる。GitHub Actionsからのみデプロイするための設定。

ステップ2:Vercelのトークン・IDを取得

変数名取得場所
VERCEL_TOKENVercel → Account Settings → Tokens → Create Token
VERCEL_ORG_IDVercel → Account Settings → General → Your ID
VERCEL_PROJECT_IDVercel → Project → Settings → General → Project ID

ステップ3:GitHub Secretsに登録

GitHub → Repository → Settings → Secrets and variables → Actions → Repository secrets に3つを追加。

注意:EnvironmentではなくRepository secretsに設定すること。

ステップ4:ESLint設定(Next.js 16対応)

Next.js 16ではnext lintコマンドが廃止された。ESLint 10はフラットコンフィグ(eslint.config.js)が必須で、.eslintrc.jsonは使えない。

eslint.config.js(新規作成)

const config = require("eslint-config-next/core-web-vitals");
module.exports = [
  ...config,
  {
    settings: {
      react: { version: "19" }, // eslint-plugin-reactのESLint 10非互換を回避
    },
  },
];

package.json

"scripts": {
  "lint": "eslint pages src"
}

.eslintrc.jsonは削除する。

ステップ5:Tailwind CSS v4対応

Tailwind v4では@tailwindcss/postcssパッケージが必要で、CSSの書き方も変わった。

npm install @tailwindcss/postcss

postcss.config.mjs

const config = {
  plugins: {
    "@tailwindcss/postcss": {},
  },
};
export default config;

styles/globals.css

/* v3の書き方 */
/* @tailwind base; */
/* @tailwind components; */
/* @tailwind utilities; */

/* v4の書き方 */
@import "tailwindcss";

ステップ6:ci.ymlの設定

.github/workflows/ci.yml

name: CI

on:
  push:
    branches: [ main ]
  pull_request:

jobs:
  ci:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

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

      - name: Install dependencies
        run: npm install

      - name: Type Check
        run: npx tsc --noEmit

      - name: Lint
        run: npm run lint

      - name: Build
        run: npm run build

  deploy:
    runs-on: ubuntu-latest
    needs: ci
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Deploy to Vercel
        run: npx vercel --prod --token="${{ secrets.VERCEL_TOKEN }}" --yes
        env:
          VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
          VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}

ポイントまとめ

設定内容
needs: ciciジョブ通過後にのみdeployジョブが実行される
if: github.ref == 'refs/heads/main' && github.event_name == 'push'mainへのpush時のみデプロイ、PRはCIチェックのみ
npx vercel --prod --yesVercel CLIで本番デプロイ(インタラクティブプロンプトをスキップ)

ハマりポイント

  1. next lintがエラー:Next.js 16で廃止。eslint pages srcに変更する
  2. .eslintrc.jsonが効かない:ESLint 10はフラットコンフィグ必須。eslint.config.jsを作成し、.eslintrc.jsonを削除する
  3. eslint-plugin-reactのエラー(getFilename is not a functionsettings.react.versionを指定して回避
  4. Tailwindビルドエラー:v4は@tailwindcss/postcssが必要。CSSも@import "tailwindcss"に変更する
  5. VERCEL_TOKENが空になる:シークレット名のミス。ci.ymlの参照名と完全一致させる
  6. 別プロジェクトが作られてしまうVERCEL_PROJECT_IDが既存プロジェクトと不一致。Vercel SettingsのProject IDを正確に設定する
  7. Environment secretsでなくRepository secretsに設定する:Environmentは別途environment:指定が必要
  8. Vercelのトークンは、1度しか表示されないので別の安全な場所にコピーしておく。
タグ: