GitHub Actions Deploy to Vercel Workflow

Generate a Vercel deployment GitHub Actions workflow with preview/prod gates

Build a GitHub Actions workflow that deploys to Vercel: preview builds on pull requests and production deploys on main merges, using the Vercel CLI with token, org ID, and project ID secrets handled correctly. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

Why use the Vercel CLI instead of the Git integration?

The Vercel Git integration auto-deploys but gives you little control over build steps, gating, or running tests first. A CLI workflow lets you run lint and tests as a gate and deploy only after they pass, while still producing real Vercel deployments.

A continuous-deployment workflow lets every push and pull request build and deploy to Vercel automatically, with tests as a gate. This generator produces a ready-to-commit GitHub Actions YAML file that uses the official Vercel CLI to create preview deployments on pull requests and production deployments when you merge to your release branch.

Why use the CLI rather than Vercel’s Git integration?

Vercel’s built-in Git integration is fast to set up but gives you limited control: it deploys on every push with no way to gate on test results or run custom build steps first. The CLI workflow gives you:

  • Tests as a hard gate — deploy only after tests pass
  • Custom build steps — run code generation, asset compilation, or migrations before building
  • Preview URLs in PR comments — post the preview URL back to the PR automatically
  • Branch-based production promotion — only main (or your chosen branch) gets the --prod flag

The three-step Vercel CLI flow

The workflow follows Vercel’s recommended prebuilt pattern, using three repository secrets: VERCEL_TOKEN, VERCEL_ORG_ID, and VERCEL_PROJECT_ID.

- name: Pull Vercel environment
  run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}

- name: Build
  run: vercel build --token=${{ secrets.VERCEL_TOKEN }}

- name: Deploy
  run: vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }}

For production, pull uses --environment=production and deploy adds --prod:

- run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}

This split matters: vercel pull fetches the environment variables and project settings for the target environment (preview and production have separate env var sets in Vercel), so vercel build runs with exactly the right config. Building --prebuilt then uploads the local output rather than triggering a second remote build.

Setting up the secrets

  1. Run vercel link in your project directory once locally. This creates .vercel/project.json containing orgId and projectId.
  2. Get a Vercel token from your account settings under Tokens — use a scoped token, not your personal account token.
  3. Add three GitHub repository secrets under Settings → Secrets and variables → Actions:
    • VERCEL_TOKEN — the token from step 2
    • VERCEL_ORG_ID — the orgId from .vercel/project.json
    • VERCEL_PROJECT_ID — the projectId from .vercel/project.json

Practical tips

  • Gate deploys on tests. Add a test job and make the deploy job declare needs: test. A failed test blocks the deploy automatically.
  • Cancel stale preview builds. Add a concurrency group keyed on the PR number so only the latest commit in a PR builds; earlier pushes are cancelled.
  • Post the preview URL to the PR. Capture the URL from vercel deploy output and post it as a PR comment using peter-evans/create-or-update-comment.
  • Handle preview vs production separately. The generator writes two jobs (or a single job with conditional flags) so the environments use the correct Vercel environment variable sets.