Skip to content
Latchkey

How to Run Per-Package Jobs With dorny/paths-filter in GitHub Actions

dorny/paths-filter emits one boolean output per named filter, which you use as an if guard on each package job.

Run dorny/paths-filter once in a detect job to classify the diff, expose its outputs, then gate each downstream package job with if: needs.detect.outputs.<name> == 'true'.

Steps

  • Add a detect job that runs dorny/paths-filter with a filter per package.
  • Promote each filter result to a job output.
  • Add needs: detect and an if: to each package job.

Workflow

.github/workflows/ci.yml
jobs:
  detect:
    runs-on: ubuntu-latest
    outputs:
      api: ${{ steps.f.outputs.api }}
      web: ${{ steps.f.outputs.web }}
    steps:
      - uses: actions/checkout@v4
      - uses: dorny/paths-filter@v3
        id: f
        with:
          filters: |
            api: 'packages/api/**'
            web: 'packages/web/**'
  api:
    needs: detect
    if: needs.detect.outputs.api == 'true'
    runs-on: ubuntu-latest
    steps:
      - run: echo "build api"

Gotchas

  • Outputs are strings, so compare with == 'true', not as a raw boolean.
  • A required check that is skipped can block merges; pair gated jobs with a status aggregator.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →