How to stop hand-maintaining monorepo CI path filters!
Introduction
Monorepo CI has one recurring chore: every workflow carries a paths: list that someone has to keep in sync with the code. Add a shared library, forget to add it to three filters, and a breaking change sails through CI untested. dynamic-monorepo is a GitHub Action that works out which projects a push or pull request affects, including projects that depend on what changed. It reads the manifests you already have (package.json workspaces, go.mod, Cargo.toml, pyproject, pom.xml, Gradle, .csproj, Dockerfile, Helm), so most repos need no config at all!
Example 1: Consolidating workflows
All separate workflows into one rajadilipkolli/spring-boot-microservices-series-v2 is a Spring Boot microservices showcase with eight services. Each service had its own near-identical workflow and its own paths: filter.
Workflow YAML (first copy)
jobs: plan: runs-on: ubuntu-latest outputs: services: ${{ steps.plan.outputs.build }} has_services: ${{ steps.plan.outputs.has_build }} steps: - uses : actions/checkout@v4 - uses : Continuous-Actions/dynamic-monorepo@v1 id : plan build: needs : plan if : needs.plan.outputs.has_services == 'true' strategy : matrix : service : ${{ fromJSON(needs.plan.outputs.services) }} # ...same build steps as before, written once
The result:
- 9 files changed, +73 / −467 lines.
- Adding a service is one entry in config, not a copied workflow.
- Docs-only changes build nothing.
- A dependency bump in one service builds just that service.
Example 2: Adding a safety net
Not every team wants to restructure CI. uni-helper/create-uni kept its existing per-package workflows. Running the audit on main found 11 problems across 4 workflows. For example, packages/core depends on the workspace packages @create-uni/shared and @create-uni/config, but its test workflows only watched packages/core/**. A PR that touched only the shared package never ran the core tests.
- Fixed the filters, with 12 lines, all inside
on.*.paths. - Added a small audit workflow so the filters can't drift again.
The audit compares every workflow's paths: list with the dependency graph and flags three problems:
- A workflow watches
packages/app/**but not a packageappdepends on, so a change there skips the workflow.
Comments
No comments yet. Start the discussion.