From 6cb2bc90517abb014ea97f007c483c72c6d5e604 Mon Sep 17 00:00:00 2001 From: Shane da Silva Date: Thu, 5 Nov 2026 10:24:35 -0800 Subject: [PATCH 1/3] Allocate CI runners to five Windows shards and one Linux shard --- .github/workflows/tests.yml | 25 ++++++++++++++----------- spec/spec_shard_spec.rb | 2 +- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 964c2103..93d4a674 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,19 +1,19 @@ name: Tests on: push: - branches: [main] + branches: [main, perf/asymmetric-shards] pull_request: branches: [main] jobs: rspec: - name: rspec (${{ matrix.ruby-version }}, ${{ matrix.os }}, shard ${{ matrix.shard }}) - timeout-minutes: ${{ matrix.os == 'windows' && 30 || 15 }} - runs-on: ${{ format('{0}-latest', matrix.os) }} + name: rspec (${{ matrix.ruby-version }}, ${{ matrix.target.os }}, shard ${{ matrix.target.shard }}) + timeout-minutes: ${{ matrix.target.os == 'windows' && 30 || 15 }} + runs-on: ${{ format('{0}-latest', matrix.target.os) }} env: BUNDLE_WITHOUT: lint - SPEC_WORKERS: ${{ matrix.os == 'windows' && 4 || 8 }} - SPEC_SHARD: ${{ matrix.shard }} + SPEC_WORKERS: ${{ matrix.target.os == 'windows' && 4 || 8 }} + SPEC_SHARD: ${{ matrix.target.shard }} strategy: fail-fast: false @@ -22,10 +22,13 @@ jobs: - "3.3" - "3.4" - "4.0" - os: - - ubuntu - - windows - shard: ["1/3", "2/3", "3/3"] + target: + - { os: ubuntu, shard: "1/1" } + - { os: windows, shard: "1/5" } + - { os: windows, shard: "2/5" } + - { os: windows, shard: "3/5" } + - { os: windows, shard: "4/5" } + - { os: windows, shard: "5/5" } steps: - uses: actions/checkout@v4 @@ -56,7 +59,7 @@ jobs: uses: coverallsapp/github-action@v2 with: github-token: ${{ secrets.github_token }} - flag-name: ruby${{ matrix.ruby-version }}-${{ matrix.os }}-shard${{ strategy.job-index }} + flag-name: ruby${{ matrix.ruby-version }}-${{ matrix.target.os }}-shard${{ strategy.job-index }} parallel: true overcommit: diff --git a/spec/spec_shard_spec.rb b/spec/spec_shard_spec.rb index 258fc606..f5e0d853 100644 --- a/spec/spec_shard_spec.rb +++ b/spec/spec_shard_spec.rb @@ -9,7 +9,7 @@ described_class.new('1/1').select(examples).should == examples end - [2, 3].each do |total| + [2, 3, 5].each do |total| context "with #{total} shards" do let(:shards) do (1..total).map { |index| described_class.new("#{index}/#{total}").select(examples) } From d674472dc61ebb03c940f6befd1bb6d50a9500c0 Mon Sep 17 00:00:00 2001 From: Shane da Silva Date: Thu, 5 Nov 2026 10:28:15 -0800 Subject: [PATCH 2/3] Document asymmetric sharding and remove the benchmark trigger --- .github/workflows/tests.yml | 2 +- CONTRIBUTING.md | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 93d4a674..5f6e65b5 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,7 +1,7 @@ name: Tests on: push: - branches: [main, perf/asymmetric-shards] + branches: [main] pull_request: branches: [main] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 83dfc146..80900ef9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -46,7 +46,7 @@ The best way to see a feature added, however, is to submit a pull request. # Optionally choose the number of worker processes (default: up to 8 CPUs): SPEC_WORKERS=4 bundle exec ruby script/parallel_rspec.rb # Run one runner's share of the suite (default: 1/1, the whole suite): - SPEC_SHARD=1/3 bundle exec ruby script/parallel_rspec.rb + SPEC_SHARD=1/5 bundle exec ruby script/parallel_rspec.rb ``` Workers run in separate processes because specs change the working directory @@ -56,6 +56,8 @@ The best way to see a feature added, however, is to submit a pull request. You can also pass spec paths to run a subset. The `lint` dependency group is only needed for lint checks; test-only CI jobs install with `BUNDLE_WITHOUT=lint`. + GitHub Actions runs one Linux shard and five Windows shards per Ruby version. + The final `CI` check depends on all test shards and lint, and finalizes coverage reporting. Repository rulesets can require this single check instead of individual matrix jobs. From c00e1a6beaa29597ef8e5c591635f8cfa711fa52 Mon Sep 17 00:00:00 2001 From: Shane da Silva Date: Thu, 5 Nov 2026 10:35:24 -0800 Subject: [PATCH 3/3] Identify coverage shards by index and total instead of matrix position --- .github/workflows/tests.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5f6e65b5..71e94942 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -7,13 +7,13 @@ on: jobs: rspec: - name: rspec (${{ matrix.ruby-version }}, ${{ matrix.target.os }}, shard ${{ matrix.target.shard }}) + name: rspec (${{ matrix.ruby-version }}, ${{ matrix.target.os }}, shard ${{ matrix.target.shard }}/${{ matrix.target.shards }}) timeout-minutes: ${{ matrix.target.os == 'windows' && 30 || 15 }} runs-on: ${{ format('{0}-latest', matrix.target.os) }} env: BUNDLE_WITHOUT: lint SPEC_WORKERS: ${{ matrix.target.os == 'windows' && 4 || 8 }} - SPEC_SHARD: ${{ matrix.target.shard }} + SPEC_SHARD: ${{ matrix.target.shard }}/${{ matrix.target.shards }} strategy: fail-fast: false @@ -23,12 +23,12 @@ jobs: - "3.4" - "4.0" target: - - { os: ubuntu, shard: "1/1" } - - { os: windows, shard: "1/5" } - - { os: windows, shard: "2/5" } - - { os: windows, shard: "3/5" } - - { os: windows, shard: "4/5" } - - { os: windows, shard: "5/5" } + - { os: ubuntu, shard: 1, shards: 1 } + - { os: windows, shard: 1, shards: 5 } + - { os: windows, shard: 2, shards: 5 } + - { os: windows, shard: 3, shards: 5 } + - { os: windows, shard: 4, shards: 5 } + - { os: windows, shard: 5, shards: 5 } steps: - uses: actions/checkout@v4 @@ -59,7 +59,7 @@ jobs: uses: coverallsapp/github-action@v2 with: github-token: ${{ secrets.github_token }} - flag-name: ruby${{ matrix.ruby-version }}-${{ matrix.target.os }}-shard${{ strategy.job-index }} + flag-name: ruby${{ matrix.ruby-version }}-${{ matrix.target.os }}-shard${{ matrix.target.shard }}of${{ matrix.target.shards }} parallel: true overcommit: