What’s the best way to trigger a GitHub Actions workflow only when specific files or folders change? #164673
Why are you starting this discussion?Question What GitHub Actions topic or product is this about?Misc Discussion DetailsI have a monorepo setup, and I want to run certain workflows only when files in a specific folder (like /backend/ or /docs/) are modified. I’ve tried using paths in the on.push trigger, but I’m not sure if I’m doing it optimally or if it works with pull requests too. What’s the best practice for this use case? Here’s a snippet of what I’m currently using: on: |
Replies: 3 comments 1 reply
GitHub Actions Path Filtering for MonoreposThis is about GitHub Actions' path filtering capabilities, specifically for monorepo workflows. Let me break down the best practices and considerations: Optimal Path Filtering SetupFor your monorepo, you can optimize path filtering like this: on:
push:
paths:
- 'backend/**'
- 'backend/*'
pull_request:
paths:
- 'backend/**'
- 'backend/*'Key Considerations
Improved Approach for MonoreposConsider this more robust pattern: on:
push:
paths:
- 'backend/**'
- 'backend/*'
- 'package.json'
- 'yarn.lock'
- 'pnpm-lock.yaml'
- 'lerna.json'
pull_request:
paths-ignore:
- 'docs/**'
- 'README.md'Gotchas to Watch For
Advanced ExampleFor complex monorepos, consider using a matrix approach: jobs: |
|
The best way to trigger a GitHub Actions workflow only when specific files or folders change is by using the Here’s an example: name: Run on Specific File Changes
on:
push:
paths:
- 'src/**'
- 'config/*.yml'
pull_request:
paths:
- 'src/**'
- 'config/*.yml'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: echo "Changes detected in src or config folder."Explanation:
💡 Pro Tip: If you're combining multiple workflows, use |
|
For a single folder, Monorepos with several services usually want something else: run CI only for the projects that changed, plus the projects that depend on them (change
I maintain an open-source action that does step 1 without any config. It detects projects from jobs:
plan:
runs-on: ubuntu-latest
outputs:
build: ${{ steps.plan.outputs.build }}
has_build: ${{ steps.plan.outputs.has_build }}
paths: ${{ steps.plan.outputs.paths }}
steps:
- uses: actions/checkout@v4
- uses: Continuous-Actions/dynamic-monorepo@v1
id: plan
build:
needs: plan
if: needs.plan.outputs.has_build == 'true'
runs-on: ubuntu-latest
strategy:
matrix:
project: ${{ fromJSON(needs.plan.outputs.build) }}
steps:
- uses: actions/checkout@v4
- run: echo "build ${{ matrix.project }}"
working-directory: ${{ fromJSON(needs.plan.outputs.paths)[matrix.project] }}Demo with example PRs: https://github.com/Continuous-Actions/dynamic-monorepo-demo. Whatever tool you use, the plan → |
GitHub Actions Path Filtering for Monorepos
This is about GitHub Actions' path filtering capabilities, specifically for monorepo workflows. Let me break down the best practices and considerations:
Optimal Path Filtering Setup
For your monorepo, you can optimize path filtering like this:
Key Considerations
Double Asterisk (
**) vs Single Asterisk (*):backend/**matches all files in backend and its subdirectoriesbackend/*matches only files directly in the backend directoryPull Request Behavior: