Skip to content

Refactor CI test sharding: Dynamic bin-packing to replace hardcoded suites #40

Description

@hongwei1

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:

  1. 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.
  2. 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).
  3. Fragile Catch-all: The catch-all mechanism has package-level vs class-level semantic traps.
  4. 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:

  1. Enumerate all suite classes dynamically to guarantee mathematically complete coverage (eliminating the need for a catch-all).
  2. Read previous timing data (which is already generated per-class by the report jobs) from a cache or artifact.
  3. Bin-pack the suites into N evenly distributed shards using a greedy algorithm.
  4. 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions