Build a reliable CI/CD pipeline that runs tests and type checks on every push before handing off to Vercel for preview and production deployments.
Why Combine GitHub Actions with Vercel
Vercel’s Git integration handles deploys, but it skips custom linting, type checking, and integration tests that matter for production reliability. GitHub Actions lets you enforce these gates before any deploy reaches Vercel, reducing broken previews and production incidents.
For teams shipping Next.js apps with server actions or API routes, this separation prevents half-tested code from reaching users. The pattern also scales cleanly when you later add OpenTelemetry tracing or Stripe subscription logic that requires end-to-end verification.
Repository and Vercel Project Setup
Create a Vercel project connected to your GitHub repository. Note the project name and team ID from the Vercel dashboard settings. These become required secrets for the Actions workflow.
In GitHub, add the following repository secrets: VERCEL_TOKEN (from Vercel account settings), VERCEL_ORG_ID, and VERCEL_PROJECT_ID. Never store these in the workflow file itself.
Core CI Workflow with GitHub Actions
Create .github/workflows/ci.yml. The workflow runs on every push and pull request, installing dependencies with pnpm, running the linter, TypeScript check, and Jest tests before attempting a production build.
name: CI
on: [push, pull_request]
jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm lint
- run: pnpm tsc --noEmit
- run: pnpm test
- run: pnpm build
Fail the job on any step. This catches type errors and broken server actions before Vercel ever sees the commit.
Adding Vercel Deploy Steps
Extend the workflow with a separate deploy job that only runs after CI succeeds. Use the Vercel CLI to trigger preview or production deploys based on branch.
- name: Install Vercel CLI
run: pnpm add -g vercel
- name: Deploy to Vercel
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
run: |
if [ "${{ github.ref }}" = "refs/heads/main" ]; then
vercel --prod --token=$VERCEL_TOKEN
else
vercel --token=$VERCEL_TOKEN
fi
The production flag ensures main branch commits go live while all other branches create preview URLs that can be shared for review.
Environment Variables and Secrets Handling
Store runtime secrets in Vercel’s dashboard under Project Settings > Environment Variables. Reference them by name in both preview and production environments. GitHub Actions never needs these values; only the Vercel CLI does.
For build-time variables required during pnpm build, add them to Vercel as well. Avoid committing .env files. If a variable changes, trigger a manual redeploy from the Vercel dashboard rather than pushing an empty commit.
Failure Modes and Production Gotchas
Vercel preview URLs can become stale if the workflow fails silently; always require the CI job to pass via branch protection rules before allowing merges. At scale, add a concurrency group to cancel in-flight runs on the same branch and reduce queue time.
Monitor Vercel function logs after deploy. Next.js server actions that rely on external services (Stripe, databases) often surface runtime errors only after the first preview visit. Set up Slack or email alerts in Vercel for production deployment failures rather than relying solely on GitHub notifications.
