Problem
The current test sharding strategy across CI workflows (build_pull_request.yml, build_container.yml) and the local test runner (run_tests_parallel.sh) is based on hardcoded, statically balanced package lists with a fallback catch-all.
While sharding is necessary (to parallelize the heavy 40+ minute single-job integration test load across 9 VMs), the current implementation has several severe drawbacks:
- Static drift and Coverage Black Holes: Statically defined packages easily drift. We recently discovered and fixed a coverage black hole where newly added suites fell through the cracks of the hand-crafted inclusions and the catch-all.
- Three Sources of Truth: The shard lists are duplicated across three different files (
build_pull_request.yml, build_container.yml, and run_tests_parallel.sh).
- Fragile Catch-all: The catch-all mechanism has package-level vs class-level semantic traps.
- Manual Rebalancing: As tests grow, shards become unbalanced (e.g., historical splits between
v6 and v2_x), requiring manual intervention.
Proposed Solution
Instead of maintaining three hardcoded lists, we should introduce a single dynamic script (.github/scripts/compute_shards.py) to handle the shard distribution automatically using timing-based bin-packing.
The script will:
- Enumerate all suite classes dynamically to guarantee mathematically complete coverage (eliminating the need for a catch-all).
- Read previous timing data (which is already generated per-class by the report jobs) from a cache or artifact.
- Bin-pack the suites into
N evenly distributed shards using a greedy algorithm.
- Output a matrix JSON string.
Both GitHub Action workflows can use jobs.<id>.outputs + fromJSON() to dynamically generate their matrix, and the local run_tests_parallel.sh can call the same script to distribute local shards.
This unifies the shard generation into a single source of truth, guarantees 100% test coverage by construction, and ensures optimal CI time without manual rebalancing.
Problem
The current test sharding strategy across CI workflows (
build_pull_request.yml,build_container.yml) and the local test runner (run_tests_parallel.sh) is based on hardcoded, statically balanced package lists with a fallbackcatch-all.While sharding is necessary (to parallelize the heavy 40+ minute single-job integration test load across 9 VMs), the current implementation has several severe drawbacks:
build_pull_request.yml,build_container.yml, andrun_tests_parallel.sh).v6andv2_x), requiring manual intervention.Proposed Solution
Instead of maintaining three hardcoded lists, we should introduce a single dynamic script (
.github/scripts/compute_shards.py) to handle the shard distribution automatically using timing-based bin-packing.The script will:
Nevenly distributed shards using a greedy algorithm.Both GitHub Action workflows can use
jobs.<id>.outputs+fromJSON()to dynamically generate their matrix, and the localrun_tests_parallel.shcan call the same script to distribute local shards.This unifies the shard generation into a single source of truth, guarantees 100% test coverage by construction, and ensures optimal CI time without manual rebalancing.