ci: consolidate primary checks on one larger runner
This commit is contained in:
@@ -12,13 +12,13 @@ The artifact boundary remains load-bearing. `publint`, `verify-node-next-types`,
|
||||
|
||||
## Decision
|
||||
|
||||
The production topology below was superseded by [Evidence-based larger hosted runners](2026-07-22-evidence-based-larger-hosted-runners.md). Its shard selectors and former job layout remain available only through manual `suite=sharded-reference`; this note preserves why that earlier topology was implemented.
|
||||
The production topology below is historical and is superseded by [Evidence-based larger hosted runners](2026-07-22-evidence-based-larger-hosted-runners.md). The larger-runner decision removes its shard selectors and workflow jobs; this note preserves why that earlier topology was implemented.
|
||||
|
||||
[CI](../../../../.github/workflows/ci.yml) treats one minute for non-Windows jobs and three minutes for Windows jobs as observed performance targets, not cancellation deadlines. Hosted-runner variance should leave complete timing evidence and useful failure logs instead of cancelling an otherwise-correct gate. The [serial cross-platform CI reference](2026-07-21-serial-cross-platform-ci-reference.md) independently runs the complete unsharded primary Node aggregate on Linux, macOS, and Windows so the optimized lane inventory is not its own completeness oracle.
|
||||
|
||||
[scripts/run-gates.ts](../../../../scripts/run-gates.ts) remains the common bounded scheduler, but GitHub supplies explicit shard names for the expensive gate families. [scripts/static-shards.ts](../../../../scripts/static-shards.ts) partitions static gates into foundation, documentation-type, API-contract, catalog, prose, documentation-projection, and documentation-build ownership and rejects a missing or duplicate gate assignment; low-cost ownership groups may share one hosted lane to stay below the runner-provisioning concurrency wave. Linux lint uses disjoint A-C, D-M, N-S, and T-Z package-source and package-test lanes, while the longer Windows target uses one complete package-source lane and one complete package-test lane; both topologies include a repository complement that still starts from `.` so a new top-level lint target cannot disappear between shards and owns the single cross-file duplication run. [scripts/coverage-shards.ts](../../../../scripts/coverage-shards.ts) assigns every workspace package to exactly one source-coverage lane; its test expands the live package tree, so a new package makes CI red until it has an owner. Directory filters retain a trailing separator because Vitest positional filters match substrings and would otherwise admit prefix-named sibling packages. Each coverage lane includes only its owned source files, repeats the exhaustive companion topology test, and runs without a preceding build because the complete coverage suite passes from a tree with every generated `lib/` removed.
|
||||
In that topology, [scripts/run-gates.ts](../../../../scripts/run-gates.ts) was the common bounded scheduler and GitHub supplied explicit shard names for the expensive gate families. `scripts/static-shards.ts` partitioned static gates into foundation, documentation-type, API-contract, catalog, prose, documentation-projection, and documentation-build ownership and rejected a missing or duplicate gate assignment. Linux lint used disjoint A-C, D-M, N-S, and T-Z package-source and package-test lanes, while Windows used complete package-source and package-test lanes; both included a repository complement starting from `.` so new top-level targets could not disappear between shards and owned the single cross-file duplication run. `scripts/coverage-shards.ts` assigned every workspace package to exactly one source-coverage lane. Directory filters retained a trailing separator because Vitest positional filters match substrings and would otherwise admit prefix-named siblings. Each coverage lane included only its owned source files, repeated the exhaustive companion topology test, and ran without a preceding build because the complete coverage suite passes from a tree with every generated `lib/` removed.
|
||||
|
||||
Snapshot replay uses two explicit multi-file lanes and eight scenario partitions of the large ACP file. [scripts/snapshot-shards.ts](../../../../scripts/snapshot-shards.ts) owns that inventory, and its test discovers every file admitted by the snapshot config so a new file cannot land outside CI. Each snapshot job installs dependencies while its Linux runner installs bubblewrap, refreshing APT indexes and retrying if the hosted image's initial package install fails, then builds the shipped runtime and runs only its assigned replay surface. CI explicitly retains the suite's bounded concurrency of five subprocesses instead of clamping it to the runner's two logical CPUs, because replay spends most of its time waiting on child protocol I/O. Fixture guards still inspect the complete ACP scenario table in every partition. Static, lint, coverage, and snapshot sharding changes only GitHub scheduling: the ordinary local package scripts still run their complete suites.
|
||||
Snapshot replay used two explicit multi-file lanes and eight scenario partitions of the large ACP file. `scripts/snapshot-shards.ts` owned that inventory, and its test discovered every file admitted by the snapshot config. Each snapshot job installed dependencies while its Linux runner prepared Bubblewrap, built the shipped runtime, and ran only its assigned replay surface. The suite retained bounded concurrency of five subprocesses because replay spent most of its time waiting on child protocol I/O. Fixture guards still inspected the complete ACP scenario table in every partition.
|
||||
|
||||
Cold standalone documentation typechecking rebuilds the complete project-reference graph, so a dedicated documentation-type lane builds once and checks Markdown blocks against those declarations. The Linux documentation lane uses VitePress's MPA build to retain page rendering and dead-link validation within the observed non-Windows target; separate blocking Windows build and production-site lanes preserve the emitted-package and shipped-site checks without putting both critical paths in one job.
|
||||
|
||||
@@ -41,9 +41,7 @@ The workflow caches the pnpm store, keys each immutable ESLint cache to its owni
|
||||
|
||||
## Consequences
|
||||
|
||||
The Actions UI contains more matrix checks and total runner time can exceed a serial workflow, but PR wall time is the slowest bounded lane instead of the sum of unrelated work. Repeated setup and builds are the deliberate price of sub-minute non-Windows feedback and sub-three-minute Windows feedback.
|
||||
|
||||
Shard inventories are repository contracts. Static selection validates the complete live gate list at runtime, coverage tests validate exhaustive package ownership, and Vitest owns deterministic file sharding for snapshots and built-bin smokes. Adding a gate or package therefore requires an explicit scheduling decision instead of silently lengthening an existing lane.
|
||||
The shard inventories and matrix jobs described above are not part of the current repository contract. The superseding larger-runner decision keeps the complete primary inventory in one process and uses the serial suite as its independent completeness oracle.
|
||||
|
||||
The optimized publication validators rely on the manifest `files` contract enforced by `verify-package-invariants`. If publication rules grow beyond that contract, the structural gate and both staged views must change together.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user