[ci] Centralize cache (#32672)
To avoid race conditions where multiple jobs try to write to the same cache, we now centralize saving the cache and then reusing it in every subsequent job. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32672). * #32675 * #32674 * __->__ #32672
lauren committed
Mar 19, 2025 at 15:25 UTC
a4842c92ea241593557a3b0dadfbc5460320d375
1 file changed
+116
-23
.github/workflows/runtime_build_and_test.yml
+116
-23
@@ -17,6 +17,75 @@ env:
17
SEGMENT_DOWNLOAD_TIMEOUT_MINS: 1
18
19
jobs:
20
+ # ----- YARN CACHE -----
21
+ # Centralize the yarn/node_modules cache so it is saved once and each subsequent job only needs to
22
+ # restore the cache. Prevents race conditions where multiple workflows try to write to the cache.
23
+ runtime_yarn_cache:
24
+ name: Cache Runtime
25
+ runs-on: ubuntu-latest
26
+ steps:
27
+ - uses: actions/checkout@v4
28
+ with:
29
+ ref: ${{ github.event.pull_request.head.sha || github.sha }}
30
+ - name: Check cache hit
31
+ uses: actions/cache/restore@v4
32
+ id: node_modules
33
+ with:
34
+ path: |
35
+ **/node_modules
36
+ key: runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
37
+ lookup-only: true
38
+ - uses: actions/setup-node@v4
39
+ if: steps.node_modules.outputs.cache-hit != 'true'
40
+ with:
41
+ node-version-file: '.nvmrc'
42
+ cache: yarn
43
+ cache-dependency-path: yarn.lock
44
+ - run: yarn install --frozen-lockfile
45
+ if: steps.node_modules.outputs.cache-hit != 'true'
46
+ - name: Save cache
47
+ if: steps.node_modules.outputs.cache-hit != 'true'
48
+ uses: actions/cache/save@v4
49
+ with:
50
+ path: |
51
+ **/node_modules
52
+ key: runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
53
+
54
+ runtime_compiler_yarn_cache:
55
+ name: Cache Runtime, Compiler
56
+ runs-on: ubuntu-latest
57
+ steps:
58
+ - uses: actions/checkout@v4
59
+ with:
60
+ ref: ${{ github.event.pull_request.head.sha || github.sha }}
61
+ - name: Check cache hit
62
+ uses: actions/cache/restore@v4
63
+ id: node_modules
64
+ with:
65
+ path: |
66
+ **/node_modules
67
+ key: runtime-and-compiler-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'compiler/yarn.lock') }}
68
+ lookup-only: true
69
+ - uses: actions/setup-node@v4
70
+ if: steps.node_modules.outputs.cache-hit != 'true'
71
+ with:
72
+ node-version-file: '.nvmrc'
73
+ cache: yarn
74
+ cache-dependency-path: |
75
+ yarn.lock
76
+ compiler/yarn.lock
77
+ - run: yarn install --frozen-lockfile
78
+ if: steps.node_modules.outputs.cache-hit != 'true'
79
+ - run: yarn --cwd compiler install --frozen-lockfile
80
+ if: steps.node_modules.outputs.cache-hit != 'true'
81
+ - name: Save cache
82
+ if: steps.node_modules.outputs.cache-hit != 'true'
83
+ uses: actions/cache/save@v4
84
+ with:
85
+ path: |
86
+ **/node_modules
87
+ key: runtime-and-compiler-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'compiler/yarn.lock') }}
88
+
89
# ----- FLOW -----
90
discover_flow_inline_configs:
91
name: Discover flow inline configs
@@ -36,7 +105,7 @@ jobs:
105
106
flow:
107
name: Flow check ${{ matrix.flow_inline_config_shortname }}
39
- needs: discover_flow_inline_configs
108
+ needs: [discover_flow_inline_configs, runtime_yarn_cache]
109
runs-on: ubuntu-latest
110
strategy:
111
fail-fast: false
@@ -52,7 +121,7 @@ jobs:
121
cache: yarn
122
cache-dependency-path: yarn.lock
123
- name: Restore cached node_modules
55
- uses: actions/cache@v4
124
+ uses: actions/cache/restore@v4
125
id: node_modules
126
with:
127
path: |
@@ -61,11 +130,13 @@ jobs:
130
- name: Ensure clean build directory
131
run: rm -rf build
132
- run: yarn install --frozen-lockfile
133
+ if: steps.node_modules.outputs.cache-hit != 'true'
134
- run: node ./scripts/tasks/flow-ci ${{ matrix.flow_inline_config_shortname }}
135
136
# ----- FIZZ -----
137
check_generated_fizz_runtime:
138
name: Confirm generated inline Fizz runtime is up to date
139
+ needs: [runtime_yarn_cache]
140
runs-on: ubuntu-latest
141
steps:
142
- uses: actions/checkout@v4
@@ -77,7 +148,7 @@ jobs:
148
cache: yarn
149
cache-dependency-path: yarn.lock
150
- name: Restore cached node_modules
80
- uses: actions/cache@v4
151
+ uses: actions/cache/restore@v4
152
id: node_modules
153
with:
154
path: |
@@ -86,6 +157,7 @@ jobs:
157
- name: Ensure clean build directory
158
run: rm -rf build
159
- run: yarn install --frozen-lockfile
160
+ if: steps.node_modules.outputs.cache-hit != 'true'
161
- run: |
162
yarn generate-inline-fizz-runtime
163
git diff --quiet || (echo "There was a change to the Fizz runtime. Run `yarn generate-inline-fizz-runtime` and check in the result." && false)
@@ -93,6 +165,7 @@ jobs:
165
# ----- FEATURE FLAGS -----
166
flags:
167
name: Check flags
168
+ needs: [runtime_yarn_cache]
169
runs-on: ubuntu-latest
170
steps:
171
- uses: actions/checkout@v4
@@ -104,7 +177,7 @@ jobs:
177
cache: yarn
178
cache-dependency-path: yarn.lock
179
- name: Restore cached node_modules
107
- uses: actions/cache@v4
180
+ uses: actions/cache/restore@v4
181
id: node_modules
182
with:
183
path: |
@@ -113,11 +186,13 @@ jobs:
186
- name: Ensure clean build directory
187
run: rm -rf build
188
- run: yarn install --frozen-lockfile
189
+ if: steps.node_modules.outputs.cache-hit != 'true'
190
- run: yarn flags
191
192
# ----- TESTS -----
193
test:
194
name: yarn test ${{ matrix.params }} (Shard ${{ matrix.shard }})
195
+ needs: [runtime_compiler_yarn_cache]
196
runs-on: ubuntu-latest
197
strategy:
198
fail-fast: false
@@ -160,7 +235,7 @@ jobs:
235
yarn.lock
236
compiler/yarn.lock
237
- name: Restore cached node_modules
163
- uses: actions/cache@v4
238
+ uses: actions/cache/restore@v4
239
id: node_modules
240
with:
241
path: |
@@ -169,12 +244,15 @@ jobs:
244
- name: Ensure clean build directory
245
run: rm -rf build
246
- run: yarn install --frozen-lockfile
247
+ if: steps.node_modules.outputs.cache-hit != 'true'
248
- run: yarn --cwd compiler install --frozen-lockfile
249
+ if: steps.node_modules.outputs.cache-hit != 'true'
250
- run: yarn test ${{ matrix.params }} --ci --shard=${{ matrix.shard }}
251
252
# ----- BUILD -----
253
build_and_lint:
254
name: yarn build and lint
255
+ needs: [runtime_compiler_yarn_cache]
256
runs-on: ubuntu-latest
257
strategy:
258
fail-fast: false
@@ -198,7 +276,7 @@ jobs:
276
distribution: temurin
277
java-version: 11.0.22
278
- name: Restore cached node_modules
201
- uses: actions/cache@v4
279
+ uses: actions/cache/restore@v4
280
id: node_modules
281
with:
282
path: |
@@ -207,7 +285,9 @@ jobs:
285
- name: Ensure clean build directory
286
run: rm -rf build
287
- run: yarn install --frozen-lockfile
288
+ if: steps.node_modules.outputs.cache-hit != 'true'
289
- run: yarn --cwd compiler install --frozen-lockfile
290
+ if: steps.node_modules.outputs.cache-hit != 'true'
291
- run: yarn build --index=${{ matrix.worker_id }} --total=20 --r=${{ matrix.release_channel }} --ci
292
env:
293
CI: github
@@ -225,7 +305,7 @@ jobs:
305
306
test_build:
307
name: yarn test-build
228
- needs: build_and_lint
308
+ needs: [build_and_lint, runtime_compiler_yarn_cache]
309
strategy:
310
fail-fast: false
311
matrix:
@@ -276,7 +356,7 @@ jobs:
356
yarn.lock
357
compiler/yarn.lock
358
- name: Restore cached node_modules
279
- uses: actions/cache@v4
359
+ uses: actions/cache/restore@v4
360
id: node_modules
361
with:
362
path: |
@@ -285,7 +365,9 @@ jobs:
365
- name: Ensure clean build directory
366
run: rm -rf build
367
- run: yarn install --frozen-lockfile
368
+ if: steps.node_modules.outputs.cache-hit != 'true'
369
- run: yarn --cwd compiler install --frozen-lockfile
370
+ if: steps.node_modules.outputs.cache-hit != 'true'
371
- name: Restore archived build
372
uses: actions/download-artifact@v4
373
with:
@@ -298,7 +380,7 @@ jobs:
380
381
process_artifacts_combined:
382
name: Process artifacts combined
301
- needs: build_and_lint
383
+ needs: [build_and_lint, runtime_yarn_cache]
384
runs-on: ubuntu-latest
385
steps:
386
- uses: actions/checkout@v4
@@ -310,7 +392,7 @@ jobs:
392
cache: yarn
393
cache-dependency-path: yarn.lock
394
- name: Restore cached node_modules
313
- uses: actions/cache@v4
395
+ uses: actions/cache/restore@v4
396
id: node_modules
397
with:
398
path: |
@@ -319,6 +401,7 @@ jobs:
401
- name: Ensure clean build directory
402
run: rm -rf build
403
- run: yarn install --frozen-lockfile
404
+ if: steps.node_modules.outputs.cache-hit != 'true'
405
- name: Restore archived build
406
uses: actions/download-artifact@v4
407
with:
@@ -346,7 +429,7 @@ jobs:
429
430
check_error_codes:
431
name: Search build artifacts for unminified errors
349
- needs: build_and_lint
432
+ needs: [build_and_lint, runtime_yarn_cache]
433
runs-on: ubuntu-latest
434
steps:
435
- uses: actions/checkout@v4
@@ -358,7 +441,7 @@ jobs:
441
cache: yarn
442
cache-dependency-path: yarn.lock
443
- name: Restore cached node_modules
361
- uses: actions/cache@v4
444
+ uses: actions/cache/restore@v4
445
id: node_modules
446
with:
447
path: |
@@ -367,6 +450,7 @@ jobs:
450
- name: Ensure clean build directory
451
run: rm -rf build
452
- run: yarn install --frozen-lockfile
453
+ if: steps.node_modules.outputs.cache-hit != 'true'
454
- name: Restore archived build
455
uses: actions/download-artifact@v4
456
with:
@@ -382,7 +466,7 @@ jobs:
466
467
check_release_dependencies:
468
name: Check release dependencies
385
- needs: build_and_lint
469
+ needs: [build_and_lint, runtime_yarn_cache]
470
runs-on: ubuntu-latest
471
steps:
472
- uses: actions/checkout@v4
@@ -394,7 +478,7 @@ jobs:
478
cache: yarn
479
cache-dependency-path: yarn.lock
480
- name: Restore cached node_modules
397
- uses: actions/cache@v4
481
+ uses: actions/cache/restore@v4
482
id: node_modules
483
with:
484
path: |
@@ -403,6 +487,7 @@ jobs:
487
- name: Ensure clean build directory
488
run: rm -rf build
489
- run: yarn install --frozen-lockfile
490
+ if: steps.node_modules.outputs.cache-hit != 'true'
491
- name: Restore archived build
492
uses: actions/download-artifact@v4
493
with:
@@ -427,7 +512,7 @@ jobs:
512
cache: yarn
513
cache-dependency-path: yarn.lock
514
- name: Restore cached node_modules
430
- uses: actions/cache@v4
515
+ uses: actions/cache@v4 # note: this does not reuse centralized cache since it has unique cache key
516
id: node_modules
517
with:
518
path: |
@@ -436,6 +521,7 @@ jobs:
521
- name: Ensure clean build directory
522
run: rm -rf build
523
- run: yarn --cwd fixtures/dom install --frozen-lockfile
524
+ if: steps.node_modules.outputs.cache-hit != 'true'
525
- name: Restore archived build
526
uses: actions/download-artifact@v4
527
with:
@@ -470,7 +556,7 @@ jobs:
556
# That means dependencies of the built packages are not installed.
557
# We need to install dependencies of the workroot to fulfill all dependency constraints
558
- name: Restore cached node_modules
473
- uses: actions/cache@v4
559
+ uses: actions/cache@v4 # note: this does not reuse centralized cache since it has unique cache key
560
id: node_modules
561
with:
562
path: |
@@ -479,6 +565,7 @@ jobs:
565
- name: Ensure clean build directory
566
run: rm -rf build
567
- run: yarn install --frozen-lockfile
568
+ if: steps.node_modules.outputs.cache-hit != 'true'
569
- name: Restore archived build
570
uses: actions/download-artifact@v4
571
with:
@@ -517,7 +604,7 @@ jobs:
604
# ----- DEVTOOLS -----
605
build_devtools_and_process_artifacts:
606
name: Build DevTools and process artifacts
520
- needs: build_and_lint
607
+ needs: [build_and_lint, runtime_yarn_cache]
608
runs-on: ubuntu-latest
609
strategy:
610
fail-fast: false
@@ -533,7 +620,7 @@ jobs:
620
cache: yarn
621
cache-dependency-path: yarn.lock
622
- name: Restore cached node_modules
536
- uses: actions/cache@v4
623
+ uses: actions/cache/restore@v4
624
id: node_modules
625
with:
626
path: |
@@ -542,6 +629,7 @@ jobs:
629
- name: Ensure clean build directory
630
run: rm -rf build
631
- run: yarn install --frozen-lockfile
632
+ if: steps.node_modules.outputs.cache-hit != 'true'
633
- name: Restore archived build
634
uses: actions/download-artifact@v4
635
with:
@@ -573,7 +661,7 @@ jobs:
661
662
run_devtools_e2e_tests:
663
name: Run DevTools e2e tests
576
- needs: build_and_lint
664
+ needs: [build_and_lint, runtime_yarn_cache]
665
runs-on: ubuntu-latest
666
steps:
667
- uses: actions/checkout@v4
@@ -585,7 +673,7 @@ jobs:
673
cache: yarn
674
cache-dependency-path: yarn.lock
675
- name: Restore cached node_modules
588
- uses: actions/cache@v4
676
+ uses: actions/cache/restore@v4
677
id: node_modules
678
with:
679
path: |
@@ -594,6 +682,7 @@ jobs:
682
- name: Ensure clean build directory
683
run: rm -rf build
684
- run: yarn install --frozen-lockfile
685
+ if: steps.node_modules.outputs.cache-hit != 'true'
686
- name: Restore archived build
687
uses: actions/download-artifact@v4
688
with:
@@ -611,7 +700,7 @@ jobs:
700
sizebot:
701
if: ${{ github.event_name == 'pull_request' && github.ref_name != 'main' && github.event.pull_request.base.ref == 'main' }}
702
name: Run sizebot
614
- needs: [build_and_lint]
703
+ needs: [build_and_lint, runtime_yarn_cache]
704
runs-on: ubuntu-latest
705
steps:
706
- uses: actions/checkout@v4
@@ -623,15 +712,18 @@ jobs:
712
cache: yarn
713
cache-dependency-path: yarn.lock
714
- name: Restore cached node_modules
626
- uses: actions/cache@v4
715
+ uses: actions/cache/restore@v4
716
id: node_modules
717
with:
718
path: |
719
**/node_modules
631
- key: runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
720
+ key: runtime-release-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'scripts/release/yarn.lock') }}
721
- name: Ensure clean build directory
722
run: rm -rf build
723
+ - run: yarn install --frozen-lockfile
724
+ if: steps.node_modules.outputs.cache-hit != 'true'
725
- run: yarn --cwd scripts/release install --frozen-lockfile
726
+ if: steps.node_modules.outputs.cache-hit != 'true'
727
- name: Download artifacts for base revision
728
run: |
729
GH_TOKEN=${{ github.token }} scripts/release/download-experimental-build.js --commit=$(git rev-parse ${{ github.event.pull_request.base.sha }})
@@ -647,6 +739,7 @@ jobs:
739
- name: Ensure clean build directory
740
run: rm -rf build
741
- run: yarn install --frozen-lockfile
742
+ if: steps.node_modules.outputs.cache-hit != 'true'
743
- name: Restore archived build for PR
744
uses: actions/download-artifact@v4
745
with: