Safeguard
Developer Tools•

Can GitHub Actions path filters run security scans per package?

Path filters can run a scan only when a package changes, but a skipped workflow leaves required checks pending. Learn a safe pattern for required checks.

Safeguard Security Team
4 min read

Yes, path filters can start a scan workflow when files in one package change. The catch is that a skipped workflow leaves its checks in a Pending state, and a pull request that requires those checks cannot merge. Plan for that before you make a path filtered scan a required check.

How path filters behave

The GitHub Actions workflow syntax reference says that if at least one path matches a pattern in the paths filter, the workflow runs. With paths-ignore, the workflow does not run when all changed paths match the ignore patterns. You cannot use both for the same event in one workflow. You can use a leading exclamation mark inside paths to exclude, and order matters. Glob patterns use star and double star.

For pull requests, GitHub builds the changed file list with a three dot diff, which compares the latest topic branch version with the commit where it last synced with the base branch.

on:
  pull_request:
    paths:
      - 'services/payments/**'
      - 'libs/shared/**'

The pending check trap

GitHub states that if path filtering skips a workflow, its associated checks remain Pending, and a pull request that requires those checks to pass is blocked from merging. Then a docs only pull request cannot merge because the payments scan never ran.

You have three ways out.

ApproachHow it worksTrade off
Always run, decide insideTrigger on every pull request, detect changes in a first job, skip later jobsThe check reports success when skipped
Aggregate checkOne always running job that waits for conditional jobsOne extra job to maintain
Do not require the scanRun it as advisoryWeaker control

Detecting changes inside a workflow that always starts avoids the skipped workflow case. How a skipped job inside that workflow counts toward a required check depends on your settings, so test it on a throwaway pull request before you rely on it.

Shared code needs listing

A path filter for one package misses changes in the libraries it imports. If payments uses libs/shared, list both paths, or derive the affected set from your build graph. See scan only affected packages.

Lockfile changes are another case. A root lockfile change can affect many packages at once, so include the lockfile in every package filter or run everything when it changes.

Diff limits

The reference also describes limits. A push with more than 1,000 commits always runs the workflow. If generating the diff times out, the workflow always runs. If the diff has more than 3,000 files and the matches fall outside the first 3,000 returned, the workflow does not run. Large refactors can therefore behave oddly, so keep a scheduled full scan as a backstop.

A sound setup

  1. Run a full scan on a schedule, for example nightly.
  2. On pull requests, scan affected packages.
  3. Make one aggregate job the required check.
  4. Block on new high severity findings only.

Safeguard offers policies and gates that can stop a pull request on new findings. See the demo for how a gate behaves, and try the free scan at https://gold.safeguard.sh/scan.

Try it yourself

Click through the gate demo and notice what makes a pull request pass or fail.

Click through it at your own pace, or open it full screen.

Quick check

What happens to a required check when path filters skip the workflow?

It stays Pending and blocks the merge, according to GitHub documentation.

Why keep a scheduled full scan?

Path filters can miss changes in shared code, and diff limits can cause runs to be skipped or forced.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.