9494 stepName : ' build-next'
9595 secrets : inherit
9696
97+ fetch-test-timings :
98+ name : fetch test timings
99+ runs-on : ubuntu-latest
100+ needs : ['changes']
101+ if : ${{ needs.changes.outputs.docs-only == 'false' }}
102+ steps :
103+ - name : Setup Node.js
104+ uses : actions/setup-node@v4
105+ with :
106+ node-version : ${{ env.NODE_LTS_VERSION }}
107+ check-latest : true
108+
109+ - name : Setup pnpm
110+ run : |
111+ 112+ corepack enable
113+
114+ - name : Checkout
115+ uses : actions/checkout@v4
116+ with :
117+ fetch-depth : 25
118+
119+ - name : Install dependencies
120+ run : pnpm install
121+
122+ - name : Fetch test timings
123+ run : node run-tests.js --timings --write-timings -g 1/1
124+ continue-on-error : true
125+ env :
126+ KV_REST_API_URL : ${{ secrets.KV_REST_API_URL }}
127+ KV_REST_API_TOKEN : ${{ secrets.KV_REST_API_TOKEN }}
128+
129+ - name : Ensure test timings file exists
130+ run : |
131+ if [ ! -f test-timings.json ]; then
132+ echo "No timings fetched, creating empty timings file"
133+ echo '{}' > test-timings.json
134+ fi
135+
136+ - name : Upload test timings
137+ uses : actions/upload-artifact@v4
138+ with :
139+ name : test-timings
140+ path : test-timings.json
141+ retention-days : 1
142+ if-no-files-found : error
143+
97144 lint :
98145 name : lint
99146 needs : ['build-next']
@@ -236,7 +283,14 @@ jobs:
236283
237284 test-turbopack-dev :
238285 name : test turbopack dev
239- needs : ['optimize-ci', 'changes', 'build-next', 'build-native']
286+ needs :
287+ [
288+ ' optimize-ci' ,
289+ ' changes' ,
290+ ' build-next' ,
291+ ' build-native' ,
292+ ' fetch-test-timings' ,
293+ ]
240294 if : ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' }}
241295
242296 strategy :
@@ -261,13 +315,22 @@ jobs:
261315 node run-tests.js \
262316 --test-pattern '^(test\/(development|e2e))/.*\.test\.(js|jsx|ts|tsx)$' \
263317 --timings \
318+ --require-timings \
264319 -g ${{ matrix.group }}
320+ testTimingsArtifact : ' test-timings'
265321 stepName : ' test-turbopack-dev-react-${{ matrix.react }}-${{ matrix.group }}'
266322 secrets : inherit
267323
268324 test-turbopack-integration :
269325 name : test turbopack integration
270- needs : ['optimize-ci', 'changes', 'build-native', 'build-next']
326+ needs :
327+ [
328+ ' optimize-ci' ,
329+ ' changes' ,
330+ ' build-native' ,
331+ ' build-next' ,
332+ ' fetch-test-timings' ,
333+ ]
271334 if : ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' }}
272335
273336 strategy :
@@ -304,14 +367,23 @@ jobs:
304367
305368 node run-tests.js \
306369 --timings \
370+ --require-timings \
307371 -g ${{ matrix.group }} \
308372 --type integration
373+ testTimingsArtifact : ' test-timings'
309374 stepName : ' test-turbopack-integration-react-${{ matrix.react }}-${{ matrix.group }}'
310375 secrets : inherit
311376
312377 test-turbopack-production :
313378 name : test turbopack production
314- needs : ['optimize-ci', 'changes', 'build-next', 'build-native']
379+ needs :
380+ [
381+ ' optimize-ci' ,
382+ ' changes' ,
383+ ' build-next' ,
384+ ' build-native' ,
385+ ' fetch-test-timings' ,
386+ ]
315387 if : ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' }}
316388
317389 strategy :
@@ -334,13 +406,21 @@ jobs:
334406 export __NEXT_EXPERIMENTAL_STRICT_ROUTE_TYPES=true
335407 export RUST_BACKTRACE=1
336408
337- node run-tests.js --timings -g ${{ matrix.group }} --type production
409+ node run-tests.js --timings --require-timings -g ${{ matrix.group }} --type production
410+ testTimingsArtifact : ' test-timings'
338411 stepName : ' test-turbopack-production-react-${{ matrix.react }}-${{ matrix.group }}'
339412 secrets : inherit
340413
341414 test-rspack-dev :
342415 name : test rspack dev
343- needs : ['optimize-ci', 'changes', 'build-next', 'build-native']
416+ needs :
417+ [
418+ ' optimize-ci' ,
419+ ' changes' ,
420+ ' build-next' ,
421+ ' build-native' ,
422+ ' fetch-test-timings' ,
423+ ]
344424 if : ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' && needs.changes.outputs.rspack == 'true' }}
345425 strategy :
346426 fail-fast : false
@@ -370,13 +450,22 @@ jobs:
370450 node run-tests.js \
371451 --test-pattern '^(test\/(development|e2e))/.*\.test\.(js|jsx|ts|tsx)$' \
372452 --timings \
453+ --require-timings \
373454 -g ${{ matrix.group }}
455+ testTimingsArtifact : ' test-timings'
374456 stepName : ' test-rspack-dev-react-${{ matrix.react }}-${{ matrix.group }}'
375457 secrets : inherit
376458
377459 test-rspack-integration :
378460 name : test rspack development integration
379- needs : ['optimize-ci', 'changes', 'build-next', 'build-native']
461+ needs :
462+ [
463+ ' optimize-ci' ,
464+ ' changes' ,
465+ ' build-next' ,
466+ ' build-native' ,
467+ ' fetch-test-timings' ,
468+ ]
380469 if : ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' && needs.changes.outputs.rspack == 'true' }}
381470 strategy :
382471 fail-fast : false
@@ -406,14 +495,23 @@ jobs:
406495
407496 node run-tests.js \
408497 --timings \
498+ --require-timings \
409499 -g ${{ matrix.group }} \
410500 --type integration
501+ testTimingsArtifact : ' test-timings'
411502 stepName : ' test-rspack-integration-react-${{ matrix.react }}-${{ matrix.group }}'
412503 secrets : inherit
413504
414505 test-rspack-production :
415506 name : test rspack production
416- needs : ['optimize-ci', 'changes', 'build-next', 'build-native']
507+ needs :
508+ [
509+ ' optimize-ci' ,
510+ ' changes' ,
511+ ' build-next' ,
512+ ' build-native' ,
513+ ' fetch-test-timings' ,
514+ ]
417515 if : ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' && needs.changes.outputs.rspack == 'true' }}
418516 strategy :
419517 fail-fast : false
@@ -441,13 +539,21 @@ jobs:
441539 # tests, so it's applicable to rspack
442540 export TURBOPACK_BUILD=1
443541
444- node run-tests.js --timings -g ${{ matrix.group }} --type production
542+ node run-tests.js --timings --require-timings -g ${{ matrix.group }} --type production
543+ testTimingsArtifact : ' test-timings'
445544 stepName : ' test-rspack-production-react-${{ matrix.react }}-${{ matrix.group }}'
446545 secrets : inherit
447546
448547 test-rspack-production-integration :
449548 name : test rspack production integration
450- needs : ['optimize-ci', 'changes', 'build-next', 'build-native']
549+ needs :
550+ [
551+ ' optimize-ci' ,
552+ ' changes' ,
553+ ' build-next' ,
554+ ' build-native' ,
555+ ' fetch-test-timings' ,
556+ ]
451557 if : ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' && needs.changes.outputs.rspack == 'true' }}
452558 strategy :
453559 fail-fast : false
@@ -477,8 +583,10 @@ jobs:
477583
478584 node run-tests.js \
479585 --timings \
586+ --require-timings \
480587 -g ${{ matrix.group }} \
481588 --type integration
589+ testTimingsArtifact : ' test-timings'
482590 stepName : ' test-rspack-production-integration-react-${{ matrix.react }}-${{ matrix.group }}'
483591 secrets : inherit
484592
@@ -719,7 +827,14 @@ jobs:
719827
720828 test-dev : # TODO: rename to include webpack
721829 name : test dev
722- needs : ['optimize-ci', 'changes', 'build-native', 'build-next']
830+ needs :
831+ [
832+ ' optimize-ci' ,
833+ ' changes' ,
834+ ' build-native' ,
835+ ' build-next' ,
836+ ' fetch-test-timings' ,
837+ ]
723838 if : ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' }}
724839
725840 strategy :
@@ -741,8 +856,10 @@ jobs:
741856
742857 node run-tests.js \
743858 --timings \
859+ --require-timings \
744860 -g ${{ matrix.group }} \
745861 --type development
862+ testTimingsArtifact : ' test-timings'
746863 stepName : ' test-dev-react-${{ matrix.react }}-${{ matrix.group }}'
747864 secrets : inherit
748865
@@ -838,7 +955,14 @@ jobs:
838955
839956 test-prod :
840957 name : test prod
841- needs : ['optimize-ci', 'changes', 'build-native', 'build-next']
958+ needs :
959+ [
960+ ' optimize-ci' ,
961+ ' changes' ,
962+ ' build-native' ,
963+ ' build-next' ,
964+ ' fetch-test-timings' ,
965+ ]
842966 if : ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' }}
843967
844968 strategy :
@@ -858,13 +982,21 @@ jobs:
858982 export NEXT_TEST_REACT_VERSION="${{ matrix.react }}"
859983 export __NEXT_EXPERIMENTAL_STRICT_ROUTE_TYPES=true
860984
861- node run-tests.js --timings -g ${{ matrix.group }} --type production
985+ node run-tests.js --timings --require-timings -g ${{ matrix.group }} --type production
986+ testTimingsArtifact : ' test-timings'
862987 stepName : ' test-prod-react-${{ matrix.react }}-${{ matrix.group }}'
863988 secrets : inherit
864989
865990 test-integration :
866991 name : test integration
867- needs : ['optimize-ci', 'changes', 'build-native', 'build-next']
992+ needs :
993+ [
994+ ' optimize-ci' ,
995+ ' changes' ,
996+ ' build-native' ,
997+ ' build-next' ,
998+ ' fetch-test-timings' ,
999+ ]
8681000 if : ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' }}
8691001
8701002 strategy :
@@ -900,8 +1032,10 @@ jobs:
9001032
9011033 node run-tests.js \
9021034 --timings \
1035+ --require-timings \
9031036 -g ${{ matrix.group }} \
9041037 --type integration
1038+ testTimingsArtifact : ' test-timings'
9051039 stepName : ' test-integration-${{ matrix.group }}-react-${{ matrix.react }}'
9061040 secrets : inherit
9071041
@@ -958,7 +1092,14 @@ jobs:
9581092
9591093 test-cache-components-dev :
9601094 name : test cache components dev
961- needs : ['optimize-ci', 'changes', 'build-native', 'build-next']
1095+ needs :
1096+ [
1097+ ' optimize-ci' ,
1098+ ' changes' ,
1099+ ' build-native' ,
1100+ ' build-next' ,
1101+ ' fetch-test-timings' ,
1102+ ]
9621103 if : ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' }}
9631104
9641105 strategy :
@@ -976,14 +1117,23 @@ jobs:
9761117
9771118 node run-tests.js \
9781119 --timings \
1120+ --require-timings \
9791121 -g ${{ matrix.group }} \
9801122 --type development
1123+ testTimingsArtifact : ' test-timings'
9811124 stepName : ' test-cache-components-dev-${{ matrix.group }}'
9821125 secrets : inherit
9831126
9841127 test-cache-components-prod :
9851128 name : test cache components prod
986- needs : ['optimize-ci', 'changes', 'build-native', 'build-next']
1129+ needs :
1130+ [
1131+ ' optimize-ci' ,
1132+ ' changes' ,
1133+ ' build-native' ,
1134+ ' build-next' ,
1135+ ' fetch-test-timings' ,
1136+ ]
9871137 if : ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' }}
9881138
9891139 strategy :
@@ -1001,8 +1151,10 @@ jobs:
10011151
10021152 node run-tests.js \
10031153 --timings \
1154+ --require-timings \
10041155 -g ${{ matrix.group }} \
10051156 --type production
1157+ testTimingsArtifact : ' test-timings'
10061158 stepName : ' test-cache-components-prod-${{ matrix.group }}'
10071159 secrets : inherit
10081160
0 commit comments