Skip to main content Configure Vercel CI/CD integration with GitHub Actions and testing.
Use when setting up automated testing, configuring CI pipelines,
or integrating Vercel tests into your build process.
Trigger with phrases like "vercel CI", "vercel GitHub Actions",
"vercel automated tests", "CI vercel".
npx skills add jeremylongshore/claude-code-plugins-plus-skills --skill vercel-ci-integration ai automation claude-code devops mcp ai-agents
Vercel CI Integration
Overview
Set up automated Vercel deployments in GitHub Actions with preview deployments on PRs, production deploys on merge to main, and optional test gating. Covers both Vercel's built-in Git integration and custom CI pipelines using the Vercel CLI.
Prerequisites
GitHub repository with Actions enabled
Vercel project linked to the repo
VERCEL_TOKEN stored as GitHub Secret
VERCEL_ORG_ID and VERCEL_PROJECT_ID from .vercel/project.json
Instructions
Step 1: Store CI Secrets in GitHub
# Get project and org IDs
cat .vercel/project.json
# {"orgId":"team_xxx","projectId":"prj_xxx"}
# Add secrets to GitHub repo
gh secret set VERCEL_TOKEN --body "your-vercel-token"
gh secret set VERCEL_ORG_ID --body "team_xxx"
gh secret set VERCEL_PROJECT_ID --body "prj_xxx"
Step 2: GitHub Actions — Preview on PR
# .github/workflows/vercel-preview.yml
name: Vercel Preview Deployment
on:
pull_request:
branches: [main]
jobs:
deploy-preview:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Vercel CLI
run: npm install -g vercel@latest
- name: Pull Vercel Environment
run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
- name: Build Project
run: vercel build --token=${{ secrets.VERCEL_TOKEN }}
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
- name: Deploy Preview
id: deploy
run: |
url=$(vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }})
echo "preview_url=$url" >> $GITHUB_OUTPUT
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
- name: Comment PR with Preview URL
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `Preview deployed: ${{ steps.deploy.outputs.preview_url }}`
})
Step 3: GitHub Actions — Production on Merge # .github/workflows/vercel-production.yml
name: Vercel Production Deployment
on:
push:
branches: [main]
jobs:
deploy-production:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Vercel CLI
run: npm install -g vercel@latest
- name: Pull Vercel Environment
run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
- name: Build Project
run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
- name: Deploy Production
run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
Step 4: Test Gating — Run Tests Before Deploy # .github/workflows/vercel-gated.yml
name: Gated Vercel Deploy
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: npm ci
- run: npm test
- run: npm run lint
- run: npx tsc --noEmit
deploy:
needs: test # Only deploy if tests pass
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm install -g vercel@latest
- run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
- run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
- run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
Step 5: Skip Builds for Non-Code Changes // vercel.json — skip build when only docs change
{
"ignoreCommand": "git diff HEAD^ HEAD --quiet -- . ':!docs' ':!*.md' ':!.github'"
}
Or in the dashboard: Settings > Git > Ignored Build Step
Step 6: Vercel's Built-In Git Integration (Alternative) If you prefer Vercel's automatic deployments over custom CI:
Connect your GitHub repo in the Vercel dashboard
Vercel auto-deploys: preview on every push, production on merge to main
Configure in Settings > Git :
Production branch: main
Preview branches: all other branches
Auto-assign custom domains to production
This approach requires zero CI configuration but gives less control over test gating.
Output
Preview deployments on every PR with URL comment
Production deployments on merge to main (after tests pass)
Test gating preventing broken code from reaching production
Build skip rules for documentation-only changes
Error Handling Error Cause Solution Error: VERCEL_TOKEN is not setSecret not configured Add VERCEL_TOKEN as GitHub repo secret Error: Could not find projectWrong ORG_ID or PROJECT_ID Check .vercel/project.json values vercel pull failsToken lacks project access Regenerate token with correct scope Preview not commenting on PR Missing actions/github-script Add the comment step with correct permissions Build cache not working CI runs on fresh runner Use actions/cache for node_modules and .vercel/output
Resources
Next Steps For deployment orchestration, see vercel-deploy-integration.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Set up and use 1Password CLI (op). Use when installing the CLI, enabling desktop app integration, signing in (single or multi-account), or reading/injecting/running secrets via op.
CLI to manage emails via IMAP/SMTP. Use `himalaya` to list, read, write, reply, forward, search, and organize emails from the terminal. Supports multiple accounts and message composition with MML (MIME Meta Language).
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Set up and use 1Password CLI (op). Use when installing the CLI, enabling desktop app integration, signing in (single or multi-account), or reading/injecting/running secrets via op.
CLI to manage emails via IMAP/SMTP. Use `himalaya` to list, read, write, reply, forward, search, and organize emails from the terminal. Supports multiple accounts and message composition with MML (MIME Meta Language).