Skip to content

ci: run only affected integration targets - #549

Merged
boyan01 merged 2 commits into
mainfrom
ci/narrow-integration-targets
Oct 20, 2026
Merged

boyan01 merged 2 commits into
mainfrom
ci/narrow-integration-targets

Conversation

@boyan01

@boyan01 boyan01 commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Summary

 select_targets(targets, paths, base_targets, workspace)
-  shared (all targets): pubspec.yaml, pubspec.lock, .github/integration-tests.json,
-                        .github/workflows/**, tool/ci/**, packages/*/pubspec.yaml
+  all targets:          pubspec.lock, .github/workflows/**, tool/ci/**
+  pubspec.yaml (root):  nothing extra
+  <member>/pubspec.yaml: that package + packages whose members depend on it (transitive,
+                        dependencies/dev_dependencies, workspace from root pubspec.yaml)
+  integration-tests.json: targets added or edited vs. the manifest at the merge base
   packages/<pkg>/**:     targets of <pkg> (unchanged)
Event Before After
pull_request base.sha...head.sha unchanged
push to main all targets before...sha; all targets if before is all zeros or not in history
schedule (weekly, Sun 19:23 UTC) — all targets
workflow_dispatch all targets unchanged

Only PR runs share a concurrency group now (pull_request.number || run_id), so a pending main run is never replaced and its pushed changes skipped. ci.yml validate job now fails if dart pub get changes pubspec.lock.

Evidence

  • Before: word_segmenter: rename string_tokenizer and segment words on every platform #548 (6e2b29c...11d9c44), origin/main script, run in a checkout of the word_segmenter: rename string_tokenizer and segment words on every platform #548 head — 10 targets: breakpad_client windows/linux, desktop_drop web, desktop_webview_window windows/macos/linux, word_segmenter windows/macos/linux/web
    After: same checkout with this script — 4 targets: word_segmenter windows/macos/linux/web
  • Before: push b13faba..964c1c3 (desktop_drop 0.9.2 release, only packages/desktop_drop/pubspec.yaml + CHANGELOG.md) — push events passed no base, so all 6 targets ran (run 39426159620); the origin/main script given that diff also selects all 6 (package pubspec rule)
    After: --base b13faba --head 964c1c3 — 1 target: desktop_drop web
  • Before: push 6e2b29c..b13faba (fix(desktop_drop): stop Flutter's false KGP warning with built-in Kotlin #547 merge) — all 6 targets (push without base)
    After: --base 6e2b29c --head b13faba — 1 target: desktop_drop web
  • --base 0000000000000000000000000000000000000000 prints Cannot diff from ...; selecting all targets. and selects all 6.
  • python3 -B -m unittest discover -s tool/ci -p 'test_*.py' -v: 16 tests OK (manifest diff, missing manifest at base and merge-base comparison, package pubspec + transitive dependents, real workspace mixin_logger dependents, pubspec parser, push fallback for all-zero/missing base, workflow arguments per event; root pubspec.yaml selects nothing, pubspec.lock/workflow select all)
  • dart pub get on clean origin/main (Flutter 3.47.7 stable) leaves pubspec.lock unchanged.

Merge Danger

Door: two-way
Blast Radius: ci
Main pushes no longer run the full suite: a target broken by something outside its package and the rules above (or a flaky target left failing) is only caught by the weekly schedule run, which is the safety net. A resolution change pushed without its updated pubspec.lock would skip unrelated targets; the new lockfile check in ci.yml catches that. If a new Flutter stable changes SDK-pinned versions, that check fails on every PR until pubspec.lock is refreshed. The schedule trigger only takes effect after merge to the default branch.

Narrow integration target selection so shared files no longer fan out to
every target:

- .github/integration-tests.json: select only targets added or edited
  relative to the manifest at the PR merge base; removed targets need no
  job, and a manifest missing at the base selects every registered target.
- packages/<member>/pubspec.yaml: select the member's package plus every
  workspace package with a member that depends on it, directly or
  transitively, through dependencies or dev_dependencies.
- Root pubspec.yaml alone selects nothing; pubspec.lock, .github/workflows/
  and tool/ci/ still select every target.

The CI validate job now fails when dart pub get changes pubspec.lock, so a
resolution change cannot skip targets through an uncommitted lockfile.
Pushes to main now diff github.event.before...github.sha with the same
rules as pull requests instead of running every target. When the pushed
base cannot be diffed (new branch with an all-zero SHA, or a force push
whose previous tip is no longer in the history), the selector falls back
to every target.

A weekly schedule keeps a full regression run, and workflow_dispatch still
runs every target. Only pull request runs share a concurrency group now:
with narrowed push runs, a pending run on main that a later push replaced
would leave its changes untested.
@boyan01
boyan01 merged commit d9ed57a into main Oct 20, 2026
12 checks passed
@boyan01
boyan01 deleted the ci/narrow-integration-targets branch October 20, 2026 13:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant