1414jobs :
1515 unitTests :
1616 name : " 🧪 Unit Tests: Internal"
17- # Single big machine instead of a 12-job matrix: the internal suites are serial
18- # (fileParallelism: false) and container-wait-bound, so 12 in-machine shard processes
19- # fit comfortably in 32 vCPUs while paying the setup cost (install, prisma generate,
20- # image pulls) once instead of 12 times.
17+ # Two Docker daemons and disks, with twelve serial test processes per runner.
18+ # Global shard indices ensure every file runs exactly once across both machines.
19+ strategy :
20+ fail-fast : false
21+ matrix :
22+ machine : [1, 2]
2123 runs-on : warp-ubuntu-latest-x64-32x
2224 env :
2325 DOCKERHUB_USERNAME : ${{ secrets.DOCKERHUB_USERNAME }}
24- SHARD_TOTAL : 12
26+ MACHINE_INDEX : ${{ matrix.machine }}
27+ SHARDS_PER_MACHINE : 12
28+ SHARD_TOTAL : 24
2529 steps :
2630 - name : 🔧 Disable IPv6
2731 run : |
@@ -104,24 +108,32 @@ jobs:
104108 run : pnpm run generate
105109
106110 - name : 🏗️ Build test dependencies
107- # Build once up-front so the parallel shard runs below (turbo --only) never race
108- # to build or cache-restore the same outputs concurrently.
111+ # Build once up-front so shard processes never race to build or
112+ # cache-restore the same outputs concurrently.
109113 run : pnpm exec turbo run build --filter "@internal/*..."
110114
111- - name : 🧪 Run Internal Unit Tests (${{ env.SHARD_TOTAL }} in-machine shards )
115+ - name : 🧪 Run Internal Unit Tests (machine ${{ matrix.machine }}/2 )
112116 run : |
113- # Same shard partitioning as the old 12-job matrix (DurationShardingSequencer
114- # keys off --shard=i/N), but as parallel local processes. --only skips the
115- # ^build dependency handled by the step above.
117+ # Each process discovers all internal projects, then takes its globally
118+ # balanced share of files. Keep one test file active per process.
119+ first=$(( (MACHINE_INDEX - 1) * SHARDS_PER_MACHINE + 1 ))
120+ last=$(( MACHINE_INDEX * SHARDS_PER_MACHINE ))
116121 status=0
117122 declare -a pids
118- for i in $(seq 1 "$SHARD_TOTAL"); do
119- pnpm exec turbo run test --only --concurrency=1 --filter "@internal/*" -- \
120- --run --reporter=default --reporter=blob --shard="$i/$SHARD_TOTAL" --passWithNoTests \
121- > "/tmp/internal-shard-$i.log" 2>&1 &
123+ for i in $(seq "$first" "$last"); do
124+ (
125+ started=$SECONDS
126+ result=0
127+ pnpm exec vitest run --config vitest.internal.config.ts \
128+ --sequence.concurrent=false --reporter=default --reporter=blob \
129+ --shard="$i/$SHARD_TOTAL" --passWithNoTests \
130+ > "/tmp/internal-shard-$i.log" 2>&1 || result=$?
131+ echo "::notice::internal shard $i/$SHARD_TOTAL finished in $((SECONDS - started))s (exit $result)"
132+ exit "$result"
133+ ) &
122134 pids[i]=$!
123135 done
124- for i in $(seq 1 "$SHARD_TOTAL "); do
136+ for i in $(seq "$first" "$last "); do
125137 if ! wait "${pids[i]}"; then
126138 status=1
127139 echo "::error::internal unit test shard $i/$SHARD_TOTAL failed"
@@ -132,13 +144,67 @@ jobs:
132144 done
133145 exit "$status"
134146
135- - name : Gather all reports
147+ - name : Upload blob reports
136148 if : ${{ !cancelled() }}
149+ uses : actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
150+ with :
151+ name : internal-blob-report-${{ matrix.machine }}
152+ path : .vitest-reports/*
153+ include-hidden-files : true
154+ if-no-files-found : error
155+ retention-days : 1
156+
157+ merge-reports :
158+ name : " 📊 Merge Internal Reports"
159+ if : ${{ !cancelled() }}
160+ needs : [unitTests]
161+ runs-on : warp-ubuntu-latest-x64-2x
162+ steps :
163+ - name : ⬇️ Checkout repo
164+ uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
165+ with :
166+ fetch-depth : 1
167+ persist-credentials : false
168+
169+ - name : ⎔ Setup pnpm
170+ uses : pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
171+ with :
172+ version : 10.33.2
173+
174+ - name : ⎔ Setup node
175+ uses : actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
176+ with :
177+ node-version : 24.18.0
178+
179+ - name : Download blob reports
180+ uses : actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
181+ with :
182+ path : .vitest-reports
183+ pattern : internal-blob-report-*
184+ merge-multiple : true
185+
186+ - name : Check all shard reports are present
137187 run : |
138- mkdir -p .vitest-reports
139- find . -type f -path '*/ .vitest-reports/blob-* .json' \
140- -exec bash -c 'src="$1"; basename=$(basename "$src"); pkg=$(dirname "$src" | sed "s|^\./||;s|/\.vitest-reports$||;s|/|_|g"); cp "$src" ".vitest-reports/${pkg}-${basename}"' _ {} \;
188+ for i in $(seq 1 24); do
189+ test -s " .vitest-reports/blob-$i-24 .json"
190+ done
141191
142192 - name : 📊 Merge reports
193+ run : >-
194+ pnpm dlx vitest@4.1.7 run --config vitest.internal-reports.config.mjs --merge-reports
195+ --reporter=default --reporter=json --outputFile.json=internal-test-results.json
196+
197+ - name : Validate merged test timings
198+ run : |
199+ cp test-timings.json "$RUNNER_TEMP/checked-test-timings.json"
200+ node internal-packages/testcontainers/scripts/update-test-timings.mjs \
201+ internal-test-results.json "$RUNNER_TEMP/checked-test-timings.json"
202+
203+ - name : Upload internal test timings
143204 if : ${{ !cancelled() }}
144- run : pnpm dlx vitest@4.1.7 run --merge-reports --pass-with-no-tests
205+ uses : actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
206+ with :
207+ name : internal-test-results
208+ path : internal-test-results.json
209+ if-no-files-found : error
210+ retention-days : 14
0 commit comments