Skip to content

Commit 767ff8a

Browse files
committed
perf(ci): skip redundant test collection in calculate-shards
When selective testing isn't active (push to master/branch), the calculate-shards job now outputs static defaults (22 shards) without checkout, setup-sentry, or pytest --collect-only. Saves ~3 min on the critical path. Full collection only runs for PRs with selective testing.
1 parent b5337de commit 767ff8a

3 files changed

Lines changed: 36 additions & 9 deletions

File tree

.github/workflows/backend-xdist.yml

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -201,15 +201,24 @@ jobs:
201201
needs: [files-changed, prepare-selective-tests]
202202
name: calculate test shards
203203
runs-on: ubuntu-24.04
204-
timeout-minutes: 5
204+
timeout-minutes: ${{ needs.prepare-selective-tests.outputs.has-selected-tests == 'true' && 5 || 1 }}
205205
outputs:
206-
shard-count: ${{ steps.calculate-shards.outputs.shard-count }}
207-
shard-indices: ${{ steps.calculate-shards.outputs.shard-indices }}
206+
shard-count: ${{ steps.static-shards.outputs.shard-count || steps.calculate-shards.outputs.shard-count }}
207+
shard-indices: ${{ steps.static-shards.outputs.shard-indices || steps.calculate-shards.outputs.shard-indices }}
208208

209209
steps:
210+
- name: Use default shards (no selective testing)
211+
id: static-shards
212+
if: needs.prepare-selective-tests.outputs.has-selected-tests != 'true'
213+
run: |
214+
echo "shard-count=22" >> "$GITHUB_OUTPUT"
215+
echo "shard-indices=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21]" >> "$GITHUB_OUTPUT"
216+
210217
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
218+
if: needs.prepare-selective-tests.outputs.has-selected-tests == 'true'
211219

212220
- name: Setup sentry env
221+
if: needs.prepare-selective-tests.outputs.has-selected-tests == 'true'
213222
uses: ./.github/actions/setup-sentry
214223
id: setup
215224
with:
@@ -225,8 +234,9 @@ jobs:
225234

226235
- name: Calculate test shards
227236
id: calculate-shards
237+
if: needs.prepare-selective-tests.outputs.has-selected-tests == 'true'
228238
env:
229-
SELECTED_TESTS_FILE: ${{ needs.prepare-selective-tests.outputs.has-selected-tests == 'true' && '.artifacts/selected-tests.txt' || '' }}
239+
SELECTED_TESTS_FILE: '.artifacts/selected-tests.txt'
230240
SELECTED_TEST_COUNT: ${{ needs.prepare-selective-tests.outputs.test-count || '' }}
231241
run: |
232242
python3 .github/workflows/scripts/calculate-backend-test-shards.py

.github/workflows/backend.yml

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -195,23 +195,31 @@ jobs:
195195
retention-days: 1
196196

197197
calculate-shards:
198-
# Use always() so this job runs even when prepare-selective-tests is skipped (master)
199198
if: >-
200199
always() &&
201200
!cancelled() &&
202201
needs.files-changed.outputs.backend == 'true'
203202
needs: [files-changed, prepare-selective-tests]
204203
name: calculate test shards
205204
runs-on: ubuntu-24.04
206-
timeout-minutes: 5
205+
timeout-minutes: ${{ needs.prepare-selective-tests.outputs.has-selected-tests == 'true' && 5 || 1 }}
207206
outputs:
208-
shard-count: ${{ steps.calculate-shards.outputs.shard-count }}
209-
shard-indices: ${{ steps.calculate-shards.outputs.shard-indices }}
207+
shard-count: ${{ steps.static-shards.outputs.shard-count || steps.calculate-shards.outputs.shard-count }}
208+
shard-indices: ${{ steps.static-shards.outputs.shard-indices || steps.calculate-shards.outputs.shard-indices }}
210209

211210
steps:
211+
- name: Use default shards (no selective testing)
212+
id: static-shards
213+
if: needs.prepare-selective-tests.outputs.has-selected-tests != 'true'
214+
run: |
215+
echo "shard-count=22" >> "$GITHUB_OUTPUT"
216+
echo "shard-indices=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21]" >> "$GITHUB_OUTPUT"
217+
212218
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
219+
if: needs.prepare-selective-tests.outputs.has-selected-tests == 'true'
213220

214221
- name: Setup sentry env
222+
if: needs.prepare-selective-tests.outputs.has-selected-tests == 'true'
215223
uses: ./.github/actions/setup-sentry
216224
id: setup
217225
with:
@@ -227,8 +235,9 @@ jobs:
227235

228236
- name: Calculate test shards
229237
id: calculate-shards
238+
if: needs.prepare-selective-tests.outputs.has-selected-tests == 'true'
230239
env:
231-
SELECTED_TESTS_FILE: ${{ needs.prepare-selective-tests.outputs.has-selected-tests == 'true' && '.artifacts/selected-tests.txt' || '' }}
240+
SELECTED_TESTS_FILE: '.artifacts/selected-tests.txt'
232241
SELECTED_TEST_COUNT: ${{ needs.prepare-selective-tests.outputs.test-count || '' }}
233242
run: |
234243
python3 .github/workflows/scripts/calculate-backend-test-shards.py

docs/tiered-xdist-changes.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,16 @@ Sets `pytest_rerunfailures.HAS_PYTEST_HANDLECRASHITEM = False`.
8383

8484
Under xdist, the server spawns a `run_connection` thread per worker. Each thread blocks on `conn.recv(1)` waiting for the next message. If no message arrives within 5 seconds (e.g., during heavy Django/plugin initialization or between test batches), `recv` raises `TimeoutError`, the thread dies, and crash recovery for that worker is lost. With 3 workers, all 3 threads die during startup, producing the `Exception in thread Thread-N (run_connection)` errors.
8585

86+
The 5s timeout is hit because the `ClientStatusDB` connects during `pytest_configure`, but doesn't send any data until a test actually runs. Between connection and first message, the worker does Django initialization (~10s) and test collection (~100s). The server's `run_connection` thread is waiting on `recv(1)` that entire time and dies after 5s. The client still has its socket open but the server side is gone.
87+
8688
Normal `--reruns` is unaffected — each worker retries failed tests locally via `StatusDB` (in-memory, no sockets). Only segfault crash recovery (reassigning a dead worker's test to another worker) is lost, which is a rare edge case.
8789

90+
## 3. Skip Redundant Test Collection in calculate-shards
91+
92+
**Modified:** `.github/workflows/backend.yml`, `.github/workflows/backend-xdist.yml`
93+
94+
The `calculate-shards` job now has a fast path: when selective testing isn't active (push to master/branch), it outputs static defaults (22 shards) without checkout, setup-sentry, or `pytest --collect-only`. Saves ~3 min on the critical path. When selective testing IS active (PR), the full collection pipeline still runs to compute the right shard count.
95+
8896
### 2g. Snowflake test fix
8997

9098
**Modified:** `tests/sentry/utils/test_snowflake.py`

0 commit comments

Comments
 (0)