VisCommandsvis ci ignore

vis ci ignore

CI build gating for Vercel and Netlify 'Ignored Build Step' — exits with inverted codes so deployment platforms skip unaffected builds.

vis ci ignore

Decide whether a deployment should proceed, based on whether a given project is affected by the current commit. Drops directly into Vercel's "Ignored Build Step" and Netlify's ignore field using inverted exit codes.

Inspired by nx-ignore but reuses vis's own affected detection — no parallel Nx install required on the deploy runner.

Usage

vis ci ignore <project> [options]

Exit codes

vis ci ignore uses inverted exit codes so it matches the contract Vercel and Netlify expect from an ignore hook:

Exit codeMeaningPlatform behavior
0Project is not affectedCancels the build
1Project is affectedContinues the build

Pass --exit-zero-on-build to invert this back to normal semantics (useful for local testing and for gating downstream CI jobs where 0 = success).

Examples

# Vercel / Netlify default — uses CI env vars automatically
vis ci ignore my-app

# Explicit base ref
vis ci ignore my-app --base "$VERCEL_GIT_PREVIOUS_SHA"

# Emit the decision as JSON (pipe into jq in GitHub Actions)
vis ci ignore my-app --json

# Normal exit semantics for local testing
vis ci ignore my-app --exit-zero-on-build

# Debug the decision path
vis ci ignore my-app --verbose

Options

OptionDefaultDescription
--base <ref>CI env var, then HEAD~1Git base ref for the affected comparison
--head <ref>HEADGit head ref for the affected comparison
--downstream <none|direct|deep>deepHow far to follow dependents of changed projects
--upstream <none|direct|deep>noneHow far to follow dependencies of changed projects
--jsonfalseEmit the decision as JSON on stdout instead of text
--exit-zero-on-buildfalseDisable inverted exit codes (build exits 0, not 1)
--verbosefalsePrint debug info about the decision path

How it works

  1. Commit-message gating — reads the latest commit message and short-circuits on skip or force-deploy keywords before touching git diff.
  2. Workspace discovery — resolves the workspace root and verifies that the requested project actually exists. Unknown projects exit with build (defensive default).
  3. Base ref resolution — walks --base flag → CI env var chain → HEAD~1. If the resolved ref isn't reachable (e.g. Vercel's shallow clone), silently falls back to HEAD~1.
  4. Affected detection — runs the same getAffectedProjects pipeline as vis affected, respecting --downstream and --upstream scope.
  5. Decision emit — prints the outcome (human text or JSON) and calls process.exit with the inverted exit code.

Commit-message keywords

Keywords take precedence over git-diff detection — useful for emergency bypasses and forced deploys.

Skip build

TokenScope
[skip ci]All projects
[ci skip]All projects
[no ci]All projects
[vis skip]All projects
[vis skip <project>]Single project
[nx skip]All projects (legacy, for migration)
[nx skip <project>]Single project (legacy)

Force build

TokenScope
[vis deploy]All projects
[vis deploy <project>]Single project
[nx deploy]All projects (legacy)
[nx deploy <project>]Single project (legacy)

Legacy [nx …] tokens are accepted so teams migrating from nx-ignore don't have to rewrite their commit automation on day one.

Base SHA resolution order

vis ci ignore probes these env vars in order. The first non-empty match wins, unless --base is passed explicitly.

PriorityEnv varProvider
1--base <ref> flagExplicit override
2CACHED_COMMIT_REFNetlify
3VERCEL_GIT_PREVIOUS_SHAVercel
4GITHUB_BASE_REFGitHub Actions
5CI_COMMIT_BEFORE_SHAGitLab CI
6HEAD~1Fallback

Cloudflare Pages, Cloudflare Workers Builds, Render, and AWS Amplify are not detected here — their platforms don't invoke custom ignore scripts at all, so env detection would only create the illusion of support. See the supported platforms matrix.

JSON output

--json writes a structured decision record to stdout and suppresses the human text. Useful for pipelines that gate downstream jobs on the decision.

{
    "project": "my-app",
    "action": "skip",
    "reason": "project-not-affected",
    "message": "Skip my-app: not affected by changes between HEAD~1...HEAD",
    "base": "HEAD~1",
    "head": "HEAD",
    "affectedProjects": ["other-app"]
}

Reason codes

ReasonWhen it's emitted
commit-skipCommit message contains a skip token
commit-force-deployCommit message contains a force-deploy token
no-changesGit diff shows no changed files between base and head
project-affectedProject appears in the affected set
project-not-affectedProject does not appear in the affected set
project-unknownProject not found in the workspace
missing-project-argumentCommand was invoked without a project name
workspace-errorWorkspace root or discovery failed

Decisions with reasons project-unknown, missing-project-argument, and workspace-error always map to action: "build" — we never cancel a build because of a tooling problem.

Supported platforms

PlatformNative hookvis ci ignore works?
VercelIgnored Build StepYes — drop-in
Netlifyignore in netlify.tomlYes — drop-in
GitHub ActionsNone (CI gating only)Yes — via --json + job if: conditions
GitLab CINone (CI gating only)Yes — via --json + rules:
Cloudflare PagesBuild Watch Paths (globs)No — platform doesn't invoke custom scripts
Cloudflare Workers BuildsBuild Watch PathsNo — same reason
RenderBuild Filters (globs)No — use their path filters
AWS Amplify[skip-cd] commit keywordNo — no custom-command hook

For platforms without a native hook, use their built-in path filtering alongside vis, or move CI gating into GitHub Actions / GitLab CI and wrap vis ci ignore --json there.

See the CI/CD guide for complete deployment integration examples.

See also

  • vis affected — run a target only on affected projects (what vis ci ignore is built on)
  • CI/CD guide — full deployment integration patterns
Support

Contribute to our work and keep us going

Community is the heart of open source. The success of our packages wouldn't be possible without the incredible contributions of users, testers, and developers who collaborate with us every day.Want to get involved? Here are some tips on how you can make a meaningful impact on our open source projects.

Ready to help us out?

Be sure to check out the package's contribution guidelines first. They'll walk you through the process on how to properly submit an issue or pull request to our repositories.

Submit a pull request

Found something to improve? Fork the repo, make your changes, and open a PR. We review every contribution and provide feedback to help you get merged.

Good first issues

Simple issues suited for people new to open source development, and often a good place to start working on a package.
View good first issues