Problem
ci/ci_common_paths.txt force-runs every per-board workflow. Its own guidance says so deliberately:
Bias: be BROAD here. A safety-net force-run on every common-code edit is the right trade vs. missing a regression that only a board build catches.
That trade has stopped paying. The list includes crates/fbuild-core/**, crates/fbuild-cli/**, crates/fbuild-paths/**, the workspace manifest and lockfile, and more — so a one-line edit almost anywhere schedules all 80 board builds, ~94 checks per PR.
Combined with strict: true branch protection this compounds: every merge makes every other open PR out-of-date, each then needs a fresh ~20-minute full sweep, and the queue serializes. Observed directly across a 14-PR session — wall-clock was dominated by re-running board builds for changes that could not affect them.
Shape of the fix
The machinery already exists (#835): ci/render_workflows.py renders each board's on: paths: from ci/board_families.json + ci/ci_common_paths.txt, and nightly-platforms.yml already sweeps everything daily.
What is missing is a core set. Proposal:
- Core boards — one representative per family, two where a family spans distinct toolchains (ESP32 Xtensa vs RISC-V, STM32 F1/M3 vs H7/M7, SAM M3 vs M4, Teensy M4 vs M7). Shared-code paths run these.
- Every other board — triggers only on its own test dir, its family's crate paths, and its own workflow file. Family-specific work keeps full family coverage.
- Nightly covers all 80 as the safety net, moved to 3am local.
Also: hw-ci.yml is pull_request-triggered but has no concurrency block, so pushing to a PR branch queues another hardware run behind the old one instead of superseding it. It is the only PR-triggered workflow missing that guard — and it matters more there than anywhere else, because those jobs occupy a physical board.
Measured effect
| change |
before |
after |
fbuild-core one-liner |
80 |
17 |
fbuild-cli change |
80 |
17 |
| workspace lockfile bump |
80 |
17 |
| ESP32 orchestrator change |
9 |
9 |
| Teensy linker change |
8 |
8 |
| docs only |
0 |
0 |
Platform-specific coverage is unchanged; only the shared-code blast radius shrinks.
Problem
ci/ci_common_paths.txtforce-runs every per-board workflow. Its own guidance says so deliberately:That trade has stopped paying. The list includes
crates/fbuild-core/**,crates/fbuild-cli/**,crates/fbuild-paths/**, the workspace manifest and lockfile, and more — so a one-line edit almost anywhere schedules all 80 board builds, ~94 checks per PR.Combined with
strict: truebranch protection this compounds: every merge makes every other open PR out-of-date, each then needs a fresh ~20-minute full sweep, and the queue serializes. Observed directly across a 14-PR session — wall-clock was dominated by re-running board builds for changes that could not affect them.Shape of the fix
The machinery already exists (#835):
ci/render_workflows.pyrenders each board'son: paths:fromci/board_families.json+ci/ci_common_paths.txt, andnightly-platforms.ymlalready sweeps everything daily.What is missing is a core set. Proposal:
Also:
hw-ci.ymlispull_request-triggered but has noconcurrencyblock, so pushing to a PR branch queues another hardware run behind the old one instead of superseding it. It is the only PR-triggered workflow missing that guard — and it matters more there than anywhere else, because those jobs occupy a physical board.Measured effect
fbuild-coreone-linerfbuild-clichangePlatform-specific coverage is unchanged; only the shared-code blast radius shrinks.