DevTools
How to run CI only on changed Flutter packages
Enterprise Reference for affected: every variable, option and package it generates. Command: archipelago generate affected
Add the affected command, list the packages a git change touches, run tests and analysis on those only, and use it in a CI pipeline.
What you'll learn
- Adding the
affectedcommand to your monorepo toolkit - Listing the packages that a git change touches
- Running tests and analysis on those packages only
- Using the command in a CI pipeline
Prerequisites
- An existing Archipelago monorepo (see Monorepo Scaffolding)
monorepo_toolkitalready generated atdevtools/- An Enterprise subscription
Step 1: Generate the Affected Command
New Enterprise projects already include this brick. Run it on an older project:
archipelago generate affectedThe prompts are:
- appName: the name of your app
- isForMonorepo: leave this as
true
Or use a config file:
{
"appName": "MyApp",
"isForMonorepo": true
}archipelago generate affected --config affected_config.jsonStep 2: Understand the Generated Structure
The brick adds a library package. It has no bin/ entrypoint.
devtools/
└── scripts/
└── affected/
├── ci-affected-matrix.yml.example # Example GitHub Actions workflow
└── lib/src/
├── commands/ # list, analyze, test, run, build, ...
├── models/affected_config.dart
└── services/affected_service.dartThe post-generation hook adds the package to the workspace and to monorepo_toolkit. It then registers AffectedCommand in command_runner.dart.
Step 3: List the Affected Packages
Run every command through monorepo_toolkit:
dart run monorepo_toolkit affected list --base mainThe command compares your branch with main. It lists the changed packages and every package that depends on them.
Useful flags:
--format plainprints one package per line for scripts.--jsonprints a JSON array for a CI matrix.
Step 4: Run Checks on Affected Packages
dart run monorepo_toolkit affected analyze --base main
dart run monorepo_toolkit affected test --coverage --base main
dart run monorepo_toolkit affected run -- "dart format --set-exit-if-changed ."test skips golden-tagged tests unless you pass --goldens. A package with no tests counts as passed.
Step 5: Use It in CI
- name: Detect affected packages
id: affected
run: dart run monorepo_toolkit affected list --base origin/main --json > affected.json
- name: Test affected packages
run: dart run monorepo_toolkit affected test --base origin/mainThe brick ships ci-affected-matrix.yml.example with a dynamic matrix and sharded test jobs. Its detect job calls dart run devtools/scripts/affected. That path fails because the package has no bin/ entrypoint. Replace it with dart run monorepo_toolkit affected list --json.
For test sharding, pass --total-shards 4 --shard-index 0 to affected test.
Key Customization Points
| Customization | Where to Change |
|---|---|
| Base branch for comparison | The --base flag (default main) |
| Output format | The --format flag (pretty, plain) or --json |
| Stop on first failure | The --fail-fast flag (default true) |
| Shared command logic | devtools/scripts/affected/lib/src/services/affected_service.dart |
Next Steps
- Set up coverage management to measure the affected packages
- See the full affected guide for every subcommand