Skip to content
Latchkey

CI/CD for a Next.js + Playwright App on Vercel with GitHub Actions

Lint, build, run Playwright e2e tests, then deploy your Next.js app to Vercel on every push.

This recipe pairs a Next.js app with Playwright browser tests and a Vercel deploy. CI installs dependencies, builds the app, runs Playwright against the production build, and promotes to Vercel only when the suite is green.

What the pipeline does

  • install deps with npm ci
  • lint and type-check
  • install Playwright browsers with their OS deps
  • build and start the app, then run e2e specs
  • deploy to Vercel with the Vercel CLI

The workflow

Playwright spins up the built app via its webServer config, so tests hit a real Next.js server. The deploy job runs only after tests pass on the main branch.

.github/workflows/ci.yml
name: CI
on:
  push:
    branches: [main]
  pull_request:
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
      - run: npm ci
      - run: npm run lint
      - run: npx playwright install --with-deps
      - run: npm run build
      - run: npx playwright test
      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: playwright-report
          path: playwright-report/
  deploy:
    needs: test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm i -g vercel
      - run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
      - run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
      - run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}

Caching and speed

cache: npm restores node_modules quickly, and persisting .next/cache with actions/cache keyed on package-lock.json plus source hashes speeds incremental builds. Cache the Playwright browser binaries (~/.cache/ms-playwright) keyed on the Playwright version to skip re-downloading Chromium every run. Browser installs and e2e runs are heavy, so cheaper managed runners such as Latchkey (around 69% cheaper than GitHub-hosted) keep PR feedback fast and auto-retry transient browser-download failures.

Deploying

The deploy job uses the Vercel CLI with VERCEL_TOKEN, VERCEL_ORG_ID, and VERCEL_PROJECT_ID secrets. vercel build --prod produces a prebuilt output and vercel deploy --prebuilt --prod promotes it, so the Vercel platform does not rebuild. Capture the deployment URL from the CLI output for smoke checks.

Key takeaways

  • Run Playwright against the production build so e2e tests match what ships.
  • Cache the Playwright browser binaries by version to skip repeated downloads.
  • Gate the Vercel deploy on a green test job and the main branch.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →