Best practice · Trigger Scope

Filter workflows by path in GitHub Actions

Add `paths` or `paths-ignore` to expensive workflows so a docs-only or unrelated change doesn't trigger the full test suite.

Do this

Expensive workflows (E2E, full integration suites) declare a paths filter listing the source directories that can actually affect them, or a paths-ignore list for docs and markdown. A README change no longer spins up the entire suite.12

Only run when relevant files change
on:
  pull_request:
    paths:
      - "src/**"
      - "package.json"
      - "pnpm-lock.yaml"
      - ".github/workflows/e2e.yml"   # re-run if the workflow itself changes

Avoid this

A docs-only change spins up the full suite, spending wall-clock and runner minutes for nothing.

Runs on every change, including docs
on:
  pull_request:   # a one-word README fix triggers the full E2E suite

Why it matters

Running an expensive suite on changes that can't affect it is pure waste, both wall-clock the developer waits on and runner-minutes you pay for. Path filters are a high-impact, low-risk trigger fix. The one thing to watch: if a *required* status check is path-filtered, a skipped run never reports its status, and GitHub has no branch-protection setting that treats a missing check as passed, so the PR waits forever. Either don't make the path-filtered workflow a required check, or gate the work with a job-level if: condition instead of a workflow-level paths filter: GitHub reports a job skipped by a conditional as Success, which satisfies the required check, whereas a skipped workflow reports nothing at all.

When to use

Use it when

Workflows with several jobs and a clear set of source paths that gate them, especially E2E and integration suites.

Be careful when

Be careful path-filtering a *required* status check: a filtered-out workflow never reports, and GitHub can't treat a missing check as satisfied, so the PR stays blocked. Prefer path-filtering non-required expensive workflows. If the check must stay required, gate the work with a job-level if: condition instead: a job skipped by a conditional reports Success and satisfies the check, unlike a workflow skipped by paths.

Verify on your repo

Hand this prompt to your coding agent (Claude Code, Cursor, and the like) to audit and fix this practice in your own repo.

Prompt for your coding agent
Inspect this repo's .github/workflows for expensive workflows (E2E, integration suites) that trigger on every change with no path scoping. For each, look at the `on:` block for `paths:` or `paths-ignore:` and flag multi-job workflows that have neither. Add a `paths` allowlist of the source directories that can actually affect the workflow (include the workflow file itself) so a docs-only change does not spin up the full suite. Important: do not path-filter a *required* status check, since a skipped workflow never reports and blocks the PR forever, so instead gate the expensive work with a job-level `if:` condition (a job skipped by a conditional reports Success). Show me the diff and open a PR rather than applying it blindly.
Prefer to check by hand?
  1. Look at the on: block of each expensive workflow for paths: or paths-ignore:.

  2. Flag workflows with several jobs and no path filtering at all.

  3. For any *required* check, don't path-filter the whole workflow: either drop it from the required list, or gate the expensive work with a job-level if: (a job skipped by a conditional reports Success), so PRs aren't blocked waiting on a check that never runs.

More best practices for GitHub Actions

Where to go next in the CI best-practices catalog.

All CI best practices

FAQ

Should I use paths or paths-ignore?

paths is an allowlist (run only when these change) and is safest for a suite with a well-defined source set. paths-ignore is a denylist (skip when only these change) and fits when you mainly want to exclude docs and markdown. Don't set both on the same event.

Will a path filter break a required status check?

It can. When a workflow is skipped by a paths filter, its check context never reports, and branch protection waits for it forever, GitHub has no setting that counts a missing check as passed. The safe fix: don't require a path-filtered workflow, or gate the expensive job with a job-level if: condition instead. GitHub reports a job skipped by a conditional as Success (which satisfies the required check), whereas a skipped workflow reports nothing.

Sources

1GitHub Actions · paths / paths-ignore filters (opens in new tab)

2GitHub · troubleshooting required status checks (opens in new tab)

Last updated 2026-07-06

Get started

Don't run the full suite on a docs change.

One line to install. Faster runs on day one, and agents that open reviewable PRs to keep your pipeline following practices like this one.