Skip to content

Instantly share code, notes, and snippets.

@jmsaavedra
Created October 14, 2025 23:26
Show Gist options
  • Select an option

  • Save jmsaavedra/922b9bbe64d0090ec08f125ce9f4f880 to your computer and use it in GitHub Desktop.

Select an option

Save jmsaavedra/922b9bbe64d0090ec08f125ce9f4f880 to your computer and use it in GitHub Desktop.
Vercel Ignored Build Command

Vercel Ignored Build Step Command Explanation

My Favorite Version

if [[ "$VERCEL_GIT_COMMIT_REF" != "main" ]]; then exit 1; fi; git diff HEAD^ HEAD --quiet -- . && exit 0 || exit 1

What It Does

This command intelligently controls when Vercel builds your project in a monorepo setup:

  • Always builds feature/development branches - Ensures you can test and preview all branches
  • Skips unnecessary builds on main - Only builds when files in this project actually change
  • Saves build time and resources - Prevents rebuilding when changes are in other parts of the monorepo

How It Works

Part 1: Feature Branch Check

if [[ "$VERCEL_GIT_COMMIT_REF" != "main" ]]; then exit 1; fi;

What this does:

  • Checks if the current branch is NOT main
  • If it's a feature branch (like refactor-optimization, develop, etc.), it exits with code 1
  • Exit code 1 = BUILD (tells Vercel to proceed with deployment)

Why this is important:

  • You always want to deploy feature branches for testing and preview
  • Skipping builds on feature branches would prevent you from seeing your changes
  • This ensures every branch push gets a deployment URL for review

Part 2: Main Branch Change Detection

git diff HEAD^ HEAD --quiet -- . && exit 0 || exit 1

What this does:

  • Only runs if we didn't exit in Part 1 (i.e., we're on main branch)
  • Compares the last commit (HEAD) with its parent (HEAD^)
  • The -- . means "only check files in the current directory" (respects Vercel's Root Directory setting)
  • --quiet means don't output anything, just return an exit code

Exit code logic:

  • If git diff finds NO changes: returns 0 → exit 0 = SKIP BUILD
  • If git diff finds changes: returns 1 → exit 1 = BUILD

Why this is important:

  • In a monorepo, commits might change katachi-generator/ but not public-site/
  • This prevents rebuilding public-site when only katachi-generator changed
  • Saves build minutes and speeds up deployments

Vercel Environment Variables Used

$VERCEL_GIT_COMMIT_REF

  • The branch name of the current deployment
  • Examples: main, develop, refactor-optimization
  • Vercel Docs

Current Directory Context

  • The command runs in the directory specified by Vercel's "Root Directory" setting
  • For public-site: Root Directory = public-site
  • For mcp-server: Root Directory = mcp-server
  • The . in git diff ... -- . refers to this root directory

Exit Codes Explained

Vercel uses exit codes to determine build behavior:

Exit Code Meaning Result
0 No build needed ⏭️ Skip deployment
1 or greater Build needed ✅ Create deployment

Use Cases

Scenario 1: Feature Branch Push

Branch: refactor-optimization
Action: Push new commits
Result: ✅ BUILD (always build feature branches)
Reason: First condition exits with 1

Scenario 2: Main Branch - No Public Site Changes

Branch: main
Last commit: Only touched katachi-generator/
Action: Push to main
Result: ⏭️ SKIP (no changes in public-site/)
Reason: git diff finds no changes in current directory

Scenario 3: Main Branch - Public Site Changes

Branch: main
Last commit: Modified public-site/components/foo.tsx
Action: Push to main
Result: ✅ BUILD (files changed in this directory)
Reason: git diff finds changes, returns 1

Monorepo Structure

This command is designed for a monorepo with multiple deployable projects:

katachi-gen/
├── public-site/          ← Vercel Project 1 (Next.js app)
│   └── vercel.json
├── mcp-server/           ← Vercel Project 2 (MCP server)
│   └── vercel.json
└── katachi-generator/    ← Not deployed to Vercel

Each Vercel project uses:

  • Root Directory: Set to its subdirectory (public-site or mcp-server)
  • Ignored Build Step: This command (to skip unnecessary builds)

Setting It Up in Vercel

  1. Go to your Vercel project settings
  2. Navigate to Git section
  3. Find Ignored Build Step field
  4. Paste the command:
    if [[ "$VERCEL_GIT_COMMIT_REF" != "main" ]]; then exit 1; fi; git diff HEAD^ HEAD --quiet -- . && exit 0 || exit 1
  5. Set Root Directory to your project's subdirectory (e.g., public-site)
  6. Save

Benefits

For Development

  • ✅ Every feature branch gets a preview deployment
  • ✅ Can test changes before merging to main
  • ✅ Unique preview URL for each branch

For Production (main branch)

  • ✅ Only builds when files actually change
  • ✅ Skips builds when other parts of monorepo change
  • ✅ Saves Vercel build minutes
  • ✅ Faster feedback loop

For CI/CD

  • ✅ Reduces unnecessary builds
  • ✅ Saves resources
  • ✅ Clearer deployment history (only meaningful builds)

Troubleshooting

Problem: Feature branch not building

Check: Make sure VERCEL_GIT_COMMIT_REF is set correctly Solution: The first condition should catch all non-main branches

Problem: Main branch always building even with no changes

Check: Verify Root Directory is set correctly in Vercel Solution: The . in git diff -- . must point to your project's directory

Problem: Main branch not building when it should

Check: Did you modify files in the correct directory? Solution: Git diff only checks files in the Root Directory

Problem: "shallow clone" issues

Note: Vercel does git clone --depth=10 (only last 10 commits) Solution: This command works with shallow clones because it only checks HEAD^ to HEAD

Alternative Approaches

Option 1: Always build everything (simple but wasteful)

exit 1
  • Pros: Simple, always works
  • Cons: Wastes build minutes, slow feedback

Option 2: Check against previous deployment SHA

git diff $VERCEL_GIT_PREVIOUS_SHA $VERCEL_GIT_COMMIT_SHA --quiet -- . && exit 0 || exit 1
  • Pros: Checks all commits in a push
  • Cons: Can be unpredictable for first deployments or branch switches

Option 3: Branch-specific logic (what we use)

if [[ "$VERCEL_GIT_COMMIT_REF" != "main" ]]; then exit 1; fi; git diff HEAD^ HEAD --quiet -- . && exit 0 || exit 1
  • Pros: Best of both worlds - always build features, smart on main
  • Cons: Slightly more complex

Example Build Logs

Feature Branch (builds)

Running "if [[ "$VERCEL_GIT_COMMIT_REF" != "main" ]]; then exit 1; fi; ..."
✅ - Build can proceed (feature branch)
Building...

Main Branch - No Changes (skips)

Running "if [[ "$VERCEL_GIT_COMMIT_REF" != "main" ]]; then exit 1; fi; ..."
Running git diff HEAD^ HEAD --quiet -- .
⏭️ - The Deployment has been canceled (no changes detected)

Main Branch - With Changes (builds)

Running "if [[ "$VERCEL_GIT_COMMIT_REF" != "main" ]]; then exit 1; fi; ..."
Running git diff HEAD^ HEAD --quiet -- .
✅ - Build can proceed (changes detected)
Building...

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment