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--prodflag
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
- Run
vercel linkin your project directory once locally. This creates.vercel/project.jsoncontainingorgIdandprojectId. - Get a Vercel token from your account settings under Tokens — use a scoped token, not your personal account token.
- Add three GitHub repository secrets under Settings → Secrets and variables → Actions:
VERCEL_TOKEN— the token from step 2VERCEL_ORG_ID— theorgIdfrom.vercel/project.jsonVERCEL_PROJECT_ID— theprojectIdfrom.vercel/project.json
Practical tips
- Gate deploys on tests. Add a
testjob and make the deploy job declareneeds: test. A failed test blocks the deploy automatically. - Cancel stale preview builds. Add a
concurrencygroup 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 deployoutput and post it as a PR comment usingpeter-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.