Toolkit Extensions
Affected Package Detection Enterprise
The affected command detects which workspace packages are impacted by git changes and runs commands only on those packages. This dramatically speeds up CI pipelines by skipping unchanged packages. The workspace may sit in a subdirectory of a larger git repository: changed files are read relative to the workspace root.
apps/template_app/features/auth/auth_impl/home/home_impl/infrastructure/flagr_feature_flag_impl/grafana_monitoring_impl/network_sdk_api/network_sdk_dio/network_sdk_http/
abstract interface class HttpClient() { /// Sends a GET request to the specified [path]. Future<HttpResponse> get(String path, {/* … */}); // …}Usage
# List affected packages
dart run monorepo_toolkit affected list
# Run analysis on affected packages only
dart run monorepo_toolkit affected analyze
# Run tests on affected packages only
dart run monorepo_toolkit affected test --coverage
# Run any command on affected packages
dart run monorepo_toolkit affected run -- "dart format --set-exit-if-changed ."Subcommands
affected list
Lists packages affected by git changes compared to a base branch:
dart run monorepo_toolkit affected list --base develop
dart run monorepo_toolkit affected list --format plain # CI-friendly output| Flag | Abbr | Default | Description |
|---|---|---|---|
--base | -b | main | Base branch or commit to compare against |
--format | -f | pretty | Output format: pretty or plain |
--json | -j | false | Output as JSON array for GitHub Actions matrix |
affected analyze
Runs flutter analyze lib on affected packages. A package without lib/ is skipped:
dart run monorepo_toolkit affected analyze --base develop
dart run monorepo_toolkit affected analyze --no-fail-fast
dart run monorepo_toolkit affected analyze --no-fatal-infos --no-fatal-warnings # what generated CI and `melos run analyze` use| Flag | Abbr | Default | Description |
|---|---|---|---|
--base | -b | main | Base branch or commit to compare against |
--fail-fast | true | Stop on first package failure | |
--fatal-infos | true | Fail on info-level issues (--no-fatal-infos to allow them) | |
--fatal-warnings | true | Fail on warnings (--no-fatal-warnings to allow them) |
affected test
Runs flutter test on affected packages with optional coverage collection. Golden-tagged tests are excluded (--exclude-tags golden) unless you pass --goldens, because goldens fail on machines whose rasterizer differs from the fixtures. A package without a test/ directory is skipped, and one whose only tests are excluded (flutter test exit code 79) counts as passed:
dart run monorepo_toolkit affected test --coverage --base develop| Flag | Abbr | Default | Description |
|---|---|---|---|
--base | -b | main | Base branch or commit to compare against |
--coverage | false | Collect coverage information | |
--goldens | false | Include golden-tagged tests | |
--fail-fast | true | Stop on first package failure | |
--total-shards | — | — | Total number of shards for within-package test splitting |
--shard-index | — | — | Zero-based index of this shard (requires --total-shards) |
affected run
Runs an arbitrary command on affected packages:
dart run monorepo_toolkit affected run -- "flutter test --coverage"
dart run monorepo_toolkit affected run -- "dart format --set-exit-if-changed ."| Flag | Abbr | Default | Description |
|---|---|---|---|
--base | -b | main | Base branch or commit to compare against |
--fail-fast | true | Stop on first package failure |
affected format
Checks formatting (dart format --set-exit-if-changed .) on affected packages. Flags: --base/-b (default main), --fail-fast (default true).
affected fix-check
Runs dart fix --dry-run on affected packages and fails if any fixes are suggested. Flags: --base/-b, --fail-fast.
affected golden
Runs flutter test --update-goldens on affected packages. Pass --check to verify without updating (flutter test --tags golden).
| Flag | Abbr | Default | Description |
|---|---|---|---|
--base | -b | main | Base branch or commit to compare against |
--check | false | Verify goldens without updating them | |
--fail-fast | true | Stop on first package failure |
affected build
Runs flutter build on affected app packages only (library packages are skipped).
| Flag | Abbr | Default | Description |
|---|---|---|---|
--base | -b | main | Base branch or commit to compare against |
--platform | -p | apk | Build target: apk, aab, ios, ipa (iOS targets need macOS + Xcode) |
--fail-fast | true | Stop on first package failure |
affected license
Audits transitive dependency licenses of affected packages and fails on any license outside the allowlist (MIT, Apache-2.0, BSD-3-Clause, BSD-2-Clause, ISC, Zlib by default).
| Flag | Abbr | Default | Description |
|---|---|---|---|
--base | -b | main | Base branch or commit to compare against |
--allow | Extra SPDX license identifier to allow (repeatable) | ||
--fail-fast | false | Stop on first package with a disallowed license |
affected devtool
Runs other workspace devtools scoped to the affected packages. Subcommands: size-guard (--base, --changed-only), dependency-graph (--base, --format/-f, --output/-o) and coverage (--base, --fail-fast).
dart run monorepo_toolkit affected devtool coverage --base origin/developConfiguration
Create an affected.yaml at the workspace root:
affected:
base_branch: develop
# Predefined commands (merged with defaults: analyze, test, format)
commands:
lint: "dart run custom_lints ."
# Packages always included regardless of changes
always_include:
- template_app
# Glob patterns to ignore when detecting changes
ignore:
- "devtools/**"
- ".github/**"
- ".claude/**"The default ignore patterns are devtools/**, .github/**, and .claude/**. The default predefined commands are analyze (flutter analyze lib), test (flutter test), and format (dart format --set-exit-if-changed .).
CI integration
Generated projects already call it: devtools/ci/test.sh runs affected analyze --no-fatal-infos --no-fatal-warnings and affected test --coverage with the base that devtools/ci/scope.sh picks (see CI test scope). By hand:
steps:
- name: Analyze affected packages
run: dart run monorepo_toolkit affected analyze --base origin/develop
- name: Test affected packages
run: dart run monorepo_toolkit affected test --coverage --base origin/developGitHub Actions Matrix (CI Parallelism)
Use affected list --json to feed a dynamic matrix into GitHub Actions, so each affected package is tested in its own parallel job.
jobs:
detect:
runs-on: ubuntu-latest
outputs:
packages: ${{ steps.affected.outputs.packages }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: dart-lang/setup-dart@v1
- name: Detect affected packages
id: affected
run: |
PACKAGES=$(dart run monorepo_toolkit affected list --json --base origin/develop)
echo "packages=$PACKAGES" >> "$GITHUB_OUTPUT"
test:
needs: detect
if: ${{ needs.detect.outputs.packages != '[]' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
package: ${{ fromJSON(needs.detect.outputs.packages) }}
steps:
- uses: actions/checkout@v4
- uses: dart-lang/setup-dart@v1
- name: Test ${{ matrix.package }}
run: dart run monorepo_toolkit affected test --base origin/developThe --json flag outputs a JSON array of package names (e.g. ["auth_impl","ui_kit"]). GitHub's fromJSON() function expands this into the matrix, creating one job per affected package automatically. See ci-affected-matrix.yml.example in the generated project's devtools/scripts/affected/ directory for the full annotated example (copy it into .github/workflows/ to use it).