Compare commits

..

106 Commits

Author SHA1 Message Date
Sebastian Sebbie Silbermann
1fdab2f46b 19.1.6
Some checks failed
(Runtime) Build and Test / Cache Runtime node_modules (push) Has been cancelled
(Runtime) Build and Test / Cache Runtime, Compiler node_modules (push) Has been cancelled
(Runtime) Build and Test / Discover flow inline configs (push) Has been cancelled
(Runtime) Build and Test / Flow check ${{ matrix.flow_inline_config_shortname }} (push) Has been cancelled
(Runtime) Build and Test / Confirm generated inline Fizz runtime is up to date (push) Has been cancelled
(Runtime) Build and Test / Check flags (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / Test eslint-plugin-react-hooks (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 0) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 1) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 10) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 11) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 12) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 13) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 14) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 15) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 16) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 17) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 18) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 19) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 2) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 20) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 21) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 22) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 23) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 24) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 3) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 4) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 5) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 6) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 7) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 8) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 9) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 0) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 1) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 10) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 11) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 12) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 13) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 14) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 15) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 16) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 17) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 18) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 19) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 2) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 20) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 21) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 22) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 23) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 24) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 3) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 4) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 5) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 6) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 7) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 8) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 9) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / Process artifacts combined (push) Has been cancelled
(Runtime) Build and Test / Search build artifacts for unminified errors (push) Has been cancelled
(Runtime) Build and Test / Check release dependencies (push) Has been cancelled
(Runtime) Build and Test / Check fixtures DOM (stable) (push) Has been cancelled
(Runtime) Build and Test / Run fixtures Flight tests (push) Has been cancelled
(Runtime) Build and Test / Build DevTools and process artifacts (chrome) (push) Has been cancelled
(Runtime) Build and Test / Build DevTools and process artifacts (edge) (push) Has been cancelled
(Runtime) Build and Test / Build DevTools and process artifacts (firefox) (push) Has been cancelled
(Runtime) Build and Test / Merge DevTools artifacts (push) Has been cancelled
(Runtime) Build and Test / Run DevTools e2e tests (push) Has been cancelled
(Runtime) Build and Test / Run sizebot (push) Has been cancelled
2026-03-18 20:32:35 +01:00
Hendrik Liebau
6cd04f4c5f [Flight] Avoid consuming cyclic models multiple times
Co-authored-by: "Sebastian \"Sebbie\" Silbermann" <sebastian.silbermann@vercel.com>
2026-03-18 20:32:02 +01:00
Sebastian Sebbie Silbermann
4045752491 Version 19.1.5
Some checks failed
(Runtime) Build and Test / Cache Runtime node_modules (push) Has been cancelled
(Runtime) Build and Test / Cache Runtime, Compiler node_modules (push) Has been cancelled
(Runtime) Build and Test / Discover flow inline configs (push) Has been cancelled
(Runtime) Build and Test / Flow check ${{ matrix.flow_inline_config_shortname }} (push) Has been cancelled
(Runtime) Build and Test / Confirm generated inline Fizz runtime is up to date (push) Has been cancelled
(Runtime) Build and Test / Check flags (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / Test eslint-plugin-react-hooks (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 0) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 1) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 10) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 11) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 12) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 13) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 14) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 15) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 16) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 17) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 18) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 19) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 2) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 20) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 21) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 22) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 23) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 24) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 3) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 4) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 5) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 6) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 7) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 8) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 9) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 0) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 1) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 10) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 11) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 12) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 13) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 14) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 15) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 16) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 17) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 18) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 19) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 2) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 20) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 21) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 22) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 23) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 24) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 3) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 4) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 5) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 6) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 7) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 8) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 9) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / Process artifacts combined (push) Has been cancelled
(Runtime) Build and Test / Search build artifacts for unminified errors (push) Has been cancelled
(Runtime) Build and Test / Check release dependencies (push) Has been cancelled
(Runtime) Build and Test / Check fixtures DOM (stable) (push) Has been cancelled
(Runtime) Build and Test / Run fixtures Flight tests (push) Has been cancelled
(Runtime) Build and Test / Build DevTools and process artifacts (chrome) (push) Has been cancelled
(Runtime) Build and Test / Build DevTools and process artifacts (edge) (push) Has been cancelled
(Runtime) Build and Test / Build DevTools and process artifacts (firefox) (push) Has been cancelled
(Runtime) Build and Test / Merge DevTools artifacts (push) Has been cancelled
(Runtime) Build and Test / Run DevTools e2e tests (push) Has been cancelled
(Runtime) Build and Test / Run sizebot (push) Has been cancelled
2026-01-26 17:48:45 +01:00
Sebastian Markbage
1800c832d0 Add more DoS mitigations to React Flight Reply, and harden React Flight
Co-authored-by: Josh Story <josh.c.story@gmail.com>
Co-authored-by: Janka Uryga <lolzatu2@gmail.com>
Co-authored-by: Hendrik Liebau <mail@hendrik-liebau.de>
2026-01-26 16:43:23 +01:00
Sebastian Sebbie Silbermann
e3145b1f37 Version 19.1.4
Some checks failed
(Runtime) Build and Test / Cache Runtime node_modules (push) Has been cancelled
(Runtime) Build and Test / Cache Runtime, Compiler node_modules (push) Has been cancelled
(Runtime) Build and Test / Discover flow inline configs (push) Has been cancelled
(Runtime) Build and Test / Flow check ${{ matrix.flow_inline_config_shortname }} (push) Has been cancelled
(Runtime) Build and Test / Confirm generated inline Fizz runtime is up to date (push) Has been cancelled
(Runtime) Build and Test / Check flags (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / Test eslint-plugin-react-hooks (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 0) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 1) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 10) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 11) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 12) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 13) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 14) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 15) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 16) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 17) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 18) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 19) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 2) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 20) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 21) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 22) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 23) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 24) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 3) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 4) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 5) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 6) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 7) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 8) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 9) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 0) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 1) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 10) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 11) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 12) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 13) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 14) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 15) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 16) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 17) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 18) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 19) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 2) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 20) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 21) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 22) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 23) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 24) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 3) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 4) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 5) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 6) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 7) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 8) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 9) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / Process artifacts combined (push) Has been cancelled
(Runtime) Build and Test / Search build artifacts for unminified errors (push) Has been cancelled
(Runtime) Build and Test / Check release dependencies (push) Has been cancelled
(Runtime) Build and Test / Check fixtures DOM (stable) (push) Has been cancelled
(Runtime) Build and Test / Run fixtures Flight tests (push) Has been cancelled
(Runtime) Build and Test / Build DevTools and process artifacts (chrome) (push) Has been cancelled
(Runtime) Build and Test / Build DevTools and process artifacts (edge) (push) Has been cancelled
(Runtime) Build and Test / Build DevTools and process artifacts (firefox) (push) Has been cancelled
(Runtime) Build and Test / Merge DevTools artifacts (push) Has been cancelled
(Runtime) Build and Test / Run DevTools e2e tests (push) Has been cancelled
(Runtime) Build and Test / Run sizebot (push) Has been cancelled
2025-12-11 23:35:18 +01:00
Sebastian Markbage
72f436d0ef Add extra protection 2025-12-11 23:25:11 +01:00
Sebastian Sebbie Silbermann
cff62b6370 Version 19.1.3
Some checks failed
(Runtime) Build and Test / Cache Runtime node_modules (push) Has been cancelled
(Runtime) Build and Test / Cache Runtime, Compiler node_modules (push) Has been cancelled
(Runtime) Build and Test / Discover flow inline configs (push) Has been cancelled
(Runtime) Build and Test / Flow check ${{ matrix.flow_inline_config_shortname }} (push) Has been cancelled
(Runtime) Build and Test / Confirm generated inline Fizz runtime is up to date (push) Has been cancelled
(Runtime) Build and Test / Check flags (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / Test eslint-plugin-react-hooks (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 0) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 1) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 10) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 11) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 12) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 13) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 14) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 15) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 16) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 17) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 18) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 19) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 2) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 20) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 21) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 22) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 23) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 24) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 3) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 4) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 5) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 6) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 7) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 8) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 9) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 0) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 1) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 10) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 11) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 12) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 13) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 14) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 15) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 16) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 17) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 18) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 19) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 2) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 20) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 21) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 22) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 23) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 24) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 3) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 4) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 5) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 6) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 7) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 8) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 9) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / Process artifacts combined (push) Has been cancelled
(Runtime) Build and Test / Search build artifacts for unminified errors (push) Has been cancelled
(Runtime) Build and Test / Check release dependencies (push) Has been cancelled
(Runtime) Build and Test / Check fixtures DOM (stable) (push) Has been cancelled
(Runtime) Build and Test / Run fixtures Flight tests (push) Has been cancelled
(Runtime) Build and Test / Build DevTools and process artifacts (chrome) (push) Has been cancelled
(Runtime) Build and Test / Build DevTools and process artifacts (edge) (push) Has been cancelled
(Runtime) Build and Test / Build DevTools and process artifacts (firefox) (push) Has been cancelled
(Runtime) Build and Test / Merge DevTools artifacts (push) Has been cancelled
(Runtime) Build and Test / Run DevTools e2e tests (push) Has been cancelled
(Runtime) Build and Test / Run sizebot (push) Has been cancelled
2025-12-11 19:03:44 +01:00
Sebastian Markbåge
6568bd00f9 Patch Promise cycles and toString on Server Functions
[Flight] Move `react-server-dom-webpack/*.unbundled` to private `react-server-dom-unbundled` (#35290)

Co-authored-by: Hendrik Liebau <mail@hendrik-liebau.de>
Co-authored-by: Sebastian "Sebbie" Silbermann <silbermann.sebastian@gmail.com>
2025-12-11 19:03:44 +01:00
Sebastian "Sebbie" Silbermann
7adca9e3b9 Run CI for backport releases (#35313) 2025-12-08 16:09:26 +01:00
Sebastian Sebbie Silbermann
ede3840137 Version 19.1.2 2025-12-03 15:33:20 +01:00
Sebastian Markbage
0e2ae74309 Bring ReactFlightClient fixes to FlightReplyServer
We did a bunch of refactors to ReactFlightClient in PRs like #29823 and #33664.

This brings a bunch of those related refactors to the equivalent FlightReplyServer. Such as deep resolution of cycles and deferred error handling.
2025-12-03 15:32:26 +01:00
Sebastian "Sebbie" Silbermann
6e79ecf60b [release] Allow building single release channel with processed versions (#35270) 2025-12-03 01:38:04 +01:00
Jack Pope
02ef495809 Reset packages we are not releasing to currently published versions 2025-07-24 16:35:10 -04:00
Riccardo Cipolleschi
3f178f55fc [Release] Update build script to properly set React Native's renderers version (#33972) 2025-07-24 16:49:56 +01:00
Jack Pope
87e33ca2b7 Set release versions to 19.1.1 2025-07-16 13:05:36 -04:00
lauren
52cf381c72 [eprh] Bump stable version (#32978)
https://www.npmjs.com/package/eslint-plugin-react-hooks/v/6.0.0 was just
released, so we can bump this now.
2025-07-16 12:55:41 -04:00
lauren
b793948e15 Bump next prerelease version numbers (#32782)
Updates the version numbers in the prerelease channels.
2025-07-16 12:55:24 -04:00
Jack Pope
73e4ba42cd Allow runtime_build_and_test action to trigger manually (#33796) 2025-07-16 12:52:44 -04:00
Ruslan Lesiutin
5a1eb6f61a fix: rename bottom stack frame (#33680)
`react-stack-bottom-frame` -> `react_stack_bottom_frame`.

This survives `@babel/plugin-transform-function-name`, but now frames
will be displayed as `at Object.react_stack_bottom_frame (...)` in V8.
Checks that were relying on exact function name match were updated to
use either `.indexOf()` or `.includes()`

For backwards compatibility, both React DevTools and Flight Client will
look for both options. I am not so sure about the latter and if React
version is locked.
2025-07-16 11:53:56 -04:00
Sebastian Markbåge
01eae200bf [DevTools] Get source location from structured callsites in prepareStackTrace (#33143)
When we get the source location for "View source for this element" we
should be using the enclosing function of the callsite of the child. So
that we don't just point to some random line within the component.

This is similar to the technique in #33136.

This technique is now really better than the fake throw technique, when
available. So I now favor the owner technique. The only problem it's
only available in DEV and only if it has a child that's owned (and not
filtered).

We could implement this same technique for the error that's thrown in
the fake throwing solution. However, we really shouldn't need that at
all because for client components we should be able to call
`inspect(fn)` at least in Chrome which is even better.
2025-07-16 11:11:51 -04:00
Timothy Yung
0e6781a06b Enable the enableEagerAlternateStateNodeCleanup Feature Flag (#33447)
Enables the `enableEagerAlternateStateNodeCleanup` feature flag for all
variants, while maintaining the `__VARIANT__` for the internal React
Native flavor for backtesting reasons.

```
$ yarn test
```
2025-07-15 15:29:02 -04:00
Samuel Susla
2cd3c424ea Add eager alternate.stateNode cleanup (#33161)
This is a fix for a problem where React retains shadow nodes longer than
it needs to. The behaviour is shown in React Native test:
https://github.com/facebook/react-native/blob/main/packages/react-native/src/private/__tests__/utilities/__tests__/ShadowNodeReferenceCounter-itest.js#L169

When React commits a new shadow tree, old shadow nodes are stored inside
`fiber.alternate.stateNode`. This is not cleared up until React clones
the node again. This may be problematic if mutation deletes a subtree,
in that case `fiber.alternate.stateNode` will retain entire subtree
until next update. In case of image nodes, this means retaining entire
images.

So when React goes from revision A: `<View><View /></View>` to revision
B: `<View />`, `fiber.alternate.stateNode` will be pointing to Shadow
Node that represents revision A..

![image](https://github.com/user-attachments/assets/076b677e-d152-4763-8c9d-4f923212b424)

To fix this, this PR adds a new feature flag
`enableEagerAlternateStateNodeCleanup`. When enabled,
`alternate.stateNode` is proactively pointed towards finishedWork's
stateNode, releasing resources sooner.

I have verified this fixes the issue [demonstrated by React Native
tests](https://github.com/facebook/react-native/blob/main/packages/react-native/src/private/__tests__/utilities/__tests__/ShadowNodeReferenceCounter-itest.js#L169).
All existing React tests pass when the flag is enabled.
2025-07-15 15:24:50 -04:00
Jack Pope
a24654e65b Ship enableFabricCompleteRootInCommitPhase (#33064)
This was shipped internally. Cleaning up the flag.
2025-07-15 15:16:15 -04:00
Sebastian "Sebbie" Silbermann
4a9df08157 Stop creating Owner Stacks if many have been created recently (#32529)
Co-authored-by: Jack Pope <jackpope1@gmail.com>
2025-03-23 15:47:03 -07:00
mofeiZ
da996a15be [compiler][be] Move e2e tests to BabelPlugin transformer (#32706)
Clean up jest-e2e setup since
https://github.com/facebook/react/pull/32663 and other features need
program context (e.g. changing imports)
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32706).
* #32663
* __->__ #32706
2025-03-21 20:05:22 -04:00
Dimitri POSTOLOV
6b1a2c1d81 fix(react-compiler): optimize components declared with arrow function and implicit return and compilationMode: 'infer' (#31792)
fixes https://github.com/facebook/react/issues/31601
https://github.com/facebook/react/issues/31639 cc @josephsavona
2025-03-21 16:46:02 -07:00
lauren
de4aad5ba6 [ci] Add missing permissions to runtime_commit_artifacts.yml (#32710)
Turns out we need permissions to write to `contents` after all.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32710).
* #32711
* __->__ #32710
2025-03-21 18:01:02 -04:00
lauren
156f0eca20 [ci] Don't use pull_request_target (#32708)
`pull_request_target` gives access to repository secrets and permissions
for use from forks, for example to add a comment.

> Due to the dangers inherent to automatic processing of PRs, GitHub’s
standard pull_request workflow trigger by default prevents write
permissions and secrets access to the target repository. However, in
some scenarios such access is needed to properly process the PR. To this
end the pull_request_target workflow trigger was introduced.

> The reason to introduce the pull_request_target trigger was to enable
workflows to label PRs (e.g. needs review) or to comment on the PR.

(via
https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/)

In this case there is no reason for us to allow this, so let's just use
the normal `pull_request` trigger which is less permissive.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32708).
* __->__ #32708
* #32709
2025-03-21 16:17:28 -04:00
lauren
4f080e498c [ci] Also give permissions on pull_requests (#32709)
Missed one
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32709).
* #32708
* __->__ #32709
2025-03-21 16:17:15 -04:00
lauren
fe8c10695c [ci] Add missing permissions (#32707)
Missed these ones earlier.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32707).
* #32708
* __->__ #32707
2025-03-21 16:07:09 -04:00
Ricky
daee08562c [activity] remove ref for now (#32645)
Followup from https://github.com/facebook/react/pull/32499

Manual mode is unused and has some bugs such as revealing hidden
boundaries when manually toggling. We also want to change how manual
mode works, and do some refactors to Activity to make it easier to
support. For now we'll remove it, then add it back after the other
changes we have planned.
2025-03-21 14:44:02 -04:00
lauren
ab693a926f [ci] Scope permissions for all workflows (#32704) 2025-03-21 14:40:55 -04:00
lauren
607615f4f6 [ci] Scope permissions for runtime_commit_artifacts.yml (#32701) 2025-03-21 14:40:34 -04:00
Sebastian Markbåge
e1e740717b Force layout before startViewTransition (#32699)
This works around this Safari bug.
https://bugs.webkit.org/show_bug.cgi?id=290146

This unfortunate because it may cause additional layouts if there's more
updates to the tree coming by manual mutation before it gets painted
naturally. However, we might end up wanting to read layout early anyway.

This affects the fixture because we clone the `<link>` from the `<head>`
which is itself another bug. However, it should be possible to have
`<link>` tags inserted into the new tree so this is still relevant.
2025-03-21 10:05:31 -04:00
lauren
ac799e569d [ci] Bump number of shards for test_build to 10 (#32693)
I noticed `test_build` can take a while so let's bump the number of
shards
2025-03-20 17:49:36 -04:00
mofeiZ
0962f684a0 [compiler][bugfix] Don't insert hook guards in retry pipeline (#32665)
Fixing bug from https://github.com/facebook/react/pull/32164 -- prior to
this PR, we inserted hook guards even for functions that bailed out of
compilation.
2025-03-20 17:25:08 -04:00
lauren
b888986054 [ci] Rename other stale branch workflow (#32692)
Makes it easier to tell what is what
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32692).
* __->__ #32692
* #32691
2025-03-20 17:19:47 -04:00
lauren
addce2f9f2 [ci] Add daily stale branch cache cleanup (#32691)
Cleans up stale non-main caches daily
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32691).
* #32692
* __->__ #32691
2025-03-20 17:17:44 -04:00
lauren
74bcf3d0d2 [ci] Don't fail on cache miss (#32690)
Partially reverts #32686.

PR caches inherit from caches generated in `main`. If it cannot find
that cache, it will create one scoped to just that PR (and PRs that
inherit from it).

There is an edge case where cache eviction can happen in the middle of a
test run. If cache eviction removes a `main` cache, child jobs that
depend on it will start failing because of the `fail-on-cache-miss`
setting.

This PR reverts the default behavior. If this happens, the workflow will
still continue in slow mode where it will `yarn install` child jobs
instead of reusing from cache. This is slower but will at least allow
workflows to continue.

Additionally I added restore keys so that we can fallback to other
caches if present so `yarn install` doesn't need to start over from
scratch.
2025-03-20 17:02:39 -04:00
Ricky
b630219b13 [refactor] move isValidElementType to react-is (#32518) 2025-03-20 16:51:33 -04:00
Jack Pope
7943da1e81 Set accurate value for alwaysThrottleRetries on www (#32684)
This flag value was updated in
https://github.com/facebook/react/pull/28965 (seemingly unrelated, maybe
as part of unit testing). But its still controlled by a dynamic flag in
www. Let's update this to VARIANT to accurately represent the state of
the rollout.

Before:
<img width="1340" alt="Screenshot 2025-03-20 at 10 45 30 AM"
src="https://github.com/user-attachments/assets/d0405a36-eb71-4108-9e23-8d462cc68fb4"
/>

After:
<img width="1351" alt="Screenshot 2025-03-20 at 10 45 11 AM"
src="https://github.com/user-attachments/assets/459d260d-7a25-430b-95a6-d6a91d958417"
/>
2025-03-20 14:28:55 -04:00
Joe Savona
e3c06424ae [compiler] Refactor validations to return Result and log where appropriate
Updates ~all of our validations to return a Result, and then updates callers to either unwrap() if they should bailout or else just log.

ghstack-source-id: 418b5f5aa2b7dd49ca76b3f98a48a35150691d7e
Pull Request resolved: https://github.com/facebook/react/pull/32688
2025-03-20 11:02:02 -07:00
Joe Savona
5f4c5c920f [compiler] Validate static components
React uses function identity to determine whether a given JSX expression represents the same type of component and should reconcile (keep state, update props) or replace (teardown state, create a new instance). This PR adds off-by-default validation to check that developers are not dynamically creating components during render.

The check is local and intentionally conservative. We specifically look for the results of call expressions, new expressions, or function expressions that are then used directly (or aliased) as a JSX tag. This allows common sketchy but fine-in-practice cases like passing a reference to a component from a parent as props, but catches very obvious mistakes such as:

```js
function Example() {
  const Component = createComponent();
  return <Component />;
}
```

We could expand this to catch more cases, but this seems like a reasonable starting point. Note that I tried enabling the validation by default and the only fixtures that error are the new ones added here. I'll also test this internally. What i'm imagining is that we enable this in the linter but not the compiler.

ghstack-source-id: e7408c0a55478b40d65489703d209e8fa7205e45
Pull Request resolved: https://github.com/facebook/react/pull/32683
2025-03-20 11:02:02 -07:00
lauren
112224d8d2 [ci] Also cache playground playwright browsers (#32687)
Following #32678, do the same for the playground e2e test since this
step can sometimes take many minutes to complete.
2025-03-20 13:53:31 -04:00
lauren
87d7e4c55b [ci] Fail on cache miss (#32686)
Since we use a centralized cache we should fail subsequent steps if the
child jobs are unable to restore the cache from the first 2 jobs.

Also fix some incorrect hashes used for the fixture tests.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32686).
* __->__ #32686
* #32685
2025-03-20 12:22:06 -04:00
lauren
3bcf8c23de [ci] Warm cache (#32685)
Try restoring from old caches as a base to speed up the case where
node_modules needs updating.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32685).
* #32686
* __->__ #32685
2025-03-20 12:21:50 -04:00
Sebastian Markbåge
a4f9bd586b Enable Fragment refs in Experimental (#32670)
That we can test it out in Next.js router conditionally when
experimental is on for other reasons.
2025-03-19 20:38:27 -04:00
lauren
ff8f6f21f7 [ci] Fix Will commit these changes www step (#32681)
Unlike the fbsource version of the step, www doesn't add any changes so
the `force` input doesn't actually work
2025-03-19 18:13:06 -04:00
lauren
19176e3c08 [ci] Use correct revision for Meta builds (#32680)
There was a bug previously in our commit artifacts step where the
emitted REVISION hash would reference the commit on the builds branch
rather than from `main`.

Given that our internal manual sync script also does this, let's align
them both to always reference the commit from `main` instead.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32680).
* __->__ #32680
* #32679
* #32678
2025-03-19 17:24:43 -04:00
lauren
d16c26da40 [ci] Specify if-no-files-found on actions/upload-artifact@v4 (#32679)
Defaults to warn, but since some steps require these artifacts to be
uploaded we specify an error if its not found. Some other steps like
playwright test-results are only uploaded on failure so it's okay to
ignore.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32679).
* #32680
* __->__ #32679
* #32678
2025-03-19 17:22:40 -04:00
lauren
a8c155cab9 [ci] Cache playwright browsers (#32678)
No reason to download them from scratch every time.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32678).
* #32680
* #32679
* __->__ #32678
2025-03-19 17:22:17 -04:00
lauren
995410463a [ci] Parameterize branch cleanup (#32677)
Allow a PR number to be passed as input
2025-03-19 16:39:01 -04:00
lauren
208905257f [ci] Add cache cleanup workflow (#32675)
> Caches have branch scope restriction in place. This means that if
caches for a specific branch are using a lot of storage quota, it may
result into more frequently used caches from default branch getting
thrashed. For example, if there are many pull requests happening on a
repo and are creating caches, these cannot be used in default branch
scope but will still occupy a lot of space till they get cleaned up by
eviction policy. But sometime we want to clean them up on a faster
cadence so as to ensure default branch is not thrashing.


https://github.com/actions/cache/blob/main/tips-and-workarounds.md#force-deletion-of-caches-overriding-default-cache-eviction-policy
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32675).
* __->__ #32675
* #32674
2025-03-19 15:42:04 -04:00
lauren
891a6332e3 [ci] Bump build_and_lint to 25 workers (#32674)
Increases number of workers for `build_and_lint`.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32674).
* #32675
* __->__ #32674
2025-03-19 15:41:48 -04:00
lauren
a4842c92ea [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
2025-03-19 15:25:07 -04:00
Niklas Holm
ada8bbbd6a [eslint-plugin-react-compiler] Fix type error with recommended config (#32666)
## Summary

In the recommended configuration for `eslint-plugin-react-compiler`,
i.e. `reactCompiler.configs.recommended`, the rule is typed as `string`
rather than `eslint.Linter.RuleEntry` or anything assignable thereto,
which results in the following type error if you type check your eslint
configuration:
```
Property ''react-compiler/react-compiler'' is incompatible with index signature.
  Type 'string' is not assignable to type 'RuleEntry | undefined'.
```
Simply adding a const assertion fixes the error.

## How did you test this change?

I emitted declarations for the module and confirmed that the rule is now
typed as the string literal `'error'`
2025-03-19 14:58:08 -04:00
lauren
e9c3b27b4b [ci] Bump all node_modules cache keys (#32671)
I'm seeing a lot of instances of

> Failed to save: Unable to reserve cache with key
runtime-and-compiler-node_modules-v5-X64-Linux-e454609794aae66da9909c77dd6efa073eceff7f44d6527611f8465e102578b4,
another job may be creating this cache.

which is adding ~20 seconds to every step. Let's try to bust the cache
following this
[comment](https://github.com/actions/cache/issues/485#issuecomment-744145040)
and see if that helps.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32671).
* #32672
* __->__ #32671
2025-03-19 14:42:45 -04:00
lauren
b0446ff06a [ci] Properly format commit message take 2 (#32673)
We need to use the commit message from `main`, not the builds branch
2025-03-19 14:01:49 -04:00
lauren
db7dfe0550 [eprh] Don't transpile to es5 (#32669)
Now that we've moved the sync location of the plugin, we no longer need
this since those restrictions no longer apply.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32669).
* __->__ #32669
* #32668
2025-03-19 11:49:42 -04:00
lauren
646835fb59 [ci] Properly format commit message (#32668)
Using the github variable for the commit message replaces the variable
inline. If the commit message contains quotes or other characters that
need to be escaped, this breaks the workflow.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32668).
* #32669
* __->__ #32668
2025-03-19 11:49:18 -04:00
Sebastian Markbåge
c2a1961747 Minor Fixes to View Transition Fixture (#32664)
Follow up to #32656.

Remove touchAction from SwipeRecognizer. I was under the wrong
impression that this was only the touch-action applied to this
particular element, but that parents would still win but in fact this
blocks the parent from scrolling in the other direction. By specifying a
fixed direction it also blocked rage-swiping in the other direction
early on.

Disable pointer-events on view-transition so that the scroll can be hit.
This means that touches hit below the items animating above. This allows
swiping to happen again before momentum scroll has finished. Previously
they were ignored. This only works as long as the SwipeRecognizer is
itself not animating. This means you can now rage-swipe in both
directions quickly.
2025-03-18 19:20:34 -04:00
mofeiZ
6584a6eec4 [compiler] Hoist dependencies from functions more conservatively (#32616)
Alternative to facebook/react#31584 which sets
enableTreatFunctionDepsAsConditional:true` by default.

This PR changes dependency hoisting to be more conservative while trying
to preserve an optimal "happy path". We assume that a function "is
likely called" if we observe the following in the react function body.

- a direct callsite
- passed directly as a jsx attribute or child
- passed directly to a hook
- a direct return

A function is also "likely called" if it is directly called, passed to
jsx / hooks, or returned from another function that "is likely called".

Note that this approach marks the function definition site with its
hoistable properties (not its use site). I tried implementing use-site
hoisting semantics, but it felt both unpredictable (i.e. as a developer,
I can't trust that callbacks are well memoized) and not helpful (type +
null checks of a value are usually colocated with their use site)

In this fixture (copied here for easy reference), it should be safe to
use `a.value` and `b.value` as dependencies, even though these functions
are conditionally called.
```js
// inner-function/nullable-objects/assume-invoked/conditional-call-chain.tsx
function Component({a, b}) {
  const logA = () => {
    console.log(a.value);
  };
  const logB = () => {
    console.log(b.value);
  };
  const hasLogged = useRef(false);
  const log = () => {
    if (!hasLogged.current) {
      logA();
      logB();
      hasLogged.current = true;
    }
  };
  return <Stringify log={log} shouldInvokeFns={true} />;
}
```

On the other hand, this means that we produce invalid output for code
like manually implementing `Array.map`
```js
// inner-function/nullable-objects/bug-invalid-array-map-manual.js
function useFoo({arr1, arr2}) {
  const cb = e => arr2[0].value + e.value;
  const y = [];
  for (let i = 0; i < arr1.length; i++) {
    y.push(cb(arr1[i]));
  }
  return y;
}
```
2025-03-18 18:00:08 -04:00
dan
86d5ac0882 Revert "Fix:- Improve HOC support and state preservation in React Refresh" (#32214)
Reverts facebook/react#30660

I don’t feel confident in the approach. This part of code is supposed to
rely on the module bundler behaving as expected. _Maybe_ this is correct
but I need to review it closer — it was intentionally _not_ implemented
this way originally.

I’ll try to take a closer look some time this week. We don’t have to
merge this revert right now but just flagging that I don’t understand
the thinking behind the new approach and don’t have confidence in it.
2025-03-18 19:05:56 +00:00
Jack Pope
476f53879e Add getClientRects to fragment instances (#32660)
Adds `getClientRects()` to fragment instances with a fixture test case.
`Element.getClientRect` returns a collection of `DOMRect`s (see example
of multiline span returning two `DOMRect` boxes).
`fragmentInstance.getClientRects` here flattens those collections into
an array of rects.
2025-03-18 13:54:26 -04:00
Jack Pope
c69a5fc53a Add blur() and focusLast() to fragment instances (#32654)
`focus()` was added in https://github.com/facebook/react/pull/32465.
Here we add `focusLast()` and `blur()`. I also extended `focus` to take
options.

`focus` will focus the first focusable element. `focusLast` will focus
the last focusable element. We could consider a `focusFirst` naming or
even the `focusWithin` used by test selector APIs as well.

`blur` will only have an effect if the current `document.activeElement`
is one of the fragment children.
2025-03-18 11:58:12 -04:00
Sebastian Markbåge
a35aaf704c Update ViewTransition fixture to include bigger buttons/swipe (#32656)
I made the button a bit bigger and moved the swipe recognizer around the
whole screen. Typically these are used around the whole content without
any affordances and not as a standalone scrubber. Ideally the swipe
would be able to be inside the animating content but it can't yet due to
[this Safari bug](https://bugs.webkit.org/show_bug.cgi?id=288795).

Added back some paragraphs so that scrolling can be tested properly. It
appears it's possible to get the swipe to be a bit misaligned if you
scroll enough on iOS.

<img width="437" alt="Screenshot 2025-03-17 at 10 27 42 PM"
src="https://github.com/user-attachments/assets/589dc828-717e-420c-83dc-94ae6ad59791"
/>
2025-03-18 09:24:31 -04:00
Sebastian Markbåge
3c3696d554 Measure Updated ViewTransition Boundaries (#32653)
This does the same thing for `measureUpdateViewTransition` that we did
for `measureNestedViewTransitions` in
e3cbaffef0.
If a boundary hasn't mutated and didn't change in size, we mark it for
cancellation. Otherwise we add names to it. The different from the
CommitViewTransition path is that the "old" names are added to the
clones so this is the first time the "new" names.

Now we also cancel any boundaries that were unchanged. So now the root
no longer animates. We still have to clone them. There are other
optimizations that can avoid cloning but once we've done all the layouts
we can still cancel the running animation and let them just be the
regular content if they didn't change. Just like the regular
fire-and-forget path.

This also fixes the measurement so that we measure clones by adjusting
their position back into the viewport.

This actually surfaces a bug in Safari that was already in #32612. It
turns out that the old names aren't picked up for some reason and so in
Safari they looked more like a cross-fade than what #32612 was supposed
to fix. However, now that bug is even more apparent because they
actually just disappear in Safari. I'm not sure what that bug is but
it's unrelated to this PR so will fix that separately.
2025-03-17 21:38:13 -04:00
Dimitri POSTOLOV
90b511ec7a fix(react-compiler): implement NumericLiteral as ObjectPropertyKey (#31791) 2025-03-17 19:30:58 -04:00
Sebastian Markbåge
02372952e4 Don't auto-start browser in SSR fixtures (#32652)
I end up restarting these a lot and it's annoying to have it open
another tab each time.

The flight fixture already doesn't auto-start.
2025-03-17 17:26:00 -04:00
Sebastian Markbåge
9fde224a53 Materialize the tree ID when ViewTransition name=auto consumes one (#32651)
ViewTransition uses the `useId` algorithm to auto-assign names. This
ensures that we could animate between SSR content and client content by
ensuring that the names line up.

However, I missed that we need to bump the id (materialize it) when we
do that. This is what function components do if they use one or more
`useId()`. This caused duplicate names when two ViewTransitions were
nested without any siblings since they would share name.
2025-03-17 16:17:01 -04:00
lauren
ca02c4bb40 [ci][ez] use yarn --cwd (#32650)
Run yarn install via `--cwd` instead of `working-directory` to make the
labels clearer
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32650).
* __->__ #32650
* #32649
* #32648
2025-03-17 14:13:27 -04:00
lauren
c37d89827e [ci] Pin Discord webhook action to specific commit sha (#32649)
Pins the discord webhook action to
`86dc739f3f165f16dadc5666051c367efa1692f4`, which is what the v6 tag
points to.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32649).
* #32650
* __->__ #32649
* #32648
2025-03-17 14:13:17 -04:00
lauren
6c6699f3d2 [ci] Don't use third party action to push commits (#32648)
In light of recent third party actions being compromised, let's just
push the commit ourselves rather than use a third party action. We
already detect if changes are needed, so the step will only run if so.

I also added a `dry_run` option to the manual runs of this workflow for
testing.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32648).
* #32650
* #32649
* __->__ #32648
2025-03-17 14:13:02 -04:00
Andrew Clark
9320a0139d Fix COMMIT_SHA when generating PR artifacts (#32647)
Follow-up to #31850. We want to build using the original commit SHA, not
the merge commit that GitHub Actions creates behind the scenes. We were
already checking out the correct commit object, but the COMMIT_SHA
artifact was still pointing to the merge commit.

This should fix the sizebot links to point to working URLs, too.
2025-03-17 12:46:27 -04:00
Ricky
fbcda19a23 [devtools] add filters for internal builds (#32646)
We don't have an experimental-only build of devtools, but we can at
least add these filters to the internal build.

A better way would be to use feature detection, but I'm not sure how and
this isn't a very heavily used feautre.
2025-03-17 12:14:19 -04:00
Jack Pope
cd28a946d5 Add observer methods to fragment instances (#32619)
This implements `observeUsing(observer)` and `unobserverUsing(observer)`
on fragment instances. IntersectionObservers and ResizeObservers can be
passed to observe each host child of the fragment. This is the
equivalent to calling `observer.observe(child)` or
`observer.unobserve(child)` for each child target.

Just like the addEventListener, the observer is held on the fragment
instance and applied to any newly mounted child. So you can do things
like wrap a paginated list in a fragment and have each child
automatically observed as they commit in.

Unlike, the event listeners though, we don't `unobserve` when a child is
removed. If a removed child is currently intersecting, the observer
callback will be called when it is removed with an empty rect. This lets
you track all the currently intersecting elements by setting state from
the observer callback and either adding or removing them from your list
depending on the intersecting state. If you want to track the removal of
items offscreen, you'd have to maintain that state separately and append
intersecting data to it in the observer callback. This is what the
fixture example does.

There could be more convenient ways of managing the state of multiple
child intersections, but basic examples are able to be modeled with the
simple implementation. Let's see how the usage goes as we integrate this
with more advanced loggers and other features.

For now you can only attach one observer to an instance. This could
change based on usage but the fragments are composable and could be
stacked as one way to apply multiple observers to the same elements.

In practice, one pattern we expect to enable is more composable logging
such as

```javascript
function Feed({ items }) {
  return (
    <ImpressionLogger>
      {items.map((item) => (
        <FeedItem />
      ))}
    </ImpressionLogger>
  );
}
```

where `ImpressionLogger` would set up the IntersectionObserver using a
fragment ref with the required business logic and various components
could layer it wherever the logging is needed. Currently most callsites
use a hook form, which can require wiring up refs through the tree and
merging refs for multiple loggers.
2025-03-17 11:40:05 -04:00
Ricky
8243f3f063 [bug] Fix component name for Portal and add tests (#32640)
Based off: https://github.com/facebook/react/pull/32499

While looking into `React.lazy` issues for built-ins, I noticed we
already error for `lazy` with build-ins, but we don't have any tests for
`getComponentNameFromType` using all the built-ins. This may be
something we should handle, but for now we should at least have tests.

Here's why: while writing tests, I noticed we check `type` instead of
`$$typeof` for portals:


9cdf8a99ed/packages/react-reconciler/src/ReactPortal.js (L25-L32)

This PR adds tests for all the built-ins and fixes the portal bug.

[Commit to
review](e068c167d4)
2025-03-17 11:23:28 -04:00
Ricky
df31952275 Remove offscreen type (#32639)
Based off https://github.com/facebook/react/pull/32499

This is no longer used.

[Review
commit](88c297d12f)
2025-03-17 09:37:07 -04:00
Ricky
1a191701fe [refactor] Add element type for Activity (#32499)
This PR separates Activity to it's own element type separate from
Offscreen. The goal is to allow us to add Activity element boundary
semantics during hydration similar to Suspense semantics, without
impacting the Offscreen behavior in suspended children.
2025-03-17 09:17:00 -04:00
Ricky
99563e9173 Partially revert #32588 (#32621)
https://github.com/facebook/react/pull/32588 changed the babel config
impacting local tests, and I'm not able to run test:

<img width="1354" alt="Screenshot 2025-03-15 at 2 37 00 PM"
src="https://github.com/user-attachments/assets/2d4afe39-6ab6-4c83-87a9-ceb0ee5f8df5"
/>


This PR reverts those changes until we can re-land with a fix.
2025-03-15 15:21:57 -04:00
Sebastian Markbåge
17d274dc12 Remove Mutation Check Around commit/measureUpdateViewTransition (#32617)
There's two ways to find updated View Transitions.

One is the "commit/measureNestedViewTransitions" pass which is used to
find things in unchanged subtrees. This can only lead to the relayout
case since there's can't possibly be any mutations in the subtree. This
is only triggered when none of the direct siblings have any mutations at
all.

The other case is "commit/measureUpdateViewTransition" which is for a
ViewTransition that itself has mutations scheduled inside of it which
leads to the "update" case.

However, there's a case between these two cases. When a direct sibling
has a mutation but there's also a ViewTransition exactly at the same
level. In that case we can't bail out on the whole set of children so we
won't trigger the "nested" case. Previously we also didn't trigger the
"commit/measureUpdateViewTransition" case because we first checked if
that had any mutations inside of it at all. This leads to neither case
picking up this boundary.

We could check if the ViewTransition itself has any mutations inside and
if not trigger the nested path.

There's a simpler way though. Because
`commit/measureUpdateViewTransition` is actually just optimistic. The
flags are pessimistic and we don't know for sure if there will actually
be a mutation until we've traversed the tree. It can sometimes lead to
the "relayout" case. So we can just use that same path, knowing that
it'll just lead to the layout pass. Therefore it's safe to just remove
this check.
2025-03-14 17:38:53 -04:00
Sebastian Markbåge
6b5d9fd316 Move traverseFragmentInstanceChildren to internal ReactFiberTreeReflection (#32613)
This is a nit but a Config should not have to know anything about the
internals of Fibers. Ideally it shouldn't even access them but we have
some cases where we need pointers back in like for this fragment.

The way we've typically abstracted this is using the
`ReactFiberTreeReflection` helper that's in the `react-reconciler`. Such
as in the event system.
f3c956006a/packages/react-dom-bindings/src/events/ReactDOMEventListener.js (L22-L26)

We sometimes cheat but we really should clean this up such that a
`Fiber` is actually an opaque type to the Configs and it can never dot
into it without using a helper.

So this just moves `traverseFragmentInstanceChildren` to
ReactFiberTreeReflection so that the ConfigDOM doesn't ever dot into its
fields itself. It just passes the Fiber through back into the
react-reconciler. I had to add a wrapper to read the `.child` to avoid
that being assumed too. I also noticed that FragmentInstanceType is not
actually passed through so that argument is unnecessary.
2025-03-14 17:38:35 -04:00
Sebastian Markbåge
2c560374d6 Measure and apply names for the "new" phase (#32612)
Stacked on #32599 and #32611.

This is able to reuse the code from CommitViewTransitions for "enter",
"shared" and "layout". The difference is that for "enter"/"shared" in
the "new" phase we pass in the deletions.

For "layout" of nested boundaries we just need to measure the clones at
the same time we measure the original nodes since we haven't measured
them in a previous phase in the current approach.

With these updates, things move around more like expected in the fixture
because we're now applying the appropriate pairs to trigger individual
animations instead of just the full document cross-fade.

The "update" phase is a little more complicated and is coming soon.
2025-03-14 14:26:55 -04:00
Sebastian Markbåge
2e385738a4 Find Pairs and Apply View Transition Names to the Clones in the "old" Phase (#32599)
Stacked on #32578.

We need to apply view-transition-names to the clones that we create in
the "old" phase for the ViewTransition boundaries that should activate.

Finding pairs is a little trickier than in
ReactFiberCommitViewTransitions. Normally we collect all name
"insertions" in the `accumulateSuspenseyCommit` phase before we even
commit. Then in the snapshot do we visit all "deletions" and since we
already collected all the insertions we know immediately if the deletion
had a pair and should therefore get a "name" assigned to activate the
boundary. For ReactFiberApplyGesture we need to assign names to
"insertions" since it's in reverse but we don't already have a map of
deletions. Therefore we need to first visit all deletions.

Instead of doing that in a completely separate pass, we instead visit
deletions in the same pass to find pairs. Since this is in the same pass
we might visit insertions before deletions or vice versa depending on
document order. However, we can deal with this by applying the name to
the insertion when we find the deletion if we've already made the clones
at that point.

Applying names to pure exits, updates or nested (relayout) is a bit more
straight-forward.
2025-03-14 14:15:39 -04:00
Sebastian Markbåge
c4a3b92e09 Add more phases to the ReactFiberApplyGesture (#32578)
Stacked on #32585 and #32605.

This adds more loops for the phases of "Apply Gesture". It doesn't
implement the interesting bit yet like adding view-transition-names and
measurements. I'll do that in a separate PR to keep reviewing easier.

The three phases of this approach is roughly:

- Clone and apply names to the "old" state.
- Inside startViewTransition: Apply names to the "new" state. Measure
both the "old" and "new" state to know whether to cancel some of them.
Delete the clones which will include all the "old" names.
- After startViewTransition: Restore "new" names back to no
view-transition-name.

Since we don't have any other Effects in these phases we have a bit more
flexibility and we can avoid extra phases that traverse the tree. I've
tried to avoid any additional passes.

An interesting consequence of this approach is that we could measure
both the "old" and "new" state before `startViewTransition`. This would
be more efficient because we wouldn't need to take View Transition
snapshots of parts of the tree that won't actually animate. However,
that would require an extra pass and force layout earlier. It would also
have different semantics from the fire-and-forget View Transitions
because we could optimize better which can be visible. It would also not
account for any late mutations. So I decided to instead let the layout
be computed by painting as usual and then measure both "old" and "new"
inside the startViewTransition instead. Then canceling anything that
doesn't animate to keep it consistent.

Unfortunately, though there's not a lot of code sharing possible in
these phases because the strategy is so different with the cloning and
because the animation is performed in reverse. The "finishedWork" Fiber
represents the "old" state and the "current" Fiber represents the "new"
state.

The most complicated phase is the cloning. I actually ended up having to
make a very different pattern from the other phases and CommitWork in
general. Because we have to clone as we go and also do other things like
apply names and finding pairs, it has more phases. I ended up with an
approach that uses three different loops. The outer one for updated
trees, one for inserted trees that don't need cloning (doesn't include
reappearing offscreen) and one for not updated trees that still need
cloning. Inside each loop it can also be in different phases which I
track with the `visitPhase` enum - this pattern is kind of new.

Additionally, we need to measure the cloned nodes after we've applied
mutations to them and we have to wait until the whole tree is inserted.
We don't have a reference to these DOM elements in the Fiber tree since
that still refers to the original ones. We need to store the cloned
elements somewhere. So I added a temporary field on the
ViewTransitionState to keep track of any clones owned by that
ViewTransition.

When we deep clone an unchanged subtree we don't have DOM element
instances. It wouldn't be quite safe to try to find them from the tree
structure. So we need to avoid the deep clones if we might need DOM
elements. Therefore we keep traversing in the case where we need to find
nested ViewTransition boundaries that are either potentially affected by
layout or a "pair".

For the other two phases the pattern there's a lot of code duplication
since it's slightly different from the commit ones but they at least
follow the same pattern. For the restore phase I was actually able to
reuse most of the code.

I don't love how much code this is.
2025-03-14 13:20:17 -04:00
Sebastian Markbåge
6daef4e7c8 Make xViewTransitionToHostInstances helpers reusable (#32611)
This prepares from being able to reuse some this in ApplyGesture.

These all start with resetting a counter but it's tricky to have to
remember to do this and tricky to do from the outside of this module. So
we make an exported helper that does the resetting. Ideally it gets
inlined.

We also stop passing "current" to measureViewTransitionHostInstances.
Same thing for cancelViewTransitionHostInstances. This doesn't make
sense for "nested" which has not updated and so might not have an
alternate. Instead we pass in the old and new name if they might be
different.
2025-03-14 13:16:42 -04:00
Sebastian Markbåge
3e956805e8 Gate flushGestureMutations and flushGestureAnimations (#32605)
Normally these are gated by the whole commitGestureOnRoot path but in
the case of an early commit these phases may need to be invoked.
Earlier. Those paths weren't gated which I noticed when I started adding
code to them.
2025-03-14 13:16:30 -04:00
Sebastian Markbåge
1b6e3dd985 Merge restoreEnterViewTransitions and restoreExitViewTransitions (#32585)
This is the exact same code in both cases. It's just general clean up.

By unifying them it becomes less confusing to reuse these helpers in the
Apply Gesture path where the naming is reversed.
2025-03-14 13:16:20 -04:00
mofeiZ
5398b71158 [compiler] detect and throw on untransformed required features (#32512)
Traverse program after running compiler transform to find untransformed
references to compiler features (e.g. `inferEffectDeps`, `fire`).

Hard error to fail the babel pipeline when the compiler fails to
transform these features to give predictable runtime semantics.
Untransformed calls to functions like `fire` will throw at runtime
anyways, so let's fail the build to catch these earlier.

Note that with this fails the build *regardless of panicThreshold*
2025-03-14 11:44:49 -04:00
lauren
f3c956006a [ci] Update node_modules cache path (#32609)
Alternative of #32604.

Bust all old caches since I reverted some other changes to the keys.
2025-03-13 22:29:48 -04:00
lauren
4eba294c69 [ci] Cache runtime and compiler only for test runs (#32608)
We only need the compiler built for `yarn test` in the root directory.
Rather than always cache both for every step, let's just do it where
it's needed explicitly.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32608).
* #32609
* __->__ #32608
2025-03-13 22:21:35 -04:00
lauren
5200721e5c Revert "[ci] Update yarn and node_modules cache key (#32603)" (#32607)
This reverts commit 67338703aa.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32607).
* #32609
* #32608
* __->__ #32607
2025-03-13 22:14:00 -04:00
lauren
e9d80d939e Revert "[ci] Fix node_modules cache glob (#32604)" (#32606)
This reverts commit ef1103d3e9.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32606).
* #32609
* #32608
* #32607
* __->__ #32606
2025-03-13 21:52:46 -04:00
lauren
ef1103d3e9 [ci] Fix node_modules cache glob (#32604)
Seems like the stringified cache path can cause some directories not to
be cached, trying an alternative format
2025-03-13 20:59:27 -04:00
lauren
67338703aa [ci] Update yarn and node_modules cache key (#32603)
Now that the compiler lint rule is merged into
eslint-plugin-react-hooks, we also need to update our caches so compiler
dependencies are also cached. This should fix the CI walltime regression
we are now seeing.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32603).
* #32604
* __->__ #32603
2025-03-13 20:31:04 -04:00
mofeiZ
7939d92fcc [compiler] clean up retry pipeline: fireRetry flag -> compileMode (#32511)
Removes `EnvironmentConfig.enableMinimalTransformsForRetry` in favor of
`run` parameters. This is a minimal difference but lets us explicitly
opt out certain compiler passes based on mode parameters, instead of
environment configurations

Retry flags don't really make sense to have in `EnvironmentConfig`
anyways as the config is user-facing API, while retrying is a compiler
implementation detail.

(per @josephsavona's feedback
https://github.com/facebook/react/pull/32164#issuecomment-2608616479)
> Re the "hacky" framing of this in the PR title: I think this is fine.
I can see having something like a compilation or output mode that we use
when running the pipeline. Rather than changing environment settings
when we re-run, various passes could take effect based on the
combination of the mode + env flags. The modes might be:
>
> * Full: transform, validate, memoize. This is the default today.
> * Transform: Along the lines of the backup mode in this PR. Only
applies transforms that do not require following the rules of React,
like `fire()`.
> * Validate: This could be used for ESLint.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32511).
* #32512
* __->__ #32511
2025-03-13 19:54:54 -04:00
mofeiZ
d92e5713be [compiler] Avoid bailouts when inserting gating (#32598)
This change fixes a coverage hole in rolling out with `gating`. Prior to
this PR, configuring `gating` causes React Compiler to bail out of
optimizing some functions.

This means that it's not entirely safe to cutover from `gating` enabled
for all users (i.e. rolled out 100%) to removing the `gating` config
altogether, as new functions may be opted into compilation when they
stop bailing out due to gating-specific logic.

This is technically slightly slower due to the additional function
indirection. An alternative approach is to recommend running a codemod
to insert `use no memo`s on currently-bailing out functions before
removing the`gating` config.

---
Tested [internally](
https://fburl.com/diff/q982ovua) by enabling on a page that previously
had a few hundred bailouts due to gating + hoisted function declarations
and (1) clicking around locally and (2) running a bunch of e2e tests
2025-03-13 19:31:49 -04:00
mofeiZ
93b61fc4ec [compiler][ez] Stop bailing out early for hoisted gated functions (#32597)
Some code movement for the next PR
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32597).
* #32598
* __->__ #32597
2025-03-13 19:08:38 -04:00
lauren
77987e5ee3 [ci] mkdir before mv (#32602)
Missed this earlier.
2025-03-13 17:46:46 -04:00
lauren
0df46f01a9 [ci] Update eslint-plugin-react-hooks output location for Meta builds (#32601)
Updates where this file is output so we can sync it independently to
another directory.
2025-03-13 16:54:39 -04:00
mofeiZ
f457d0b4c6 [compiler][ez] Only fail gating hoisting check for referenced identifiers (#32596)
Reduce false positive bailouts by using the same
`isReferencedIdentifier` logic that the compiler also uses for
determining context variables and a function's own hoisted declarations.

Details:
Previously, we counted every babel identifier as a reference. This is
problematic because babel counts most string symbols as an identifier.

```js
print(x);  // x is an identifier as expected
obj.x      // x is.. also an identifier here
{x: 2}     // x is also an identifier here
```

This PR adds a check for `isReferencedIdentifier`. Note that only
non-lval
references pass this check. This should be fine as we don't need to
hoist function declarations before writes to the same lvalue (which
should error in strict mode anyways)
```js
print(x);  // isReferencedIdentifier(x) -> true
obj.x      // isReferencedIdentifier(x) -> false
{x: 2}     // isReferencedIdentifier(x) -> false
x = 2      // isReferencedIdentifier(x) -> false
```
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32596).
* __->__ #32596
* #32595
* #32594
* #32593
* #32522
* #32521
2025-03-13 12:10:22 -04:00
mofeiZ
1c79cb82ab [compiler][ez] Move compiler gating tests (#32595)
Move all gating tests to `gating/`
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32595).
* #32596
* __->__ #32595
* #32594
* #32593
* #32522
* #32521
2025-03-13 12:06:48 -04:00
mofeiZ
89a46a57df [compiler][optim] more shapes for mixedreadonly (#32594)
- Add `at`, `indexOf`, and `includes`
- Optimize MixedReadOnly which is currently only used by hook return
values. Hook return values are typed as Frozen, this change propagates
that to return values of aliasing function calls (such as `at`). One
potential issue is that developers may pass
`enableAssumeHooksFollowRulesOfReact:false` and set
`transitiveMixedData`, expecting their transitive mixed data to be
mutable. This is a bit of an edge case and already doesn't have clear
semantics.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32594).
* #32596
* #32595
* __->__ #32594
* #32593
* #32522
* #32521
2025-03-13 11:59:50 -04:00
mofeiZ
eb53139ee5 [compiler][optim] infer mixedReadOnly for numeric and computed properties (#32593)
Expand type inference to infer mixedReadOnly types for numeric and
computed property accesses.
```js
function Component({idx})
  const data = useFragment(...)
  // we want to type `posts` correctly as Array
  const posts = data.viewers[idx].posts.slice(0, 5);
  // ...
}
```
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32593).
* #32596
* #32595
* #32594
* __->__ #32593
* #32522
* #32521
2025-03-13 11:58:40 -04:00
mofeiZ
38a7600920 [compiler][optim] Add shape for Array.from (#32522)
(see title)
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32522).
* #32596
* #32595
* #32594
* #32593
* __->__ #32522
* #32521
2025-03-13 11:58:17 -04:00
mofeiZ
ed1264f077 [compiler] Patch array and argument spread mutability (#32521)
Array and argument spreads may mutate stateful iterables. Spread sites
should have `ConditionallyMutate` effects (e.g. mutate if the ValueKind
is mutable, otherwise read).

See
- [ecma spec (13.2.4.1 Runtime Semantics: ArrayAccumulation.
SpreadElement : ...
AssignmentExpression)](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-runtime-semantics-arrayaccumulation).
- [ecma spec 13.3.8.1 Runtime Semantics:
ArgumentListEvaluation](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-runtime-semantics-argumentlistevaluation)

Note that
- Object and JSX Attribute spreads do not evaluate iterables (srcs
[mozilla](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#description),
[ecma](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-runtime-semantics-propertydefinitionevaluation))
- An ideal mutability inference system could model known collections
(i.e. Arrays or Sets) as a "mutated collection of non-mutable objects"
(see `todo-granular-iterator-semantics`), but this is not what we do
today. As such, an array / argument spread will always extend the range
of built-in arrays, sets, etc
- Due to HIR limitations, call expressions with argument spreads may
cause unnecessary bailouts and/or scope merging when we know the call
itself has `freeze`, `capture`, or `read` semantics (e.g.
`useHook(...mutableValue)`)
We can deal with this by rewriting these call instructions to (1) create
an intermediate array to consume the iterator and (2) capture and spread
the array at the callsite
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32521).
* #32596
* #32595
* #32594
* #32593
* #32522
* __->__ #32521
2025-03-13 11:58:02 -04:00
409 changed files with 24320 additions and 3862 deletions

View File

@@ -331,6 +331,7 @@ module.exports = {
'packages/react-server-dom-turbopack/**/*.js',
'packages/react-server-dom-parcel/**/*.js',
'packages/react-server-dom-fb/**/*.js',
'packages/react-server-dom-unbundled/**/*.js',
'packages/react-test-renderer/**/*.js',
'packages/react-debug-tools/**/*.js',
'packages/react-devtools-extensions/**/*.js',

View File

@@ -1,15 +1,20 @@
name: (Compiler) Discord Notify
on:
pull_request_target:
pull_request:
types: [opened, ready_for_review]
paths:
- compiler/**
- .github/workflows/compiler_**.yml
permissions: {}
jobs:
check_maintainer:
uses: facebook/react/.github/workflows/shared_check_maintainer.yml@main
permissions:
# Used by check_maintainer
contents: read
with:
actor: ${{ github.event.pull_request.user.login }}
@@ -19,7 +24,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Discord Webhook Action
uses: tsickert/discord-webhook@v6.0.0
uses: tsickert/discord-webhook@86dc739f3f165f16dadc5666051c367efa1692f4
with:
webhook-url: ${{ secrets.COMPILER_DISCORD_WEBHOOK_URL }}
embed-author-name: ${{ github.event.pull_request.user.login }}

View File

@@ -8,6 +8,8 @@ on:
- compiler/**
- .github/workflows/compiler_playground.yml
permissions: {}
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.event.pull_request.number || github.run_id }}
cancel-in-progress: true
@@ -36,10 +38,23 @@ jobs:
uses: actions/cache@v4
id: node_modules
with:
path: "**/node_modules"
key: compiler-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('compiler/**/yarn.lock') }}
path: |
**/node_modules
key: compiler-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('compiler/**/yarn.lock') }}
- run: yarn install --frozen-lockfile
- name: Check Playwright version
id: playwright_version
run: echo "playwright_version=$(npm ls @playwright/test | grep @playwright | sed 's/.*@//' | head -1)" >> "$GITHUB_OUTPUT"
- name: Cache Playwright Browsers for version ${{ steps.playwright_version.outputs.playwright_version }}
id: cache_playwright_browsers
uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: playwright-browsers-v6-${{ runner.arch }}-${{ runner.os }}-${{ steps.playwright_version.outputs.playwright_version }}
- run: npx playwright install --with-deps chromium
if: steps.cache_playwright_browsers.outputs.cache-hit != 'true'
- run: npx playwright install-deps
if: steps.cache_playwright_browsers.outputs.cache-hit == 'true'
- run: CI=true yarn test
- run: ls -R test-results
if: '!cancelled()'
@@ -49,3 +64,4 @@ jobs:
with:
name: test-results
path: compiler/apps/playground/test-results
if-no-files-found: ignore

View File

@@ -20,11 +20,12 @@ on:
NPM_TOKEN:
required: true
permissions: {}
env:
TZ: /usr/share/zoneinfo/America/Los_Angeles
# https://github.com/actions/cache/blob/main/tips-and-workarounds.md#cache-segment-restore-timeout
SEGMENT_DOWNLOAD_TIMEOUT_MINS: 1
GH_TOKEN: ${{ github.token }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
defaults:
@@ -46,8 +47,9 @@ jobs:
uses: actions/cache@v4
id: node_modules
with:
path: "**/node_modules"
key: compiler-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('compiler/**/yarn.lock') }}
path: |
**/node_modules
key: compiler-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('compiler/**/yarn.lock') }}
- run: yarn install --frozen-lockfile
- name: Publish packages to npm
run: |

View File

@@ -15,6 +15,8 @@ on:
required: true
type: string
permissions: {}
env:
TZ: /usr/share/zoneinfo/America/Los_Angeles

View File

@@ -5,6 +5,8 @@ on:
# At 10 minutes past 16:00 on Mon, Tue, Wed, Thu, and Fri
- cron: 10 16 * * 1,2,3,4,5
permissions: {}
env:
TZ: /usr/share/zoneinfo/America/Los_Angeles

View File

@@ -5,6 +5,8 @@ on:
# At 10 minutes past 9:00 on Mon
- cron: 10 9 * * 1
permissions: {}
env:
TZ: /usr/share/zoneinfo/America/Los_Angeles

View File

@@ -8,6 +8,8 @@ on:
- compiler/**
- .github/workflows/compiler_typescript.yml
permissions: {}
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.event.pull_request.number || github.run_id }}
cancel-in-progress: true
@@ -46,8 +48,9 @@ jobs:
- name: Restore cached node_modules
uses: actions/cache@v4
with:
path: "**/node_modules"
key: compiler-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('compiler/**/yarn.lock') }}
path: |
**/node_modules
key: compiler-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('compiler/**/yarn.lock') }}
- run: yarn install --frozen-lockfile
- run: yarn workspace babel-plugin-react-compiler lint
@@ -66,8 +69,9 @@ jobs:
uses: actions/cache@v4
id: node_modules
with:
path: "**/node_modules"
key: compiler-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('compiler/**/yarn.lock') }}
path: |
**/node_modules
key: compiler-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('compiler/**/yarn.lock') }}
- run: yarn install --frozen-lockfile
- run: yarn workspace babel-plugin-react-compiler jest
@@ -90,8 +94,9 @@ jobs:
uses: actions/cache@v4
id: node_modules
with:
path: "**/node_modules"
key: compiler-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('compiler/**/yarn.lock') }}
path: |
**/node_modules
key: compiler-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('compiler/**/yarn.lock') }}
- run: yarn install --frozen-lockfile
- run: xvfb-run -a yarn workspace ${{ matrix.workspace_name }} test
if: runner.os == 'Linux' && matrix.workspace_name == 'react-forgive'

View File

@@ -9,6 +9,8 @@ on:
required: false
type: string
permissions: {}
env:
TZ: /usr/share/zoneinfo/America/Los_Angeles
# https://github.com/actions/cache/blob/main/tips-and-workarounds.md#cache-segment-restore-timeout
@@ -18,6 +20,9 @@ jobs:
download_build:
name: Download base build
runs-on: ubuntu-latest
permissions:
# We use github.token to download the build artifact from a previous runtime_build_and_test.yml run
actions: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
@@ -29,13 +34,13 @@ jobs:
uses: actions/cache@v4
id: node_modules
with:
path: "**/node_modules"
key: runtime-release-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'scripts/release/yarn.lock') }}
path: |
**/node_modules
key: runtime-release-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'scripts/release/yarn.lock') }}
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
- run: yarn install --frozen-lockfile
working-directory: scripts/release
- run: yarn --cwd scripts/release install --frozen-lockfile
- name: Download react-devtools artifacts for base revision
run: |
git fetch origin main
@@ -47,6 +52,7 @@ jobs:
with:
name: build
path: build
if-no-files-found: error
build_devtools_and_process_artifacts:
name: Build DevTools and process artifacts
@@ -63,8 +69,9 @@ jobs:
uses: actions/cache@v4
id: node_modules
with:
path: "**/node_modules"
key: runtime-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
path: |
**/node_modules
key: runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
@@ -83,17 +90,20 @@ jobs:
with:
name: react-devtools
path: build/devtools.tgz
if-no-files-found: error
# Simplifies getting the extension for local testing
- name: Archive chrome extension
uses: actions/upload-artifact@v4
with:
name: react-devtools-chrome-extension
path: build/devtools/chrome-extension.zip
if-no-files-found: error
- name: Archive firefox extension
uses: actions/upload-artifact@v4
with:
name: react-devtools-firefox-extension
path: build/devtools/firefox-extension.zip
if-no-files-found: error
run_devtools_tests_for_versions:
name: Run DevTools tests for versions
@@ -120,8 +130,9 @@ jobs:
uses: actions/cache@v4
id: node_modules
with:
path: "**/node_modules"
key: runtime-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
path: |
**/node_modules
key: runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
- run: yarn install --frozen-lockfile
- name: Restore all archived build artifacts
uses: actions/download-artifact@v4
@@ -154,8 +165,9 @@ jobs:
uses: actions/cache@v4
id: node_modules
with:
path: "**/node_modules"
key: runtime-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
path: |
**/node_modules
key: runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
- run: yarn install --frozen-lockfile
- name: Restore all archived build artifacts
uses: actions/download-artifact@v4
@@ -176,3 +188,4 @@ jobs:
with:
name: screenshots
path: ./tmp/screenshots
if-no-files-found: warn

View File

@@ -3,9 +3,21 @@ name: (Runtime) Build and Test
on:
push:
branches: [main]
tags:
# To get CI for backport releases.
# This will duplicate CI for releases from main which is acceptable
- "v*"
pull_request:
paths-ignore:
- compiler/**
workflow_dispatch:
inputs:
commit_sha:
required: false
type: string
default: ''
permissions: {}
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.event.pull_request.number || github.run_id }}
@@ -17,6 +29,91 @@ env:
SEGMENT_DOWNLOAD_TIMEOUT_MINS: 1
jobs:
# ----- NODE_MODULES CACHE -----
# Centralize the node_modules cache so it is saved once and each subsequent job only needs to
# restore the cache. Prevents race conditions where multiple workflows try to write to the cache.
runtime_node_modules_cache:
name: Cache Runtime node_modules
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- name: Check cache hit
uses: actions/cache/restore@v4
id: node_modules
with:
path: |
**/node_modules
key: runtime-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
lookup-only: true
- uses: actions/setup-node@v4
if: steps.node_modules.outputs.cache-hit != 'true'
with:
node-version-file: '.nvmrc'
cache: yarn
cache-dependency-path: yarn.lock
- name: Warm with old cache
if: steps.node_modules.outputs.cache-hit != 'true'
uses: actions/cache/restore@v4
with:
path: |
**/node_modules
key: runtime-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
# Don't use restore-keys here. Otherwise the cache grows indefinitely.
- run: yarn install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- name: Save cache
if: steps.node_modules.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: |
**/node_modules
key: runtime-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
runtime_compiler_node_modules_cache:
name: Cache Runtime, Compiler node_modules
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- name: Check cache hit
uses: actions/cache/restore@v4
id: node_modules
with:
path: |
**/node_modules
key: runtime-and-compiler-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'compiler/yarn.lock') }}
lookup-only: true
- uses: actions/setup-node@v4
if: steps.node_modules.outputs.cache-hit != 'true'
with:
node-version-file: '.nvmrc'
cache: yarn
cache-dependency-path: |
yarn.lock
compiler/yarn.lock
- name: Warm with old cache
if: steps.node_modules.outputs.cache-hit != 'true'
uses: actions/cache/restore@v4
with:
path: |
**/node_modules
key: runtime-and-compiler-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'compiler/yarn.lock') }}
# Don't use restore-keys here. Otherwise the cache grows indefinitely.
- run: yarn install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- run: yarn --cwd compiler install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- name: Save cache
if: steps.node_modules.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: |
**/node_modules
key: runtime-and-compiler-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'compiler/yarn.lock') }}
# ----- FLOW -----
discover_flow_inline_configs:
name: Discover flow inline configs
@@ -26,7 +123,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/github-script@v7
id: set-matrix
with:
@@ -36,7 +133,7 @@ jobs:
flow:
name: Flow check ${{ matrix.flow_inline_config_shortname }}
needs: discover_flow_inline_configs
needs: [discover_flow_inline_configs, runtime_node_modules_cache]
runs-on: ubuntu-latest
strategy:
fail-fast: false
@@ -45,45 +142,52 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: yarn
cache-dependency-path: yarn.lock
- name: Restore cached node_modules
uses: actions/cache@v4
uses: actions/cache/restore@v4
id: node_modules
with:
path: "**/node_modules"
key: runtime-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
path: |
**/node_modules
key: runtime-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
# Don't use restore-keys here. Otherwise the cache grows indefinitely.
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- run: node ./scripts/tasks/flow-ci ${{ matrix.flow_inline_config_shortname }}
# ----- FIZZ -----
check_generated_fizz_runtime:
name: Confirm generated inline Fizz runtime is up to date
needs: [runtime_node_modules_cache]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: yarn
cache-dependency-path: yarn.lock
- name: Restore cached node_modules
uses: actions/cache@v4
uses: actions/cache/restore@v4
id: node_modules
with:
path: "**/node_modules"
key: runtime-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
path: |
**/node_modules
key: runtime-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
# Don't use restore-keys here. Otherwise the cache grows indefinitely.
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- run: |
yarn generate-inline-fizz-runtime
git diff --quiet || (echo "There was a change to the Fizz runtime. Run `yarn generate-inline-fizz-runtime` and check in the result." && false)
@@ -91,30 +195,34 @@ jobs:
# ----- FEATURE FLAGS -----
flags:
name: Check flags
needs: [runtime_node_modules_cache]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: yarn
cache-dependency-path: yarn.lock
- name: Restore cached node_modules
uses: actions/cache@v4
uses: actions/cache/restore@v4
id: node_modules
with:
path: "**/node_modules"
key: runtime-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
path: |
**/node_modules
key: runtime-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- run: yarn flags
# ----- TESTS -----
test:
name: yarn test ${{ matrix.params }} (Shard ${{ matrix.shard }})
needs: [runtime_compiler_node_modules_cache]
runs-on: ubuntu-latest
strategy:
fail-fast: false
@@ -148,56 +256,102 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: yarn
cache-dependency-path: yarn.lock
cache-dependency-path: |
yarn.lock
compiler/yarn.lock
- name: Restore cached node_modules
uses: actions/cache/restore@v4
id: node_modules
with:
path: |
**/node_modules
key: runtime-and-compiler-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'compiler/yarn.lock') }}
# Don't use restore-keys here. Otherwise the cache grows indefinitely.
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- run: yarn --cwd compiler install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- run: yarn test ${{ matrix.params }} --ci --shard=${{ matrix.shard }}
# Hardcoded to improve parallelism
test-linter:
name: Test eslint-plugin-react-hooks
needs: [runtime_compiler_node_modules_cache]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: yarn
cache-dependency-path: |
yarn.lock
compiler/yarn.lock
- name: Restore cached node_modules
uses: actions/cache@v4
id: node_modules
with:
path: "**/node_modules"
key: runtime-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
- run: yarn test ${{ matrix.params }} --ci --shard=${{ matrix.shard }}
path: |
**/node_modules
key: runtime-and-compiler-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'compiler/yarn.lock') }}
- name: Install runtime dependencies
run: yarn install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- name: Install compiler dependencies
run: yarn install --frozen-lockfile
working-directory: compiler
if: steps.node_modules.outputs.cache-hit != 'true'
- run: ./scripts/react-compiler/build-compiler.sh && ./scripts/react-compiler/link-compiler.sh
- run: yarn workspace eslint-plugin-react-hooks test
# ----- BUILD -----
build_and_lint:
name: yarn build and lint
needs: [runtime_compiler_node_modules_cache]
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# yml is dumb. update the --total arg to yarn build if you change the number of workers
worker_id: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]
worker_id: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]
release_channel: [stable, experimental]
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: yarn
cache-dependency-path: yarn.lock
cache-dependency-path: |
yarn.lock
compiler/yarn.lock
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 11.0.22
- name: Restore cached node_modules
uses: actions/cache@v4
uses: actions/cache/restore@v4
id: node_modules
with:
path: "**/node_modules"
key: runtime-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
path: |
**/node_modules
key: runtime-and-compiler-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'compiler/yarn.lock') }}
# Don't use restore-keys here. Otherwise the cache grows indefinitely.
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
- run: yarn build --index=${{ matrix.worker_id }} --total=20 --r=${{ matrix.release_channel }} --ci
if: steps.node_modules.outputs.cache-hit != 'true'
- run: yarn --cwd compiler install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- run: yarn build --index=${{ matrix.worker_id }} --total=25 --r=${{ matrix.release_channel }} --ci
env:
CI: github
RELEASE_CHANNEL: ${{ matrix.release_channel }}
@@ -211,10 +365,11 @@ jobs:
with:
name: _build_${{ matrix.worker_id }}_${{ matrix.release_channel }}
path: build
if-no-files-found: error
test_build:
name: yarn test-build
needs: build_and_lint
needs: [build_and_lint, runtime_compiler_node_modules_cache]
strategy:
fail-fast: false
matrix:
@@ -249,28 +404,42 @@ jobs:
# TODO: Test more persistent configurations?
]
shard:
- 1/3
- 2/3
- 3/3
- 1/10
- 2/10
- 3/10
- 4/10
- 5/10
- 6/10
- 7/10
- 8/10
- 9/10
- 10/10
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: yarn
cache-dependency-path: yarn.lock
cache-dependency-path: |
yarn.lock
compiler/yarn.lock
- name: Restore cached node_modules
uses: actions/cache@v4
uses: actions/cache/restore@v4
id: node_modules
with:
path: "**/node_modules"
key: runtime-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
path: |
**/node_modules
key: runtime-and-compiler-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'compiler/yarn.lock') }}
# Don't use restore-keys here. Otherwise the cache grows indefinitely.
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- run: yarn --cwd compiler install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- name: Restore archived build
uses: actions/download-artifact@v4
with:
@@ -283,26 +452,29 @@ jobs:
process_artifacts_combined:
name: Process artifacts combined
needs: build_and_lint
needs: [build_and_lint, runtime_node_modules_cache]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: yarn
cache-dependency-path: yarn.lock
- name: Restore cached node_modules
uses: actions/cache@v4
uses: actions/cache/restore@v4
id: node_modules
with:
path: "**/node_modules"
key: runtime-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
path: |
**/node_modules
key: runtime-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
# Don't use restore-keys here. Otherwise the cache grows indefinitely.
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- name: Restore archived build
uses: actions/download-artifact@v4
with:
@@ -311,7 +483,7 @@ jobs:
merge-multiple: true
- name: Display structure of build
run: ls -R build
- run: echo ${{ github.sha }} >> build/COMMIT_SHA
- run: echo ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }} >> build/COMMIT_SHA
- name: Scrape warning messages
run: |
mkdir -p ./build/__test_utils__
@@ -327,29 +499,33 @@ jobs:
path: |
./build.tgz
./build2.tgz
if-no-files-found: error
check_error_codes:
name: Search build artifacts for unminified errors
needs: build_and_lint
needs: [build_and_lint, runtime_node_modules_cache]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: yarn
cache-dependency-path: yarn.lock
- name: Restore cached node_modules
uses: actions/cache@v4
uses: actions/cache/restore@v4
id: node_modules
with:
path: "**/node_modules"
key: runtime-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
path: |
**/node_modules
key: runtime-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
# Don't use restore-keys here. Otherwise the cache grows indefinitely.
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- name: Restore archived build
uses: actions/download-artifact@v4
with:
@@ -365,26 +541,29 @@ jobs:
check_release_dependencies:
name: Check release dependencies
needs: build_and_lint
needs: [build_and_lint, runtime_node_modules_cache]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: yarn
cache-dependency-path: yarn.lock
- name: Restore cached node_modules
uses: actions/cache@v4
uses: actions/cache/restore@v4
id: node_modules
with:
path: "**/node_modules"
key: runtime-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
path: |
**/node_modules
key: runtime-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
# Don't use restore-keys here. Otherwise the cache grows indefinitely.
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- name: Restore archived build
uses: actions/download-artifact@v4
with:
@@ -402,22 +581,23 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: yarn
cache-dependency-path: yarn.lock
- name: Restore cached node_modules
uses: actions/cache@v4
uses: actions/cache@v4 # note: this does not reuse centralized cache since it has unique cache key
id: node_modules
with:
path: "**/node_modules"
key: fixtures_dom-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
path: |
**/node_modules
key: fixtures_dom-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'fixtures/dom/yarn.lock') }}
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
working-directory: fixtures/dom
- run: yarn --cwd fixtures/dom install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- name: Restore archived build
uses: actions/download-artifact@v4
with:
@@ -442,7 +622,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
@@ -452,14 +632,31 @@ jobs:
# That means dependencies of the built packages are not installed.
# We need to install dependencies of the workroot to fulfill all dependency constraints
- name: Restore cached node_modules
uses: actions/cache@v4
uses: actions/cache@v4 # note: this does not reuse centralized cache since it has unique cache key
id: node_modules
with:
path: "**/node_modules"
key: fixtures_flight-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
path: |
**/node_modules
key: fixtures_flight-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'fixtures/flight/yarn.lock') }}
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- run: yarn --cwd fixtures/flight install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- name: Check Playwright version
id: playwright_version
run: echo "playwright_version=$(npm ls @playwright/test | grep @playwright | sed 's/.*@//' | head -1)" >> "$GITHUB_OUTPUT"
- name: Cache Playwright Browsers for version ${{ steps.playwright_version.outputs.playwright_version }}
id: cache_playwright_browsers
uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: playwright-browsers-v6-${{ runner.arch }}-${{ runner.os }}-${{ steps.playwright_version.outputs.playwright_version }}
- name: Playwright install deps
if: steps.cache_playwright_browsers.outputs.cache-hit != 'true'
working-directory: fixtures/flight
run: npx playwright install --with-deps chromium
- name: Restore archived build
uses: actions/download-artifact@v4
with:
@@ -468,16 +665,6 @@ jobs:
merge-multiple: true
- name: Display structure of build
run: ls -R build
- name: Install fixture dependencies
working-directory: fixtures/flight
run: |
yarn install --frozen-lockfile --cache-folder ~/.cache/yarn
if [ $? -ne 0 ]; then
yarn install --frozen-lockfile --cache-folder ~/.cache/yarn
fi
- name: Playwright install deps
working-directory: fixtures/flight
run: npx playwright install --with-deps chromium
- name: Run tests
working-directory: fixtures/flight
run: yarn test
@@ -489,16 +676,18 @@ jobs:
with:
name: flight-playwright-report
path: fixtures/flight/playwright-report
if-no-files-found: warn
- name: Archive Flight fixture artifacts
uses: actions/upload-artifact@v4
with:
name: flight-test-results
path: fixtures/flight/test-results
if-no-files-found: ignore
# ----- DEVTOOLS -----
build_devtools_and_process_artifacts:
name: Build DevTools and process artifacts
needs: build_and_lint
needs: [build_and_lint, runtime_node_modules_cache]
runs-on: ubuntu-latest
strategy:
fail-fast: false
@@ -507,21 +696,24 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: yarn
cache-dependency-path: yarn.lock
- name: Restore cached node_modules
uses: actions/cache@v4
uses: actions/cache/restore@v4
id: node_modules
with:
path: "**/node_modules"
key: runtime-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
path: |
**/node_modules
key: runtime-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
# Don't use restore-keys here. Otherwise the cache grows indefinitely.
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- name: Restore archived build
uses: actions/download-artifact@v4
with:
@@ -539,6 +731,7 @@ jobs:
with:
name: react-devtools-${{ matrix.browser }}-extension
path: build/devtools/${{ matrix.browser }}-extension.zip
if-no-files-found: error
merge_devtools_artifacts:
name: Merge DevTools artifacts
@@ -553,26 +746,29 @@ jobs:
run_devtools_e2e_tests:
name: Run DevTools e2e tests
needs: build_and_lint
needs: [build_and_lint, runtime_node_modules_cache]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: yarn
cache-dependency-path: yarn.lock
- name: Restore cached node_modules
uses: actions/cache@v4
uses: actions/cache/restore@v4
id: node_modules
with:
path: "**/node_modules"
key: runtime-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
path: |
**/node_modules
key: runtime-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
# Don't use restore-keys here. Otherwise the cache grows indefinitely.
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- name: Restore archived build
uses: actions/download-artifact@v4
with:
@@ -591,26 +787,32 @@ jobs:
if: ${{ github.event_name == 'pull_request' && github.ref_name != 'main' && github.event.pull_request.base.ref == 'main' }}
name: Run sizebot
needs: [build_and_lint]
permissions:
# We use github.token to download the build artifact from a previous runtime_build_and_test.yml run
actions: read
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: yarn
cache-dependency-path: yarn.lock
- name: Restore cached node_modules
uses: actions/cache@v4
uses: actions/cache@v4 # note: this does not reuse centralized cache since it has unique cache key
id: node_modules
with:
path: "**/node_modules"
key: runtime-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
path: |
**/node_modules
key: runtime-release-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'scripts/release/yarn.lock') }}
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
working-directory: scripts/release
if: steps.node_modules.outputs.cache-hit != 'true'
- run: yarn --cwd scripts/release install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- name: Download artifacts for base revision
run: |
GH_TOKEN=${{ github.token }} scripts/release/download-experimental-build.js --commit=$(git rev-parse ${{ github.event.pull_request.base.sha }})
@@ -625,7 +827,6 @@ jobs:
run: ls -R base-build
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
- name: Restore archived build for PR
uses: actions/download-artifact@v4
with:
@@ -638,10 +839,11 @@ jobs:
node ./scripts/print-warnings/print-warnings.js > build/__test_utils__/ReactAllWarnings.js
- name: Display structure of build for PR
run: ls -R build
- run: echo ${{ github.sha }} >> build/COMMIT_SHA
- run: echo ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }} >> build/COMMIT_SHA
- run: node ./scripts/tasks/danger
- name: Archive sizebot results
uses: actions/upload-artifact@v4
with:
name: sizebot-message
path: sizebot-message.md
if-no-files-found: ignore

View File

@@ -16,6 +16,13 @@ on:
required: true
default: false
type: boolean
dry_run:
description: Perform a dry run (run everything except push)
required: true
default: false
type: boolean
permissions: {}
env:
TZ: /usr/share/zoneinfo/America/Los_Angeles
@@ -25,6 +32,40 @@ env:
jobs:
download_artifacts:
runs-on: ubuntu-latest
permissions:
# We use github.token to download the build artifact from a previous runtime_build_and_test.yml run
actions: read
steps:
- uses: actions/checkout@v4
- name: Restore cached node_modules
uses: actions/cache@v4
id: node_modules
with:
path: |
**/node_modules
key: runtime-release-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'scripts/release/yarn.lock') }}
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- run: yarn --cwd scripts/release install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- name: Download artifacts for base revision
run: |
GH_TOKEN=${{ github.token }} scripts/release/download-experimental-build.js --commit=${{ inputs.commit_sha || github.event.workflow_run.head_sha || github.sha }}
- name: Display structure of build
run: ls -R build
- name: Archive build
uses: actions/upload-artifact@v4
with:
name: build
path: build/
if-no-files-found: error
process_artifacts:
runs-on: ubuntu-latest
needs: [download_artifacts]
outputs:
www_branch_count: ${{ steps.check_branches.outputs.www_branch_count }}
fbsource_branch_count: ${{ steps.check_branches.outputs.fbsource_branch_count }}
@@ -64,27 +105,11 @@ jobs:
run: |
echo "www_branch_count=$(git ls-remote --heads origin "refs/heads/meta-www" | wc -l)" >> "$GITHUB_OUTPUT"
echo "fbsource_branch_count=$(git ls-remote --heads origin "refs/heads/meta-fbsource" | wc -l)" >> "$GITHUB_OUTPUT"
- uses: actions/setup-node@v4
- name: Restore downloaded build
uses: actions/download-artifact@v4
with:
node-version-file: '.nvmrc'
cache: yarn
cache-dependency-path: yarn.lock
- name: Restore cached node_modules
uses: actions/cache@v4
id: node_modules
with:
path: "**/node_modules"
key: runtime-release-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'scripts/release/yarn.lock') }}
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
name: yarn install (react)
- run: yarn install --frozen-lockfile
name: yarn install (scripts/release)
working-directory: scripts/release
- name: Download artifacts for base revision
run: |
GH_TOKEN=${{ github.token }} scripts/release/download-experimental-build.js --commit=${{ inputs.commit_sha || github.event.workflow_run.head_sha || github.sha }}
name: build
path: build
- name: Display structure of build
run: ls -R build
- name: Strip @license from eslint plugin and react-refresh
@@ -107,9 +132,10 @@ jobs:
mkdir ./compiled/facebook-www/__test_utils__
mv build/__test_utils__/ReactAllWarnings.js ./compiled/facebook-www/__test_utils__/ReactAllWarnings.js
# Move eslint-plugin-react-hooks into facebook-www
# Move eslint-plugin-react-hooks into eslint-plugin-react-hooks
mkdir ./compiled/eslint-plugin-react-hooks
mv build/oss-experimental/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js \
./compiled/facebook-www/eslint-plugin-react-hooks.js
./compiled/eslint-plugin-react-hooks/index.js
# Move unstable_server-external-runtime.js into facebook-www
mv build/oss-experimental/react-dom/unstable_server-external-runtime.js \
@@ -147,9 +173,9 @@ jobs:
ls -R ./compiled-rn
- name: Add REVISION files
run: |
echo ${{ github.sha }} >> ./compiled/facebook-www/REVISION
echo ${{ inputs.commit_sha || github.event.workflow_run.head_sha || github.sha }} >> ./compiled/facebook-www/REVISION
cp ./compiled/facebook-www/REVISION ./compiled/facebook-www/REVISION_TRANSFORMS
echo ${{ github.sha}} >> ./compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION
echo ${{ inputs.commit_sha || github.event.workflow_run.head_sha || github.sha }} >> ./compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION
- name: "Get current version string"
id: get_current_version
run: |
@@ -166,15 +192,20 @@ jobs:
with:
name: compiled
path: compiled/
if-no-files-found: error
- uses: actions/upload-artifact@v4
with:
name: compiled-rn
path: compiled-rn/
if-no-files-found: error
commit_www_artifacts:
needs: download_artifacts
if: inputs.force == true || (github.ref == 'refs/heads/main' && needs.download_artifacts.outputs.www_branch_count == '0')
needs: [download_artifacts, process_artifacts]
if: inputs.force == true || (github.ref == 'refs/heads/main' && needs.process_artifacts.outputs.www_branch_count == '0')
runs-on: ubuntu-latest
permissions:
# Used to push a commit to builds/facebook-www
contents: write
steps:
- uses: actions/checkout@v4
with:
@@ -186,12 +217,12 @@ jobs:
name: compiled
path: compiled/
- name: Revert version changes
if: needs.download_artifacts.outputs.last_version_classic != '' && needs.download_artifacts.outputs.last_version_modern != ''
if: needs.process_artifacts.outputs.last_version_classic != '' && needs.process_artifacts.outputs.last_version_modern != ''
env:
CURRENT_VERSION_CLASSIC: ${{ needs.download_artifacts.outputs.current_version_classic }}
CURRENT_VERSION_MODERN: ${{ needs.download_artifacts.outputs.current_version_modern }}
LAST_VERSION_CLASSIC: ${{ needs.download_artifacts.outputs.last_version_classic }}
LAST_VERSION_MODERN: ${{ needs.download_artifacts.outputs.last_version_modern }}
CURRENT_VERSION_CLASSIC: ${{ needs.process_artifacts.outputs.current_version_classic }}
CURRENT_VERSION_MODERN: ${{ needs.process_artifacts.outputs.current_version_modern }}
LAST_VERSION_CLASSIC: ${{ needs.process_artifacts.outputs.last_version_classic }}
LAST_VERSION_MODERN: ${{ needs.process_artifacts.outputs.last_version_modern }}
run: |
echo "Reverting $CURRENT_VERSION_CLASSIC to $LAST_VERSION_CLASSIC"
grep -rl "$CURRENT_VERSION_CLASSIC" ./compiled || echo "No files found with $CURRENT_VERSION_CLASSIC"
@@ -221,12 +252,12 @@ jobs:
echo "should_commit=false" >> "$GITHUB_OUTPUT"
fi
- name: Re-apply version changes
if: inputs.force == true || (steps.check_should_commit.outputs.should_commit == 'true' && needs.download_artifacts.outputs.last_version_classic != '' && needs.download_artifacts.outputs.last_version_modern != '')
if: inputs.force == true || (steps.check_should_commit.outputs.should_commit == 'true' && needs.process_artifacts.outputs.last_version_classic != '' && needs.process_artifacts.outputs.last_version_modern != '')
env:
CURRENT_VERSION_CLASSIC: ${{ needs.download_artifacts.outputs.current_version_classic }}
CURRENT_VERSION_MODERN: ${{ needs.download_artifacts.outputs.current_version_modern }}
LAST_VERSION_CLASSIC: ${{ needs.download_artifacts.outputs.last_version_classic }}
LAST_VERSION_MODERN: ${{ needs.download_artifacts.outputs.last_version_modern }}
CURRENT_VERSION_CLASSIC: ${{ needs.process_artifacts.outputs.current_version_classic }}
CURRENT_VERSION_MODERN: ${{ needs.process_artifacts.outputs.current_version_modern }}
LAST_VERSION_CLASSIC: ${{ needs.process_artifacts.outputs.last_version_classic }}
LAST_VERSION_MODERN: ${{ needs.process_artifacts.outputs.last_version_modern }}
run: |
echo "Re-applying $LAST_VERSION_CLASSIC to $CURRENT_VERSION_CLASSIC"
grep -rl "$LAST_VERSION_CLASSIC" ./compiled || echo "No files found with $LAST_VERSION_CLASSIC"
@@ -240,24 +271,31 @@ jobs:
- name: Will commit these changes
if: inputs.force == true || steps.check_should_commit.outputs.should_commit == 'true'
run: |
echo ":"
git status -u
git add .
git status
- name: Check commit message
if: inputs.dry_run
run: |
git fetch origin --quiet
git show ${{ inputs.commit_sha || github.event.workflow_run.head_sha || github.sha }} --no-patch --pretty=format:"%B"
- name: Commit changes to branch
if: inputs.force == true || steps.check_should_commit.outputs.should_commit == 'true'
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: |
${{ github.event.workflow_run.head_commit.message || format('Manual build of {0}', github.event.workflow_run.head_sha || github.sha) }}
run: |
git config --global user.email "${{ format('{0}@users.noreply.github.com', github.triggering_actor) }}"
git config --global user.name "${{ github.triggering_actor }}"
DiffTrain build for [${{ github.event.workflow_run.head_sha || github.sha }}](https://github.com/facebook/react/commit/${{ github.event.workflow_run.head_sha || github.sha }})
branch: builds/facebook-www
commit_user_name: ${{ github.triggering_actor }}
commit_user_email: ${{ format('{0}@users.noreply.github.com', github.triggering_actor) }}
create_branch: true
git fetch origin --quiet
git commit -m "$(git show ${{ inputs.commit_sha || github.event.workflow_run.head_sha || github.sha }} --no-patch --pretty=format:'%B%n%nDiffTrain build for [${{ inputs.commit_sha || github.event.workflow_run.head_sha || github.sha }}](https://github.com/facebook/react/commit/${{ inputs.commit_sha || github.event.workflow_run.head_sha || github.sha}})')" || echo "No changes to commit"
- name: Push changes to branch
if: inputs.dry_run == false && (inputs.force == true || steps.check_should_commit.outputs.should_commit == 'true')
run: git push
commit_fbsource_artifacts:
needs: download_artifacts
if: inputs.force == true || (github.ref == 'refs/heads/main' && needs.download_artifacts.outputs.fbsource_branch_count == '0')
needs: [download_artifacts, process_artifacts]
permissions:
# Used to push a commit to builds/facebook-fbsource
contents: write
if: inputs.force == true || (github.ref == 'refs/heads/main' && needs.process_artifacts.outputs.fbsource_branch_count == '0')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@@ -270,10 +308,10 @@ jobs:
name: compiled-rn
path: compiled-rn/
- name: Revert version changes
if: needs.download_artifacts.outputs.last_version_rn != ''
if: needs.process_artifacts.outputs.last_version_rn != ''
env:
CURRENT_VERSION: ${{ needs.download_artifacts.outputs.current_version_rn }}
LAST_VERSION: ${{ needs.download_artifacts.outputs.last_version_rn }}
CURRENT_VERSION: ${{ needs.process_artifacts.outputs.current_version_rn }}
LAST_VERSION: ${{ needs.process_artifacts.outputs.last_version_rn }}
run: |
echo "Reverting $CURRENT_VERSION to $LAST_VERSION"
grep -rl "$CURRENT_VERSION" ./compiled-rn || echo "No files found with $CURRENT_VERSION"
@@ -299,10 +337,10 @@ jobs:
echo "should_commit=false" >> "$GITHUB_OUTPUT"
fi
- name: Re-apply version changes
if: inputs.force == true || (steps.check_should_commit.outputs.should_commit == 'true' && needs.download_artifacts.outputs.last_version_rn != '')
if: inputs.force == true || (steps.check_should_commit.outputs.should_commit == 'true' && needs.process_artifacts.outputs.last_version_rn != '')
env:
CURRENT_VERSION: ${{ needs.download_artifacts.outputs.current_version_rn }}
LAST_VERSION: ${{ needs.download_artifacts.outputs.last_version_rn }}
CURRENT_VERSION: ${{ needs.process_artifacts.outputs.current_version_rn }}
LAST_VERSION: ${{ needs.process_artifacts.outputs.last_version_rn }}
run: |
echo "Re-applying $LAST_VERSION to $CURRENT_VERSION"
grep -rl "$LAST_VERSION" ./compiled-rn || echo "No files found with $LAST_VERSION"
@@ -409,15 +447,19 @@ jobs:
run: |
git add .
git status
- name: Check commit message
if: inputs.dry_run
run: |
git fetch origin --quiet
git show ${{ inputs.commit_sha || github.event.workflow_run.head_sha || github.sha }} --no-patch --pretty=format:"%B"
- name: Commit changes to branch
if: inputs.force == true || steps.check_should_commit.outputs.should_commit == 'true'
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: |
${{ github.event.workflow_run.head_commit.message || format('Manual build of {0}', github.event.workflow_run.head_sha || github.sha) }}
run: |
git config --global user.email "${{ format('{0}@users.noreply.github.com', github.triggering_actor) }}"
git config --global user.name "${{ github.triggering_actor }}"
DiffTrain build for [${{ github.event.workflow_run.head_sha || github.sha }}](https://github.com/facebook/react/commit/${{ github.event.workflow_run.head_sha || github.sha }})
branch: builds/facebook-fbsource
commit_user_name: ${{ github.triggering_actor }}
commit_user_email: ${{ format('{0}@users.noreply.github.com', github.triggering_actor) }}
create_branch: true
git fetch origin --quiet
git commit -m "$(git show ${{ inputs.commit_sha || github.event.workflow_run.head_sha || github.sha }} --no-patch --pretty=format:'%B%n%nDiffTrain build for [${{ inputs.commit_sha || github.event.workflow_run.head_sha || github.sha }}](https://github.com/facebook/react/commit/${{ inputs.commit_sha || github.event.workflow_run.head_sha || github.sha}})')" || echo "No changes to commit"
- name: Push changes to branch
if: inputs.dry_run == false && (inputs.force == true || steps.check_should_commit.outputs.should_commit == 'true')
run: git push

View File

@@ -1,15 +1,20 @@
name: (Runtime) Discord Notify
on:
pull_request_target:
pull_request:
types: [opened, ready_for_review]
paths-ignore:
- compiler/**
- .github/workflows/compiler_**.yml
permissions: {}
jobs:
check_maintainer:
uses: facebook/react/.github/workflows/shared_check_maintainer.yml@main
permissions:
# Used by check_maintainer
contents: read
with:
actor: ${{ github.event.pull_request.user.login }}
@@ -19,7 +24,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Discord Webhook Action
uses: tsickert/discord-webhook@v6.0.0
uses: tsickert/discord-webhook@86dc739f3f165f16dadc5666051c367efa1692f4
with:
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
embed-author-name: ${{ github.event.pull_request.user.login }}

View File

@@ -7,6 +7,8 @@ on:
paths-ignore:
- compiler/**
permissions: {}
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.event.pull_request.number || github.run_id }}
cancel-in-progress: true
@@ -35,16 +37,20 @@ jobs:
with:
node-version-file: '.nvmrc'
cache: yarn
cache-dependency-path: yarn.lock
cache-dependency-path: |
yarn.lock
compiler/yarn.lock
- name: Restore cached node_modules
uses: actions/cache@v4
id: node_modules
with:
path: "node_modules"
key: runtime-eslint_e2e-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
path: |
**/node_modules
key: runtime-and-compiler-eslint_e2e-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'compiler/yarn.lock') }}
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
- run: yarn --cwd compiler install --frozen-lockfile
- name: Build plugin
working-directory: fixtures/eslint-v${{ matrix.eslint_major }}
run: node build.mjs

View File

@@ -8,6 +8,8 @@ on:
- main
workflow_dispatch:
permissions: {}
env:
TZ: /usr/share/zoneinfo/America/Los_Angeles

View File

@@ -17,11 +17,12 @@ on:
NPM_TOKEN:
required: true
permissions: {}
env:
TZ: /usr/share/zoneinfo/America/Los_Angeles
# https://github.com/actions/cache/blob/main/tips-and-workarounds.md#cache-segment-restore-timeout
SEGMENT_DOWNLOAD_TIMEOUT_MINS: 1
GH_TOKEN: ${{ github.token }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
jobs:
@@ -39,13 +40,13 @@ jobs:
uses: actions/cache@v4
id: node_modules
with:
path: "**/node_modules"
key: runtime-release-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'scripts/release/yarn.lock') }}
path: |
**/node_modules
key: runtime-release-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'scripts/release/yarn.lock') }}
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
- run: yarn install --frozen-lockfile
working-directory: scripts/release
- run: yarn --cwd scripts/release install --frozen-lockfile
- run: |
scripts/release/prepare-release-from-ci.js --skipTests -r ${{ inputs.release_channel }} --commit=${{ inputs.commit_sha }}
cp ./scripts/release/ci-npmrc ~/.npmrc

View File

@@ -6,6 +6,8 @@ on:
prerelease_commit_sha:
required: true
permissions: {}
env:
TZ: /usr/share/zoneinfo/America/Los_Angeles

View File

@@ -5,6 +5,8 @@ on:
# At 10 minutes past 16:00 on Mon, Tue, Wed, Thu, and Fri
- cron: 10 16 * * 1,2,3,4,5
permissions: {}
env:
TZ: /usr/share/zoneinfo/America/Los_Angeles

View File

@@ -31,11 +31,12 @@ on:
type: boolean
default: false
permissions: {}
env:
TZ: /usr/share/zoneinfo/America/Los_Angeles
# https://github.com/actions/cache/blob/main/tips-and-workarounds.md#cache-segment-restore-timeout
SEGMENT_DOWNLOAD_TIMEOUT_MINS: 1
GH_TOKEN: ${{ github.token }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
jobs:
@@ -44,7 +45,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Discord Webhook Action
uses: tsickert/discord-webhook@v6.0.0
uses: tsickert/discord-webhook@86dc739f3f165f16dadc5666051c367efa1692f4
with:
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
embed-author-name: ${{ github.event.sender.login }}
@@ -71,13 +72,13 @@ jobs:
uses: actions/cache@v4
id: node_modules
with:
path: "**/node_modules"
key: runtime-release-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'scripts/release/yarn.lock') }}
path: |
**/node_modules
key: runtime-release-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'scripts/release/yarn.lock') }}
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
- run: yarn install --frozen-lockfile
working-directory: scripts/release
- run: yarn --cwd scripts/release install --frozen-lockfile
- run: cp ./scripts/release/ci-npmrc ~/.npmrc
- if: '${{ inputs.only_packages }}'
name: 'Prepare ${{ inputs.only_packages }} from NPM'

View File

@@ -14,6 +14,8 @@ on:
is_core_team:
value: ${{ jobs.check_maintainer.outputs.is_core_team }}
permissions: {}
env:
TZ: /usr/share/zoneinfo/America/Los_Angeles
# https://github.com/actions/cache/blob/main/tips-and-workarounds.md#cache-segment-restore-timeout
@@ -22,6 +24,9 @@ env:
jobs:
check_maintainer:
runs-on: ubuntu-latest
permissions:
# We fetch the contents of the MAINTAINERS file
contents: read
outputs:
is_core_team: ${{ steps.check_if_actor_is_maintainer.outputs.result }}
steps:

View File

@@ -0,0 +1,41 @@
# https://github.com/actions/cache/blob/main/tips-and-workarounds.md#force-deletion-of-caches-overriding-default-cache-eviction-policy
name: (Shared) Cleanup Merged Branch Caches
on:
pull_request:
types:
- closed
workflow_dispatch:
inputs:
pr_number:
required: true
type: string
permissions: {}
jobs:
cleanup:
runs-on: ubuntu-latest
permissions:
# `actions:write` permission is required to delete caches
# See also: https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#delete-a-github-actions-cache-for-a-repository-using-a-cache-id
actions: write
contents: read
steps:
- name: Cleanup
run: |
echo "Fetching list of cache key"
cacheKeysForPR=$(gh cache list --ref $BRANCH --limit 100 --json id --jq '.[].id')
## Setting this to not fail the workflow while deleting cache keys.
set +e
for cacheKey in $cacheKeysForPR
do
gh cache delete $cacheKey
echo "Deleting $cacheKey"
done
echo "Done"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
BRANCH: refs/pull/${{ inputs.pr_number || github.event.pull_request.number }}/merge

View File

@@ -0,0 +1,35 @@
# https://github.com/actions/cache/blob/main/tips-and-workarounds.md#force-deletion-of-caches-overriding-default-cache-eviction-policy
name: (Shared) Cleanup Stale Branch Caches
on:
schedule:
- cron: 0 0 * * *
workflow_dispatch:
permissions: {}
jobs:
cleanup:
runs-on: ubuntu-latest
permissions:
# `actions:write` permission is required to delete caches
# See also: https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#delete-a-github-actions-cache-for-a-repository-using-a-cache-id
actions: write
contents: read
steps:
- name: Cleanup
run: |
echo "Fetching list of cache keys"
cacheKeysForPR=$(gh cache list --limit 100 --json id,ref --jq '.[] | select(.ref != "refs/heads/main") | .id')
## Setting this to not fail the workflow while deleting cache keys.
set +e
for cacheKey in $cacheKeysForPR
do
gh cache delete $cacheKey
echo "Deleting $cacheKey"
done
echo "Done"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}

View File

@@ -5,6 +5,8 @@ on:
branches:
- 'builds/facebook-**'
permissions: {}
env:
TZ: /usr/share/zoneinfo/America/Los_Angeles
# https://github.com/actions/cache/blob/main/tips-and-workarounds.md#cache-segment-restore-timeout
@@ -13,6 +15,9 @@ env:
jobs:
close_pr:
runs-on: ubuntu-latest
permissions:
# Used to create a review and close PRs
pull-requests: write
steps:
- name: Close PR
uses: actions/github-script@v7

View File

@@ -1,7 +1,9 @@
name: (Shared) Label Core Team PRs
on:
pull_request_target:
pull_request:
permissions: {}
env:
TZ: /usr/share/zoneinfo/America/Los_Angeles
@@ -11,6 +13,9 @@ env:
jobs:
check_maintainer:
uses: facebook/react/.github/workflows/shared_check_maintainer.yml@main
permissions:
# Used by check_maintainer
contents: read
with:
actor: ${{ github.event.pull_request.user.login }}
@@ -18,6 +23,11 @@ jobs:
if: ${{ needs.check_maintainer.outputs.is_core_team == 'true' }}
runs-on: ubuntu-latest
needs: check_maintainer
permissions:
# Used to add labels on issues
issues: write
# Used to add labels on PRs
pull-requests: write
steps:
- name: Label PR as React Core Team
uses: actions/github-script@v7

View File

@@ -5,6 +5,8 @@ on:
branches: [main]
pull_request:
permissions: {}
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.event.pull_request.number || github.run_id }}
cancel-in-progress: true
@@ -28,8 +30,9 @@ jobs:
- name: Restore cached node_modules
uses: actions/cache@v4
with:
path: "**/node_modules"
key: shared-lint-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}
path: |
**/node_modules
key: shared-lint-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
@@ -48,8 +51,9 @@ jobs:
- name: Restore cached node_modules
uses: actions/cache@v4
with:
path: "**/node_modules"
key: shared-lint-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}
path: |
**/node_modules
key: shared-lint-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
@@ -68,8 +72,9 @@ jobs:
- name: Restore cached node_modules
uses: actions/cache@v4
with:
path: "**/node_modules"
key: shared-lint-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}
path: |
**/node_modules
key: shared-lint-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
@@ -88,8 +93,9 @@ jobs:
- name: Restore cached node_modules
uses: actions/cache@v4
with:
path: "**/node_modules"
key: shared-lint-node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}
path: |
**/node_modules
key: shared-lint-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile

View File

@@ -6,6 +6,8 @@ on:
- cron: '0 * * * *'
workflow_dispatch:
permissions: {}
env:
TZ: /usr/share/zoneinfo/America/Los_Angeles

View File

@@ -7,18 +7,18 @@
//
// The @latest channel uses the version as-is, e.g.:
//
// 19.1.0
// 19.1.6
//
// The @canary channel appends additional information, with the scheme
// <version>-<label>-<commit_sha>, e.g.:
//
// 19.1.0-canary-a1c2d3e4
// 19.1.6-canary-a1c2d3e4
//
// The @experimental channel doesn't include a version, only a date and a sha, e.g.:
//
// 0.0.0-experimental-241c4467e-20200129
const ReactVersion = '19.1.0';
const ReactVersion = '19.1.6';
// The label used by the @canary channel. Represents the upcoming release's
// stability. Most of the time, this will be "canary", but we may temporarily
@@ -34,7 +34,7 @@ const rcNumber = 0;
const stablePackages = {
'eslint-plugin-react-hooks': '5.2.0',
'jest-react': '0.17.0',
'jest-react': '0.16.0',
react: ReactVersion,
'react-art': ReactVersion,
'react-dom': ReactVersion,

View File

@@ -4,8 +4,7 @@ module.exports = {
plugins: [
'@babel/plugin-syntax-jsx',
'@babel/plugin-transform-flow-strip-types',
['@babel/plugin-transform-class-properties', {loose: true}],
'@babel/plugin-transform-classes',
['@babel/plugin-proposal-class-properties', {loose: true}],
'syntax-trailing-function-commas',
[
'@babel/plugin-proposal-object-rest-spread',

View File

@@ -7,7 +7,4 @@
const makeE2EConfig = require('../jest/makeE2EConfig');
const config = makeE2EConfig('e2e with forget', true);
config.setupFilesAfterEnv = ['<rootDir>/../scripts/jest/setupEnvE2E.js'];
module.exports = config;
module.exports = makeE2EConfig('e2e with forget', true);

View File

@@ -5,19 +5,16 @@
* LICENSE file in the root directory of this source tree.
*/
import {jsx} from '@babel/plugin-syntax-jsx';
import babelJest from 'babel-jest';
import {compile} from 'babel-plugin-react-compiler';
import {
validateEnvironmentConfig,
EnvironmentConfig,
} from 'babel-plugin-react-compiler';
import {execSync} from 'child_process';
import type {NodePath, Visitor} from '@babel/traverse';
import type {CallExpression, FunctionDeclaration} from '@babel/types';
import * as t from '@babel/types';
import {
EnvironmentConfig,
validateEnvironmentConfig,
} from 'babel-plugin-react-compiler';
import {basename} from 'path';
import type {CallExpression} from '@babel/types';
import BabelPluginReactCompiler from 'babel-plugin-react-compiler';
/**
* -- IMPORTANT --
@@ -28,10 +25,19 @@ import {basename} from 'path';
const e2eTransformerCacheKey = 1;
const forgetOptions: EnvironmentConfig = validateEnvironmentConfig({
enableAssumeHooksFollowRulesOfReact: true,
enableFunctionOutlining: false,
});
const debugMode = process.env['DEBUG_FORGET_COMPILER'] != null;
const compilerCacheKey = execSync(
'yarn --silent --cwd ../.. hash packages/babel-plugin-react-compiler/dist',
)
.toString()
.trim();
if (debugMode) {
console.log('cachebreaker', compilerCacheKey);
}
module.exports = (useForget: boolean) => {
function createTransformer() {
return babelJest.createTransformer({
@@ -42,15 +48,14 @@ module.exports = (useForget: boolean) => {
plugins: [
useForget
? [
ReactForgetFunctionTransform,
BabelPluginReactCompiler,
{
environment: forgetOptions,
/*
* Jest hashes the babel config as a cache breaker.
* (see https://github.com/jestjs/jest/blob/v29.6.2/packages/babel-jest/src/index.ts#L84)
*/
compilerCacheKey: execSync(
'yarn --silent --cwd ../.. hash packages/babel-plugin-react-compiler/dist',
).toString(),
compilerCacheKey,
transformOptionsCacheKey: forgetOptions,
e2eTransformerCacheKey,
},
@@ -105,103 +110,3 @@ module.exports = (useForget: boolean) => {
createTransformer,
};
};
// Mostly copied from react/scripts/babel/transform-forget.js
function isReactComponentLike(fn: NodePath<FunctionDeclaration>): boolean {
let isReactComponent = false;
let hasNoUseForgetDirective = false;
/*
* React components start with an upper case letter,
* React hooks start with `use`
*/
if (
fn.node.id == null ||
(fn.node.id.name[0].toUpperCase() !== fn.node.id.name[0] &&
!/^use[A-Z0-9]/.test(fn.node.id.name))
) {
return false;
}
fn.traverse({
DirectiveLiteral(path) {
if (path.node.value === 'use no forget') {
hasNoUseForgetDirective = true;
}
},
JSX(path) {
// Is there is a JSX node created in the current function context?
if (path.scope.getFunctionParent()?.path.node === fn.node) {
isReactComponent = true;
}
},
CallExpression(path) {
// Is there hook usage?
if (
path.node.callee.type === 'Identifier' &&
!/^use[A-Z0-9]/.test(path.node.callee.name)
) {
isReactComponent = true;
}
},
});
if (hasNoUseForgetDirective) {
return false;
}
return isReactComponent;
}
function ReactForgetFunctionTransform() {
const compiledFns = new Set();
const visitor = {
FunctionDeclaration(fn: NodePath<FunctionDeclaration>, state: any): void {
if (compiledFns.has(fn.node)) {
return;
}
if (!isReactComponentLike(fn)) {
return;
}
if (debugMode) {
const filename = basename(state.file.opts.filename);
if (fn.node.loc && fn.node.id) {
console.log(
` Compiling ${filename}:${fn.node.loc.start.line}:${fn.node.loc.start.column} ${fn.node.id.name}`,
);
} else {
console.log(` Compiling ${filename} ${fn.node.id?.name}`);
}
}
const compiled = compile(
fn,
forgetOptions,
'Other',
'_c',
null,
null,
null,
);
compiledFns.add(compiled);
const fun = t.functionDeclaration(
compiled.id,
compiled.params,
compiled.body,
compiled.generator,
compiled.async,
);
fn.replaceWith(fun);
fn.skip();
},
};
return {
name: 'react-forget-e2e',
inherits: jsx,
visitor,
};
}

View File

@@ -1,16 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
const ReactCompilerRuntime = require('react/compiler-runtime');
/*
* Our e2e babel transform currently only compiles functions, not programs.
* As a result, our e2e transpiled code does not contain an import for the
* memo cache function. As a temporary hack, we add a `_c` global, which is
* the name that is used for the import by default.
*/
globalThis._c = ReactCompilerRuntime.c;

View File

@@ -11,6 +11,7 @@ import {
injectReanimatedFlag,
pipelineUsesReanimatedPlugin,
} from '../Entrypoint/Reanimated';
import validateNoUntransformedReferences from '../Entrypoint/ValidateNoUntransformedReferences';
const ENABLE_REACT_COMPILER_TIMINGS =
process.env['ENABLE_REACT_COMPILER_TIMINGS'] === '1';
@@ -61,12 +62,19 @@ export default function BabelPluginReactCompiler(
},
};
}
compileProgram(prog, {
const result = compileProgram(prog, {
opts,
filename: pass.filename ?? null,
comments: pass.file.ast.comments ?? [],
code: pass.file.code,
});
validateNoUntransformedReferences(
prog,
pass.filename ?? null,
opts.logger,
opts.environment,
result?.retryErrors ?? [],
);
if (ENABLE_REACT_COMPILER_TIMINGS === true) {
performance.mark(`${filename}:end`, {
detail: 'BabelPlugin:Program:end',

View File

@@ -6,6 +6,7 @@
*/
import type {SourceLocation} from './HIR';
import {Err, Ok, Result} from './Utils/Result';
import {assertExhaustive} from './Utils/utils';
export enum ErrorSeverity {
@@ -224,6 +225,10 @@ export class CompilerError extends Error {
return this.details.length > 0;
}
asResult(): Result<void, CompilerError> {
return this.hasErrors() ? Err(this) : Ok(undefined);
}
/*
* An error is critical if it means the compiler has entered into a broken state and cannot
* continue safely. Other expected errors such as Todos mean that we can skip over that component

View File

@@ -8,7 +8,119 @@
import {NodePath} from '@babel/core';
import * as t from '@babel/types';
import {PluginOptions} from './Options';
import {CompilerError} from '../CompilerError';
/**
* Gating rewrite for function declarations which are referenced before their
* declaration site.
*
* ```js
* // original
* export default React.memo(Foo);
* function Foo() { ... }
*
* // React compiler optimized + gated
* import {gating} from 'myGating';
* export default React.memo(Foo);
* const gating_result = gating(); <- inserted
* function Foo_optimized() {} <- inserted
* function Foo_unoptimized() {} <- renamed from Foo
* function Foo() { <- inserted function, which can be hoisted by JS engines
* if (gating_result) return Foo_optimized();
* else return Foo_unoptimized();
* }
* ```
*/
function insertAdditionalFunctionDeclaration(
fnPath: NodePath<t.FunctionDeclaration>,
compiled: t.FunctionDeclaration,
gating: NonNullable<PluginOptions['gating']>,
): void {
const originalFnName = fnPath.node.id;
const originalFnParams = fnPath.node.params;
const compiledParams = fnPath.node.params;
/**
* Note that other than `export default function() {}`, all other function
* declarations must have a binding identifier. Since default exports cannot
* be referenced, it's safe to assume that all function declarations passed
* here will have an identifier.
* https://tc39.es/ecma262/multipage/ecmascript-language-functions-and-classes.html#sec-function-definitions
*/
CompilerError.invariant(originalFnName != null && compiled.id != null, {
reason:
'Expected function declarations that are referenced elsewhere to have a named identifier',
loc: fnPath.node.loc ?? null,
});
CompilerError.invariant(originalFnParams.length === compiledParams.length, {
reason:
'Expected React Compiler optimized function declarations to have the same number of parameters as source',
loc: fnPath.node.loc ?? null,
});
const gatingCondition = fnPath.scope.generateUidIdentifier(
`${gating.importSpecifierName}_result`,
);
const unoptimizedFnName = fnPath.scope.generateUidIdentifier(
`${originalFnName.name}_unoptimized`,
);
const optimizedFnName = fnPath.scope.generateUidIdentifier(
`${originalFnName.name}_optimized`,
);
/**
* Step 1: rename existing functions
*/
compiled.id.name = optimizedFnName.name;
fnPath.get('id').replaceInline(unoptimizedFnName);
/**
* Step 2: insert new function declaration
*/
const newParams: Array<t.Identifier | t.RestElement> = [];
const genNewArgs: Array<() => t.Identifier | t.SpreadElement> = [];
for (let i = 0; i < originalFnParams.length; i++) {
const argName = `arg${i}`;
if (originalFnParams[i].type === 'RestElement') {
newParams.push(t.restElement(t.identifier(argName)));
genNewArgs.push(() => t.spreadElement(t.identifier(argName)));
} else {
newParams.push(t.identifier(argName));
genNewArgs.push(() => t.identifier(argName));
}
}
// insertAfter called in reverse order of how nodes should appear in program
fnPath.insertAfter(
t.functionDeclaration(
originalFnName,
newParams,
t.blockStatement([
t.ifStatement(
gatingCondition,
t.returnStatement(
t.callExpression(
compiled.id,
genNewArgs.map(fn => fn()),
),
),
t.returnStatement(
t.callExpression(
unoptimizedFnName,
genNewArgs.map(fn => fn()),
),
),
),
]),
),
);
fnPath.insertBefore(
t.variableDeclaration('const', [
t.variableDeclarator(
gatingCondition,
t.callExpression(t.identifier(gating.importSpecifierName), []),
),
]),
);
fnPath.insertBefore(compiled);
}
export function insertGatedFunctionDeclaration(
fnPath: NodePath<
t.FunctionDeclaration | t.ArrowFunctionExpression | t.FunctionExpression
@@ -18,47 +130,57 @@ export function insertGatedFunctionDeclaration(
| t.ArrowFunctionExpression
| t.FunctionExpression,
gating: NonNullable<PluginOptions['gating']>,
referencedBeforeDeclaration: boolean,
): void {
const gatingExpression = t.conditionalExpression(
t.callExpression(t.identifier(gating.importSpecifierName), []),
buildFunctionExpression(compiled),
buildFunctionExpression(fnPath.node),
);
/*
* Convert function declarations to named variables *unless* this is an
* `export default function ...` since `export default const ...` is
* not supported. For that case we fall through to replacing w the raw
* conditional expression
*/
if (
fnPath.parentPath.node.type !== 'ExportDefaultDeclaration' &&
fnPath.node.type === 'FunctionDeclaration' &&
fnPath.node.id != null
) {
fnPath.replaceWith(
t.variableDeclaration('const', [
t.variableDeclarator(fnPath.node.id, gatingExpression),
]),
);
} else if (
fnPath.parentPath.node.type === 'ExportDefaultDeclaration' &&
fnPath.node.type !== 'ArrowFunctionExpression' &&
fnPath.node.id != null
) {
fnPath.insertAfter(
t.exportDefaultDeclaration(t.identifier(fnPath.node.id.name)),
);
fnPath.parentPath.replaceWith(
t.variableDeclaration('const', [
t.variableDeclarator(
t.identifier(fnPath.node.id.name),
gatingExpression,
),
]),
);
if (referencedBeforeDeclaration && fnPath.isFunctionDeclaration()) {
CompilerError.invariant(compiled.type === 'FunctionDeclaration', {
reason: 'Expected compiled node type to match input type',
description: `Got ${compiled.type} but expected FunctionDeclaration`,
loc: fnPath.node.loc ?? null,
});
insertAdditionalFunctionDeclaration(fnPath, compiled, gating);
} else {
fnPath.replaceWith(gatingExpression);
const gatingExpression = t.conditionalExpression(
t.callExpression(t.identifier(gating.importSpecifierName), []),
buildFunctionExpression(compiled),
buildFunctionExpression(fnPath.node),
);
/*
* Convert function declarations to named variables *unless* this is an
* `export default function ...` since `export default const ...` is
* not supported. For that case we fall through to replacing w the raw
* conditional expression
*/
if (
fnPath.parentPath.node.type !== 'ExportDefaultDeclaration' &&
fnPath.node.type === 'FunctionDeclaration' &&
fnPath.node.id != null
) {
fnPath.replaceWith(
t.variableDeclaration('const', [
t.variableDeclarator(fnPath.node.id, gatingExpression),
]),
);
} else if (
fnPath.parentPath.node.type === 'ExportDefaultDeclaration' &&
fnPath.node.type !== 'ArrowFunctionExpression' &&
fnPath.node.id != null
) {
fnPath.insertAfter(
t.exportDefaultDeclaration(t.identifier(fnPath.node.id.name)),
);
fnPath.parentPath.replaceWith(
t.variableDeclaration('const', [
t.variableDeclarator(
t.identifier(fnPath.node.id.name),
gatingExpression,
),
]),
);
} else {
fnPath.replaceWith(gatingExpression);
}
}
}

View File

@@ -12,6 +12,7 @@ import {
EnvironmentConfig,
ExternalFunction,
parseEnvironmentConfig,
tryParseExternalFunction,
} from '../HIR/Environment';
import {hasOwnProperty} from '../Utils/utils';
import {fromZodError} from 'zod-validation-error';
@@ -271,6 +272,14 @@ export function parsePluginOptions(obj: unknown): PluginOptions {
parsedOptions[key] = parseTargetConfig(value);
break;
}
case 'gating': {
if (value == null) {
parsedOptions[key] = null;
} else {
parsedOptions[key] = tryParseExternalFunction(value);
}
break;
}
default: {
parsedOptions[key] = value;
}

View File

@@ -24,6 +24,7 @@ import {
pruneUnusedLabelsHIR,
} from '../HIR';
import {
CompilerMode,
Environment,
EnvironmentConfig,
ReactFunctionType,
@@ -99,7 +100,9 @@ import {propagateScopeDependenciesHIR} from '../HIR/PropagateScopeDependenciesHI
import {outlineJSX} from '../Optimization/OutlineJsx';
import {optimizePropsMethodCalls} from '../Optimization/OptimizePropsMethodCalls';
import {transformFire} from '../Transform';
import {validateNoImpureFunctionsInRender} from '../Validation/ValiateNoImpureFunctionsInRender';
import {validateNoImpureFunctionsInRender} from '../Validation/ValidateNoImpureFunctionsInRender';
import {CompilerError} from '..';
import {validateStaticComponents} from '../Validation/ValidateStaticComponents';
export type CompilerPipelineValue =
| {kind: 'ast'; name: string; value: CodegenFunction}
@@ -113,6 +116,7 @@ function run(
>,
config: EnvironmentConfig,
fnType: ReactFunctionType,
mode: CompilerMode,
useMemoCacheIdentifier: string,
logger: Logger | null,
filename: string | null,
@@ -122,6 +126,7 @@ function run(
const env = new Environment(
func.scope,
fnType,
mode,
config,
contextIdentifiers,
logger,
@@ -157,13 +162,13 @@ function runWithEnvironment(
log({kind: 'hir', name: 'PruneMaybeThrows', value: hir});
validateContextVariableLValues(hir);
validateUseMemo(hir);
validateUseMemo(hir).unwrap();
if (
env.isInferredMemoEnabled &&
!env.config.enablePreserveExistingManualUseMemo &&
!env.config.disableMemoizationForDebugging &&
!env.config.enableChangeDetectionForDebugging &&
!env.config.enableMinimalTransformsForRetry
!env.config.enableChangeDetectionForDebugging
) {
dropManualMemoization(hir);
log({kind: 'hir', name: 'DropManualMemoization', value: hir});
@@ -196,8 +201,13 @@ function runWithEnvironment(
inferTypes(hir);
log({kind: 'hir', name: 'InferTypes', value: hir});
if (env.config.validateHooksUsage) {
validateHooksUsage(hir);
if (env.isInferredMemoEnabled) {
if (env.config.validateHooksUsage) {
validateHooksUsage(hir).unwrap();
}
if (env.config.validateNoCapitalizedCalls) {
validateNoCapitalizedCalls(hir).unwrap();
}
}
if (env.config.enableFire) {
@@ -205,10 +215,6 @@ function runWithEnvironment(
log({kind: 'hir', name: 'TransformFire', value: hir});
}
if (env.config.validateNoCapitalizedCalls) {
validateNoCapitalizedCalls(hir);
}
if (env.config.lowerContextAccess) {
lowerContextAccess(hir, env.config.lowerContextAccess);
}
@@ -219,7 +225,12 @@ function runWithEnvironment(
analyseFunctions(hir);
log({kind: 'hir', name: 'AnalyseFunctions', value: hir});
inferReferenceEffects(hir);
const fnEffectErrors = inferReferenceEffects(hir);
if (env.isInferredMemoEnabled) {
if (fnEffectErrors.length > 0) {
CompilerError.throw(fnEffectErrors[0]);
}
}
log({kind: 'hir', name: 'InferReferenceEffects', value: hir});
validateLocalsNotReassignedAfterRender(hir);
@@ -239,28 +250,30 @@ function runWithEnvironment(
inferMutableRanges(hir);
log({kind: 'hir', name: 'InferMutableRanges', value: hir});
if (env.config.assertValidMutableRanges) {
assertValidMutableRanges(hir);
}
if (env.isInferredMemoEnabled) {
if (env.config.assertValidMutableRanges) {
assertValidMutableRanges(hir);
}
if (env.config.validateRefAccessDuringRender) {
validateNoRefAccessInRender(hir);
}
if (env.config.validateRefAccessDuringRender) {
validateNoRefAccessInRender(hir).unwrap();
}
if (env.config.validateNoSetStateInRender) {
validateNoSetStateInRender(hir);
}
if (env.config.validateNoSetStateInRender) {
validateNoSetStateInRender(hir).unwrap();
}
if (env.config.validateNoSetStateInPassiveEffects) {
validateNoSetStateInPassiveEffects(hir);
}
if (env.config.validateNoSetStateInPassiveEffects) {
env.logErrors(validateNoSetStateInPassiveEffects(hir));
}
if (env.config.validateNoJSXInTryStatements) {
validateNoJSXInTryStatement(hir);
}
if (env.config.validateNoJSXInTryStatements) {
env.logErrors(validateNoJSXInTryStatement(hir));
}
if (env.config.validateNoImpureFunctionsInRender) {
validateNoImpureFunctionsInRender(hir);
if (env.config.validateNoImpureFunctionsInRender) {
validateNoImpureFunctionsInRender(hir).unwrap();
}
}
inferReactivePlaces(hir);
@@ -280,7 +293,16 @@ function runWithEnvironment(
value: hir,
});
if (!env.config.enableMinimalTransformsForRetry) {
if (env.isInferredMemoEnabled) {
if (env.config.validateStaticComponents) {
env.logErrors(validateStaticComponents(hir));
}
/**
* Only create reactive scopes (which directly map to generated memo blocks)
* if inferred memoization is enabled. This makes all later passes which
* transform reactive-scope labeled instructions no-ops.
*/
inferReactiveScopeVariables(hir);
log({kind: 'hir', name: 'InferReactiveScopeVariables', value: hir});
}
@@ -492,14 +514,14 @@ function runWithEnvironment(
});
if (env.config.validateMemoizedEffectDependencies) {
validateMemoizedEffectDependencies(reactiveFunction);
validateMemoizedEffectDependencies(reactiveFunction).unwrap();
}
if (
env.config.enablePreserveExistingMemoizationGuarantees ||
env.config.validatePreserveExistingMemoizationGuarantees
) {
validatePreservedManualMemoization(reactiveFunction);
validatePreservedManualMemoization(reactiveFunction).unwrap();
}
const ast = codegenFunction(reactiveFunction, {
@@ -529,6 +551,7 @@ export function compileFn(
>,
config: EnvironmentConfig,
fnType: ReactFunctionType,
mode: CompilerMode,
useMemoCacheIdentifier: string,
logger: Logger | null,
filename: string | null,
@@ -538,6 +561,7 @@ export function compileFn(
func,
config,
fnType,
mode,
useMemoCacheIdentifier,
logger,
filename,

View File

@@ -16,8 +16,6 @@ import {
EnvironmentConfig,
ExternalFunction,
ReactFunctionType,
MINIMAL_RETRY_CONFIG,
tryParseExternalFunction,
} from '../HIR/Environment';
import {CodegenFunction} from '../ReactiveScopes';
import {isComponentDeclaration} from '../Utils/ComponentDeclaration';
@@ -273,6 +271,9 @@ function isFilePartOfSources(
return false;
}
type CompileProgramResult = {
retryErrors: Array<{fn: BabelFn; error: CompilerError}>;
};
/**
* `compileProgram` is directly invoked by the react-compiler babel plugin, so
* exceptions thrown by this function will fail the babel build.
@@ -287,16 +288,16 @@ function isFilePartOfSources(
export function compileProgram(
program: NodePath<t.Program>,
pass: CompilerPass,
): void {
): CompileProgramResult | null {
if (shouldSkipCompilation(program, pass)) {
return;
return null;
}
const environment = pass.opts.environment;
const restrictedImportsErr = validateRestrictedImports(program, environment);
if (restrictedImportsErr) {
handleError(restrictedImportsErr, pass, null);
return;
return null;
}
const useMemoCacheIdentifier = program.scope.generateUidIdentifier('c');
@@ -367,7 +368,7 @@ export function compileProgram(
filename: pass.filename ?? null,
},
);
const retryErrors: Array<{fn: BabelFn; error: CompilerError}> = [];
const processFn = (
fn: BabelFn,
fnType: ReactFunctionType,
@@ -408,6 +409,7 @@ export function compileProgram(
fn,
environment,
fnType,
'all_features',
useMemoCacheIdentifier.name,
pass.opts.logger,
pass.filename,
@@ -418,28 +420,7 @@ export function compileProgram(
compileResult = {kind: 'error', error: err};
}
}
// If non-memoization features are enabled, retry regardless of error kind
if (compileResult.kind === 'error' && environment.enableFire) {
try {
compileResult = {
kind: 'compile',
compiledFn: compileFn(
fn,
{
...environment,
...MINIMAL_RETRY_CONFIG,
},
fnType,
useMemoCacheIdentifier.name,
pass.opts.logger,
pass.filename,
pass.code,
),
};
} catch (err) {
compileResult = {kind: 'error', error: err};
}
}
if (compileResult.kind === 'error') {
/**
* If an opt out directive is present, log only instead of throwing and don't mark as
@@ -450,7 +431,39 @@ export function compileProgram(
} else {
handleError(compileResult.error, pass, fn.node.loc ?? null);
}
return null;
// If non-memoization features are enabled, retry regardless of error kind
if (
!(environment.enableFire || environment.inferEffectDependencies != null)
) {
return null;
}
try {
compileResult = {
kind: 'compile',
compiledFn: compileFn(
fn,
environment,
fnType,
'no_inferred_memo',
useMemoCacheIdentifier.name,
pass.opts.logger,
pass.filename,
pass.code,
),
};
if (
!compileResult.compiledFn.hasFireRewrite &&
!compileResult.compiledFn.hasLoweredContextAccess
) {
return null;
}
} catch (err) {
// TODO: we might want to log error here, but this will also result in duplicate logging
if (err instanceof CompilerError) {
retryErrors.push({fn, error: err});
}
return null;
}
}
pass.opts.logger?.logEvent(pass.filename, {
@@ -539,32 +552,28 @@ export function compileProgram(
program.node.directives,
);
if (moduleScopeOptOutDirectives.length > 0) {
return;
return null;
}
let gating: null | {
gatingFn: ExternalFunction;
referencedBeforeDeclared: Set<CompileResult>;
} = null;
if (pass.opts.gating != null) {
const error = checkFunctionReferencedBeforeDeclarationAtTopLevel(
program,
compiledFns.map(result => {
return result.originalFn;
}),
);
if (error) {
handleError(error, pass, null);
return;
}
gating = {
gatingFn: pass.opts.gating,
referencedBeforeDeclared:
getFunctionReferencedBeforeDeclarationAtTopLevel(program, compiledFns),
};
}
const hasLoweredContextAccess = compiledFns.some(
c => c.compiledFn.hasLoweredContextAccess,
);
const externalFunctions: Array<ExternalFunction> = [];
let gating: null | ExternalFunction = null;
try {
// TODO: check for duplicate import specifiers
if (pass.opts.gating != null) {
gating = tryParseExternalFunction(pass.opts.gating);
externalFunctions.push(gating);
if (gating != null) {
externalFunctions.push(gating.gatingFn);
}
const lowerContextAccess = environment.lowerContextAccess;
@@ -601,7 +610,7 @@ export function compileProgram(
}
} catch (err) {
handleError(err, pass, null);
return;
return null;
}
/*
@@ -613,7 +622,12 @@ export function compileProgram(
const transformedFn = createNewFunctionNode(originalFn, compiledFn);
if (gating != null && kind === 'original') {
insertGatedFunctionDeclaration(originalFn, transformedFn, gating);
insertGatedFunctionDeclaration(
originalFn,
transformedFn,
gating.gatingFn,
gating.referencedBeforeDeclared.has(result),
);
} else {
originalFn.replaceWith(transformedFn);
}
@@ -638,6 +652,7 @@ export function compileProgram(
}
addImportsToProgram(program, externalFunctions);
}
return {retryErrors};
}
function shouldSkipCompilation(
@@ -993,31 +1008,39 @@ function callsHooksOrCreatesJsx(
return invokesHooks || createsJsx;
}
function isNonNode(node?: t.Expression | null): boolean {
if (!node) {
return true;
}
switch (node.type) {
case 'ObjectExpression':
case 'ArrowFunctionExpression':
case 'FunctionExpression':
case 'BigIntLiteral':
case 'ClassExpression':
case 'NewExpression': // technically `new Array()` is legit, but unlikely
return true;
}
return false;
}
function returnsNonNode(
node: NodePath<
t.FunctionDeclaration | t.ArrowFunctionExpression | t.FunctionExpression
>,
): boolean {
let hasReturn = false;
let returnsNonNode = false;
if (
// node.traverse#ArrowFunctionExpression isn't called for the root node
node.type === 'ArrowFunctionExpression' &&
node.node.body.type !== 'BlockStatement'
) {
returnsNonNode = isNonNode(node.node.body);
}
node.traverse({
ReturnStatement(ret) {
hasReturn = true;
const argument = ret.node.argument;
if (argument == null) {
returnsNonNode = true;
} else {
switch (argument.type) {
case 'ObjectExpression':
case 'ArrowFunctionExpression':
case 'FunctionExpression':
case 'BigIntLiteral':
case 'ClassExpression':
case 'NewExpression': // technically `new Array()` is legit, but unlikely
returnsNonNode = true;
}
}
returnsNonNode = isNonNode(ret.node.argument);
},
// Skip traversing all nested functions and their return statements
ArrowFunctionExpression: skipNestedFunctions(node),
@@ -1026,7 +1049,7 @@ function returnsNonNode(
ObjectMethod: node => node.skip(),
});
return !hasReturn || returnsNonNode;
return returnsNonNode;
}
/*
@@ -1093,20 +1116,23 @@ function getFunctionName(
}
}
function checkFunctionReferencedBeforeDeclarationAtTopLevel(
function getFunctionReferencedBeforeDeclarationAtTopLevel(
program: NodePath<t.Program>,
fns: Array<BabelFn>,
): CompilerError | null {
const fnIds = new Set(
fns: Array<CompileResult>,
): Set<CompileResult> {
const fnNames = new Map<string, {id: t.Identifier; fn: CompileResult}>(
fns
.map(fn => getFunctionName(fn))
.map<[NodePath<t.Expression> | null, CompileResult]>(fn => [
getFunctionName(fn.originalFn),
fn,
])
.filter(
(name): name is NodePath<t.Identifier> => !!name && name.isIdentifier(),
(entry): entry is [NodePath<t.Identifier>, CompileResult] =>
!!entry[0] && entry[0].isIdentifier(),
)
.map(name => name.node),
.map(entry => [entry[0].node.name, {id: entry[0].node, fn: entry[1]}]),
);
const fnNames = new Map([...fnIds].map(id => [id.name, id]));
const errors = new CompilerError();
const referencedBeforeDeclaration = new Set<CompileResult>();
program.traverse({
TypeAnnotation(path) {
@@ -1132,8 +1158,7 @@ function checkFunctionReferencedBeforeDeclarationAtTopLevel(
* We've reached the declaration, hoisting is no longer possible, stop
* checking for this component name.
*/
if (fnIds.has(id.node)) {
fnIds.delete(id.node);
if (id.node === fn.id) {
fnNames.delete(id.node.name);
return;
}
@@ -1143,21 +1168,13 @@ function checkFunctionReferencedBeforeDeclarationAtTopLevel(
* A null scope means there's no function scope, which means we're at the
* top level scope.
*/
if (scope === null) {
errors.pushErrorDetail(
new CompilerErrorDetail({
reason: `Encountered a function used before its declaration, which breaks Forget's gating codegen due to hoisting`,
description: `Rewrite the reference to ${fn.name} to not rely on hoisting to fix this issue`,
loc: fn.loc ?? null,
suggestions: null,
severity: ErrorSeverity.Invariant,
}),
);
if (scope === null && id.isReferencedIdentifier()) {
referencedBeforeDeclaration.add(fn.fn);
}
},
});
return errors.details.length > 0 ? errors : null;
return referencedBeforeDeclaration;
}
function getReactCompilerRuntimeModule(opts: PluginOptions): string {

View File

@@ -0,0 +1,275 @@
import {NodePath} from '@babel/core';
import * as t from '@babel/types';
import {
CompilerError,
CompilerErrorDetailOptions,
EnvironmentConfig,
ErrorSeverity,
Logger,
} from '..';
import {getOrInsertWith} from '../Utils/utils';
import {Environment} from '../HIR';
import {DEFAULT_EXPORT} from '../HIR/Environment';
function throwInvalidReact(
options: Omit<CompilerErrorDetailOptions, 'severity'>,
{logger, filename}: TraversalState,
): never {
const detail: CompilerErrorDetailOptions = {
...options,
severity: ErrorSeverity.InvalidReact,
};
logger?.logEvent(filename, {
kind: 'CompileError',
fnLoc: null,
detail,
});
CompilerError.throw(detail);
}
function assertValidEffectImportReference(
numArgs: number,
paths: Array<NodePath<t.Node>>,
context: TraversalState,
): void {
for (const path of paths) {
const parent = path.parentPath;
if (parent != null && parent.isCallExpression()) {
const args = parent.get('arguments');
/**
* Only error on untransformed references of the form `useMyEffect(...)`
* or `moduleNamespace.useMyEffect(...)`, with matching argument counts.
* TODO: do we also want a mode to also hard error on non-call references?
*/
if (args.length === numArgs) {
const maybeErrorDiagnostic = matchCompilerDiagnostic(
path,
context.transformErrors,
);
/**
* Note that we cannot easily check the type of the first argument here,
* as it may have already been transformed by the compiler (and not
* memoized).
*/
throwInvalidReact(
{
reason:
'[InferEffectDependencies] React Compiler is unable to infer dependencies of this effect. ' +
'This will break your build! ' +
'To resolve, either pass your own dependency array or fix reported compiler bailout diagnostics.',
description: maybeErrorDiagnostic
? `(Bailout reason: ${maybeErrorDiagnostic})`
: null,
loc: parent.node.loc ?? null,
},
context,
);
}
}
}
}
function assertValidFireImportReference(
paths: Array<NodePath<t.Node>>,
context: TraversalState,
): void {
if (paths.length > 0) {
const maybeErrorDiagnostic = matchCompilerDiagnostic(
paths[0],
context.transformErrors,
);
throwInvalidReact(
{
reason:
'[Fire] Untransformed reference to compiler-required feature. ' +
'Either remove this `fire` call or ensure it is successfully transformed by the compiler',
description: maybeErrorDiagnostic
? `(Bailout reason: ${maybeErrorDiagnostic})`
: null,
loc: paths[0].node.loc ?? null,
},
context,
);
}
}
export default function validateNoUntransformedReferences(
path: NodePath<t.Program>,
filename: string | null,
logger: Logger | null,
env: EnvironmentConfig,
transformErrors: Array<{fn: NodePath<t.Node>; error: CompilerError}>,
): void {
const moduleLoadChecks = new Map<
string,
Map<string, CheckInvalidReferenceFn>
>();
if (env.enableFire) {
/**
* Error on any untransformed references to `fire` (e.g. including non-call
* expressions)
*/
for (const module of Environment.knownReactModules) {
const react = getOrInsertWith(moduleLoadChecks, module, () => new Map());
react.set('fire', assertValidFireImportReference);
}
}
if (env.inferEffectDependencies) {
for (const {
function: {source, importSpecifierName},
numRequiredArgs,
} of env.inferEffectDependencies) {
const module = getOrInsertWith(moduleLoadChecks, source, () => new Map());
module.set(
importSpecifierName,
assertValidEffectImportReference.bind(null, numRequiredArgs),
);
}
}
if (moduleLoadChecks.size > 0) {
transformProgram(path, moduleLoadChecks, filename, logger, transformErrors);
}
}
type TraversalState = {
shouldInvalidateScopes: boolean;
program: NodePath<t.Program>;
logger: Logger | null;
filename: string | null;
transformErrors: Array<{fn: NodePath<t.Node>; error: CompilerError}>;
};
type CheckInvalidReferenceFn = (
paths: Array<NodePath<t.Node>>,
context: TraversalState,
) => void;
function validateImportSpecifier(
specifier: NodePath<t.ImportSpecifier>,
importSpecifierChecks: Map<string, CheckInvalidReferenceFn>,
state: TraversalState,
): void {
const imported = specifier.get('imported');
const specifierName: string =
imported.node.type === 'Identifier'
? imported.node.name
: imported.node.value;
const checkFn = importSpecifierChecks.get(specifierName);
if (checkFn == null) {
return;
}
if (state.shouldInvalidateScopes) {
state.shouldInvalidateScopes = false;
state.program.scope.crawl();
}
const local = specifier.get('local');
const binding = local.scope.getBinding(local.node.name);
CompilerError.invariant(binding != null, {
reason: 'Expected binding to be found for import specifier',
loc: local.node.loc ?? null,
});
checkFn(binding.referencePaths, state);
}
function validateNamespacedImport(
specifier: NodePath<t.ImportNamespaceSpecifier | t.ImportDefaultSpecifier>,
importSpecifierChecks: Map<string, CheckInvalidReferenceFn>,
state: TraversalState,
): void {
if (state.shouldInvalidateScopes) {
state.shouldInvalidateScopes = false;
state.program.scope.crawl();
}
const local = specifier.get('local');
const binding = local.scope.getBinding(local.node.name);
const defaultCheckFn = importSpecifierChecks.get(DEFAULT_EXPORT);
CompilerError.invariant(binding != null, {
reason: 'Expected binding to be found for import specifier',
loc: local.node.loc ?? null,
});
const filteredReferences = new Map<
CheckInvalidReferenceFn,
Array<NodePath<t.Node>>
>();
for (const reference of binding.referencePaths) {
if (defaultCheckFn != null) {
getOrInsertWith(filteredReferences, defaultCheckFn, () => []).push(
reference,
);
}
const parent = reference.parentPath;
if (
parent != null &&
parent.isMemberExpression() &&
parent.get('object') === reference
) {
if (parent.node.computed || parent.node.property.type !== 'Identifier') {
continue;
}
const checkFn = importSpecifierChecks.get(parent.node.property.name);
if (checkFn != null) {
getOrInsertWith(filteredReferences, checkFn, () => []).push(parent);
}
}
}
for (const [checkFn, references] of filteredReferences) {
checkFn(references, state);
}
}
function transformProgram(
path: NodePath<t.Program>,
moduleLoadChecks: Map<string, Map<string, CheckInvalidReferenceFn>>,
filename: string | null,
logger: Logger | null,
transformErrors: Array<{fn: NodePath<t.Node>; error: CompilerError}>,
): void {
const traversalState: TraversalState = {
shouldInvalidateScopes: true,
program: path,
filename,
logger,
transformErrors,
};
path.traverse({
ImportDeclaration(path: NodePath<t.ImportDeclaration>) {
const importSpecifierChecks = moduleLoadChecks.get(
path.node.source.value,
);
if (importSpecifierChecks == null) {
return;
}
const specifiers = path.get('specifiers');
for (const specifier of specifiers) {
if (specifier.isImportSpecifier()) {
validateImportSpecifier(
specifier,
importSpecifierChecks,
traversalState,
);
} else {
validateNamespacedImport(
specifier as NodePath<
t.ImportNamespaceSpecifier | t.ImportDefaultSpecifier
>,
importSpecifierChecks,
traversalState,
);
}
}
},
});
}
function matchCompilerDiagnostic(
badReference: NodePath<t.Node>,
transformErrors: Array<{fn: NodePath<t.Node>; error: CompilerError}>,
): string | null {
for (const {fn, error} of transformErrors) {
if (fn.isAncestor(badReference)) {
return error.toString();
}
}
return null;
}

View File

@@ -1455,6 +1455,11 @@ function lowerObjectPropertyKey(
kind: 'identifier',
name: key.node.name,
};
} else if (key.isNumericLiteral()) {
return {
kind: 'identifier',
name: String(key.node.value),
};
}
builder.errors.push({

View File

@@ -13,11 +13,13 @@ import {
BlockId,
DependencyPathEntry,
GeneratedSource,
getHookKind,
HIRFunction,
Identifier,
IdentifierId,
InstructionId,
InstructionValue,
LoweredFunction,
PropertyLiteral,
ReactiveScopeDependency,
ScopeId,
@@ -112,6 +114,9 @@ export function collectHoistablePropertyLoads(
hoistableFromOptionals,
registry,
nestedFnImmutableContext: null,
assumedInvokedFns: fn.env.config.enableTreatFunctionDepsAsConditional
? new Set()
: getAssumedInvokedFunctions(fn),
});
}
@@ -127,6 +132,11 @@ type CollectHoistablePropertyLoadsContext = {
* but are currently kept separate for readability.
*/
nestedFnImmutableContext: ReadonlySet<IdentifierId> | null;
/**
* Functions which are assumed to be eventually called (as opposed to ones which might
* not be called, e.g. the 0th argument of Array.map)
*/
assumedInvokedFns: ReadonlySet<LoweredFunction>;
};
function collectHoistablePropertyLoadsImpl(
fn: HIRFunction,
@@ -338,7 +348,13 @@ function collectNonNullsInBlocks(
context.registry.getOrCreateIdentifier(identifier),
);
}
const nodes = new Map<BlockId, BlockInfo>();
const nodes = new Map<
BlockId,
{
block: BasicBlock;
assumedNonNullObjects: Set<PropertyPathNode>;
}
>();
for (const [_, block] of fn.body.blocks) {
const assumedNonNullObjects = new Set<PropertyPathNode>(
knownNonNullIdentifiers,
@@ -358,32 +374,30 @@ function collectNonNullsInBlocks(
) {
assumedNonNullObjects.add(maybeNonNull);
}
if (
(instr.value.kind === 'FunctionExpression' ||
instr.value.kind === 'ObjectMethod') &&
!fn.env.config.enableTreatFunctionDepsAsConditional
) {
if (instr.value.kind === 'FunctionExpression') {
const innerFn = instr.value.loweredFunc;
const innerHoistableMap = collectHoistablePropertyLoadsImpl(
innerFn.func,
{
...context,
nestedFnImmutableContext:
context.nestedFnImmutableContext ??
new Set(
innerFn.func.context
.filter(place =>
isImmutableAtInstr(place.identifier, instr.id, context),
)
.map(place => place.identifier.id),
),
},
);
const innerHoistables = assertNonNull(
innerHoistableMap.get(innerFn.func.body.entry),
);
for (const entry of innerHoistables.assumedNonNullObjects) {
assumedNonNullObjects.add(entry);
if (context.assumedInvokedFns.has(innerFn)) {
const innerHoistableMap = collectHoistablePropertyLoadsImpl(
innerFn.func,
{
...context,
nestedFnImmutableContext:
context.nestedFnImmutableContext ??
new Set(
innerFn.func.context
.filter(place =>
isImmutableAtInstr(place.identifier, instr.id, context),
)
.map(place => place.identifier.id),
),
},
);
const innerHoistables = assertNonNull(
innerHoistableMap.get(innerFn.func.body.entry),
);
for (const entry of innerHoistables.assumedNonNullObjects) {
assumedNonNullObjects.add(entry);
}
}
}
}
@@ -591,3 +605,130 @@ function reduceMaybeOptionalChains(
}
} while (changed);
}
function getAssumedInvokedFunctions(
fn: HIRFunction,
temporaries: Map<
IdentifierId,
{fn: LoweredFunction; mayInvoke: Set<LoweredFunction>}
> = new Map(),
): ReadonlySet<LoweredFunction> {
const hoistableFunctions = new Set<LoweredFunction>();
/**
* Step 1: Conservatively collect identifier to function expression mappings
*/
for (const block of fn.body.blocks.values()) {
for (const {lvalue, value} of block.instructions) {
/**
* Conservatively only match function expressions which can have guaranteed ssa.
* ObjectMethods and ObjectProperties do not.
*/
if (value.kind === 'FunctionExpression') {
temporaries.set(lvalue.identifier.id, {
fn: value.loweredFunc,
mayInvoke: new Set(),
});
} else if (value.kind === 'StoreLocal') {
const lvalue = value.lvalue.place.identifier;
const maybeLoweredFunc = temporaries.get(value.value.identifier.id);
if (maybeLoweredFunc != null) {
temporaries.set(lvalue.id, maybeLoweredFunc);
}
} else if (value.kind === 'LoadLocal') {
const maybeLoweredFunc = temporaries.get(value.place.identifier.id);
if (maybeLoweredFunc != null) {
temporaries.set(lvalue.identifier.id, maybeLoweredFunc);
}
}
}
}
/**
* Step 2: Forward pass to do analysis of assumed function calls. Note that
* this is conservative and does not count indirect references through
* containers (e.g. `return {cb: () => {...}})`).
*/
for (const block of fn.body.blocks.values()) {
for (const {lvalue, value} of block.instructions) {
if (value.kind === 'CallExpression') {
const callee = value.callee;
const maybeHook = getHookKind(fn.env, callee.identifier);
const maybeLoweredFunc = temporaries.get(callee.identifier.id);
if (maybeLoweredFunc != null) {
// Direct calls
hoistableFunctions.add(maybeLoweredFunc.fn);
} else if (maybeHook != null) {
/**
* Assume arguments to all hooks are safe to invoke
*/
for (const arg of value.args) {
if (arg.kind === 'Identifier') {
const maybeLoweredFunc = temporaries.get(arg.identifier.id);
if (maybeLoweredFunc != null) {
hoistableFunctions.add(maybeLoweredFunc.fn);
}
}
}
}
} else if (value.kind === 'JsxExpression') {
/**
* Assume JSX attributes and children are safe to invoke
*/
for (const attr of value.props) {
if (attr.kind === 'JsxSpreadAttribute') {
continue;
}
const maybeLoweredFunc = temporaries.get(attr.place.identifier.id);
if (maybeLoweredFunc != null) {
hoistableFunctions.add(maybeLoweredFunc.fn);
}
}
for (const child of value.children ?? []) {
const maybeLoweredFunc = temporaries.get(child.identifier.id);
if (maybeLoweredFunc != null) {
hoistableFunctions.add(maybeLoweredFunc.fn);
}
}
} else if (value.kind === 'FunctionExpression') {
/**
* Recursively traverse into other function expressions which may invoke
* or pass already declared functions to react (e.g. as JSXAttributes).
*
* If lambda A calls lambda B, we assume lambda B is safe to invoke if
* lambda A is -- even if lambda B is conditionally called. (see
* `conditional-call-chain` fixture for example).
*/
const loweredFunc = value.loweredFunc.func;
const lambdasCalled = getAssumedInvokedFunctions(
loweredFunc,
temporaries,
);
const maybeLoweredFunc = temporaries.get(lvalue.identifier.id);
if (maybeLoweredFunc != null) {
for (const called of lambdasCalled) {
maybeLoweredFunc.mayInvoke.add(called);
}
}
}
}
if (block.terminal.kind === 'return') {
/**
* Assume directly returned functions are safe to call
*/
const maybeLoweredFunc = temporaries.get(
block.terminal.value.identifier.id,
);
if (maybeLoweredFunc != null) {
hoistableFunctions.add(maybeLoweredFunc.fn);
}
}
}
for (const [_, {fn, mayInvoke}] of temporaries) {
if (hoistableFunctions.has(fn)) {
for (const called of mayInvoke) {
hoistableFunctions.add(called);
}
}
}
return hoistableFunctions;
}

View File

@@ -96,6 +96,8 @@ export const MacroSchema = z.union([
z.tuple([z.string(), z.array(MacroMethodSchema)]),
]);
export type CompilerMode = 'all_features' | 'no_inferred_memo';
export type Macro = z.infer<typeof MacroSchema>;
export type MacroMethod = z.infer<typeof MacroMethodSchema>;
@@ -328,6 +330,11 @@ const EnvironmentConfigSchema = z.object({
*/
validateNoJSXInTryStatements: z.boolean().default(false),
/**
* Validates against dynamically creating components during render.
*/
validateStaticComponents: z.boolean().default(false),
/**
* Validates that the dependencies of all effect hooks are memoized. This helps ensure
* that Forget does not introduce infinite renders caused by a dependency changing,
@@ -550,8 +557,6 @@ const EnvironmentConfigSchema = z.object({
*/
disableMemoizationForDebugging: z.boolean().default(false),
enableMinimalTransformsForRetry: z.boolean().default(false),
/**
* When true, rather using memoized values, the compiler will always re-compute
* values, and then use a heuristic to compare the memoized value to the newly
@@ -626,17 +631,6 @@ const EnvironmentConfigSchema = z.object({
export type EnvironmentConfig = z.infer<typeof EnvironmentConfigSchema>;
export const MINIMAL_RETRY_CONFIG: PartialEnvironmentConfig = {
validateHooksUsage: false,
validateRefAccessDuringRender: false,
validateNoSetStateInRender: false,
validateNoSetStateInPassiveEffects: false,
validateNoJSXInTryStatements: false,
validateMemoizedEffectDependencies: false,
validateNoCapitalizedCalls: null,
validateBlocklistedImports: null,
enableMinimalTransformsForRetry: true,
};
/**
* For test fixtures and playground only.
*
@@ -663,7 +657,7 @@ const testComplexConfigDefaults: PartialEnvironmentConfig = {
source: 'react-compiler-runtime',
importSpecifierName: 'shouldInstrument',
},
globalGating: '__DEV__',
globalGating: 'DEV',
},
enableEmitHookGuards: {
source: 'react-compiler-runtime',
@@ -851,6 +845,7 @@ export class Environment {
code: string | null;
config: EnvironmentConfig;
fnType: ReactFunctionType;
compilerMode: CompilerMode;
useMemoCacheIdentifier: string;
hasLoweredContextAccess: boolean;
hasFireRewrite: boolean;
@@ -861,6 +856,7 @@ export class Environment {
constructor(
scope: BabelScope,
fnType: ReactFunctionType,
compilerMode: CompilerMode,
config: EnvironmentConfig,
contextIdentifiers: Set<t.Identifier>,
logger: Logger | null,
@@ -870,6 +866,7 @@ export class Environment {
) {
this.#scope = scope;
this.fnType = fnType;
this.compilerMode = compilerMode;
this.config = config;
this.filename = filename;
this.code = code;
@@ -924,6 +921,10 @@ export class Environment {
this.#hoistedIdentifiers = new Set();
}
get isInferredMemoEnabled(): boolean {
return this.compilerMode !== 'no_inferred_memo';
}
get nextIdentifierId(): IdentifierId {
return makeIdentifierId(this.#nextIdentifer++);
}
@@ -936,6 +937,19 @@ export class Environment {
return makeScopeId(this.#nextScope++);
}
logErrors(errors: Result<void, CompilerError>): void {
if (errors.isOk() || this.logger == null) {
return;
}
for (const error of errors.unwrapErr().details) {
this.logger.logEvent(this.filename, {
kind: 'CompileError',
detail: error,
fnLoc: null,
});
}
}
isContextIdentifier(node: t.Identifier): boolean {
return this.#contextIdentifiers.has(node);
}
@@ -1125,6 +1139,7 @@ export class Environment {
moduleName.toLowerCase() === 'react-dom'
);
}
static knownReactModules: ReadonlyArray<string> = ['react', 'react-dom'];
getFallthroughPropertyType(
receiver: Type,

View File

@@ -703,6 +703,10 @@ export type ObjectPropertyKey =
| {
kind: 'computed';
name: Place;
}
| {
kind: 'number';
name: number;
};
export type ObjectProperty = {

View File

@@ -330,6 +330,9 @@ function printObjectPropertyKey(key: ObjectPropertyKey): string {
case 'computed': {
return `[${printPlace(key.name)}]`;
}
case 'number': {
return String(key.name);
}
}
}

View File

@@ -5,7 +5,12 @@
* LICENSE file in the root directory of this source tree.
*/
import {CompilerError, ErrorSeverity, ValueKind} from '..';
import {
CompilerError,
CompilerErrorDetailOptions,
ErrorSeverity,
ValueKind,
} from '..';
import {
AbstractValue,
BasicBlock,
@@ -290,21 +295,21 @@ export function inferTerminalFunctionEffects(
return functionEffects;
}
export function raiseFunctionEffectErrors(
export function transformFunctionEffectErrors(
functionEffects: Array<FunctionEffect>,
): void {
functionEffects.forEach(eff => {
): Array<CompilerErrorDetailOptions> {
return functionEffects.map(eff => {
switch (eff.kind) {
case 'ReactMutation':
case 'GlobalMutation': {
CompilerError.throw(eff.error);
return eff.error;
}
case 'ContextMutation': {
CompilerError.throw({
return {
severity: ErrorSeverity.Invariant,
reason: `Unexpected ContextMutation in top-level function effects`,
loc: eff.loc,
});
};
}
default:
assertExhaustive(

View File

@@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
import {CompilerError} from '../CompilerError';
import {CompilerError, CompilerErrorDetailOptions} from '../CompilerError';
import {Environment} from '../HIR';
import {
AbstractValue,
@@ -49,7 +49,7 @@ import {assertExhaustive} from '../Utils/utils';
import {
inferTerminalFunctionEffects,
inferInstructionFunctionEffects,
raiseFunctionEffectErrors,
transformFunctionEffectErrors,
} from './InferFunctionEffects';
const UndefinedValue: InstructionValue = {
@@ -103,7 +103,7 @@ const UndefinedValue: InstructionValue = {
export default function inferReferenceEffects(
fn: HIRFunction,
options: {isFunctionExpression: boolean} = {isFunctionExpression: false},
): void {
): Array<CompilerErrorDetailOptions> {
/*
* Initial state contains function params
* TODO: include module declarations here as well
@@ -241,8 +241,9 @@ export default function inferReferenceEffects(
if (options.isFunctionExpression) {
fn.effects = functionEffects;
} else if (!fn.env.config.enableMinimalTransformsForRetry) {
raiseFunctionEffectErrors(functionEffects);
return [];
} else {
return transformFunctionEffectErrors(functionEffects);
}
}

View File

@@ -14,7 +14,7 @@ import {
renameVariables,
} from '.';
import {CompilerError, ErrorSeverity} from '../CompilerError';
import {Environment, EnvironmentConfig, ExternalFunction} from '../HIR';
import {Environment, ExternalFunction} from '../HIR';
import {
ArrayPattern,
BlockId,
@@ -156,7 +156,7 @@ export function codegenFunction(
const compiled = compileResult.unwrap();
const hookGuard = fn.env.config.enableEmitHookGuards;
if (hookGuard != null) {
if (hookGuard != null && fn.env.isInferredMemoEnabled) {
compiled.body = t.blockStatement([
createHookGuard(
hookGuard,
@@ -250,7 +250,11 @@ export function codegenFunction(
}
const emitInstrumentForget = fn.env.config.enableEmitInstrumentForget;
if (emitInstrumentForget != null && fn.id != null) {
if (
emitInstrumentForget != null &&
fn.id != null &&
fn.env.isInferredMemoEnabled
) {
/*
* Technically, this is a conditional hook call. However, we expect
* __DEV__ and gating identifier to be runtime constants
@@ -548,7 +552,7 @@ function codegenBlockNoReset(
}
function wrapCacheDep(cx: Context, value: t.Expression): t.Expression {
if (cx.env.config.enableEmitFreeze != null) {
if (cx.env.config.enableEmitFreeze != null && cx.env.isInferredMemoEnabled) {
// The import declaration for emitFreeze is inserted in the Babel plugin
return t.conditionalExpression(
t.identifier('__DEV__'),
@@ -1553,7 +1557,7 @@ function createHookGuard(
* ```
*/
function createCallExpression(
config: EnvironmentConfig,
env: Environment,
callee: t.Expression,
args: Array<t.Expression | t.SpreadElement>,
loc: SourceLocation | null,
@@ -1564,8 +1568,8 @@ function createCallExpression(
callExpr.loc = loc;
}
const hookGuard = config.enableEmitHookGuards;
if (hookGuard != null && isHook) {
const hookGuard = env.config.enableEmitHookGuards;
if (hookGuard != null && isHook && env.isInferredMemoEnabled) {
const iife = t.functionExpression(
null,
[],
@@ -1701,7 +1705,7 @@ function codegenInstructionValue(
const callee = codegenPlaceToExpression(cx, instrValue.callee);
const args = instrValue.args.map(arg => codegenArgument(cx, arg));
value = createCallExpression(
cx.env.config,
cx.env,
callee,
args,
instrValue.loc,
@@ -1791,7 +1795,7 @@ function codegenInstructionValue(
);
const args = instrValue.args.map(arg => codegenArgument(cx, arg));
value = createCallExpression(
cx.env.config,
cx.env,
memberExpr,
args,
instrValue.loc,
@@ -2429,6 +2433,9 @@ function codegenObjectPropertyKey(
});
return expr;
}
case 'number': {
return t.numericLiteral(key.name);
}
}
}

View File

@@ -26,6 +26,7 @@ import {
eachTerminalOperand,
} from '../HIR/visitors';
import {assertExhaustive} from '../Utils/utils';
import {Result} from '../Utils/Result';
/**
* Represents the possible kinds of value which may be stored at a given Place during
@@ -87,7 +88,9 @@ function joinKinds(a: Kind, b: Kind): Kind {
* may not appear as the callee of a conditional call.
* See the note for Kind.PotentialHook for sources of potential hooks
*/
export function validateHooksUsage(fn: HIRFunction): void {
export function validateHooksUsage(
fn: HIRFunction,
): Result<void, CompilerError> {
const unconditionalBlocks = computeUnconditionalBlocks(fn);
const errors = new CompilerError();
@@ -423,9 +426,7 @@ export function validateHooksUsage(fn: HIRFunction): void {
for (const [, error] of errorsByPlace) {
errors.push(error);
}
if (errors.hasErrors()) {
throw errors;
}
return errors.asResult();
}
function visitFunctionExpression(errors: CompilerError, fn: HIRFunction): void {

View File

@@ -22,6 +22,7 @@ import {
ReactiveFunctionVisitor,
visitReactiveFunction,
} from '../ReactiveScopes/visitors';
import {Result} from '../Utils/Result';
/**
* Validates that all known effect dependencies are memoized. The algorithm checks two things:
@@ -47,12 +48,12 @@ import {
* mutate(object); // ... mutable range ends here after this mutation
* ```
*/
export function validateMemoizedEffectDependencies(fn: ReactiveFunction): void {
export function validateMemoizedEffectDependencies(
fn: ReactiveFunction,
): Result<void, CompilerError> {
const errors = new CompilerError();
visitReactiveFunction(fn, new Visitor(), errors);
if (errors.hasErrors()) {
throw errors;
}
return errors.asResult();
}
class Visitor extends ReactiveFunctionVisitor<CompilerError> {

View File

@@ -4,11 +4,14 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {CompilerError, EnvironmentConfig} from '..';
import {CompilerError, EnvironmentConfig, ErrorSeverity} from '..';
import {HIRFunction, IdentifierId} from '../HIR';
import {DEFAULT_GLOBALS} from '../HIR/Globals';
import {Result} from '../Utils/Result';
export function validateNoCapitalizedCalls(fn: HIRFunction): void {
export function validateNoCapitalizedCalls(
fn: HIRFunction,
): Result<void, CompilerError> {
const envConfig: EnvironmentConfig = fn.env.config;
const ALLOW_LIST = new Set([
...DEFAULT_GLOBALS.keys(),
@@ -26,6 +29,7 @@ export function validateNoCapitalizedCalls(fn: HIRFunction): void {
);
};
const errors = new CompilerError();
const capitalLoadGlobals = new Map<IdentifierId, string>();
const capitalizedProperties = new Map<IdentifierId, string>();
const reason =
@@ -73,7 +77,8 @@ export function validateNoCapitalizedCalls(fn: HIRFunction): void {
const propertyIdentifier = value.property.identifier.id;
const propertyName = capitalizedProperties.get(propertyIdentifier);
if (propertyName != null) {
CompilerError.throwInvalidReact({
errors.push({
severity: ErrorSeverity.InvalidReact,
reason,
description: `${propertyName} may be a component.`,
loc: value.loc,
@@ -85,4 +90,5 @@ export function validateNoCapitalizedCalls(fn: HIRFunction): void {
}
}
}
return errors.asResult();
}

View File

@@ -8,6 +8,7 @@
import {CompilerError, ErrorSeverity} from '..';
import {HIRFunction} from '../HIR';
import {getFunctionCallSignature} from '../Inference/InferReferenceEffects';
import {Result} from '../Utils/Result';
/**
* Checks that known-impure functions are not called during render. Examples of invalid functions to
@@ -18,7 +19,9 @@ import {getFunctionCallSignature} from '../Inference/InferReferenceEffects';
* this in several of our validation passes and should unify those analyses into a reusable helper
* and use it here.
*/
export function validateNoImpureFunctionsInRender(fn: HIRFunction): void {
export function validateNoImpureFunctionsInRender(
fn: HIRFunction,
): Result<void, CompilerError> {
const errors = new CompilerError();
for (const [, block] of fn.body.blocks) {
for (const instr of block.instructions) {
@@ -46,7 +49,5 @@ export function validateNoImpureFunctionsInRender(fn: HIRFunction): void {
}
}
}
if (errors.hasErrors()) {
throw errors;
}
return errors.asResult();
}

View File

@@ -7,6 +7,7 @@
import {CompilerError, ErrorSeverity} from '..';
import {BlockId, HIRFunction} from '../HIR';
import {Result} from '../Utils/Result';
import {retainWhere} from '../Utils/utils';
/**
@@ -19,7 +20,9 @@ import {retainWhere} from '../Utils/utils';
* created within a try block. JSX is allowed within a catch statement, unless that catch
* is itself nested inside an outer try.
*/
export function validateNoJSXInTryStatement(fn: HIRFunction): void {
export function validateNoJSXInTryStatement(
fn: HIRFunction,
): Result<void, CompilerError> {
const activeTryBlocks: Array<BlockId> = [];
const errors = new CompilerError();
for (const [, block] of fn.body.blocks) {
@@ -46,7 +49,5 @@ export function validateNoJSXInTryStatement(fn: HIRFunction): void {
activeTryBlocks.push(block.terminal.handler);
}
}
if (errors.hasErrors()) {
throw errors;
}
return errors.asResult();
}

View File

@@ -99,9 +99,11 @@ class Env extends Map<IdentifierId, RefAccessType> {
}
}
export function validateNoRefAccessInRender(fn: HIRFunction): void {
export function validateNoRefAccessInRender(
fn: HIRFunction,
): Result<void, CompilerError> {
const env = new Env();
validateNoRefAccessInRenderImpl(fn, env).unwrap();
return validateNoRefAccessInRenderImpl(fn, env).map(_ => undefined);
}
function refTypeOfType(place: Place): RefAccessType {

View File

@@ -14,6 +14,7 @@ import {
Place,
} from '../HIR';
import {eachInstructionValueOperand} from '../HIR/visitors';
import {Result} from '../Utils/Result';
/**
* Validates against calling setState in the body of a *passive* effect (useEffect),
@@ -23,7 +24,9 @@ import {eachInstructionValueOperand} from '../HIR/visitors';
* often bad for performance and frequently has more efficient and straightforward
* alternatives. See https://react.dev/learn/you-might-not-need-an-effect for examples.
*/
export function validateNoSetStateInPassiveEffects(fn: HIRFunction): void {
export function validateNoSetStateInPassiveEffects(
fn: HIRFunction,
): Result<void, CompilerError> {
const setStateFunctions: Map<IdentifierId, Place> = new Map();
const errors = new CompilerError();
for (const [, block] of fn.body.blocks) {
@@ -98,9 +101,7 @@ export function validateNoSetStateInPassiveEffects(fn: HIRFunction): void {
}
}
if (errors.hasErrors()) {
throw errors;
}
return errors.asResult();
}
function getSetStateCall(

View File

@@ -9,7 +9,7 @@ import {CompilerError, ErrorSeverity} from '../CompilerError';
import {HIRFunction, IdentifierId, isSetStateType} from '../HIR';
import {computeUnconditionalBlocks} from '../HIR/ComputeUnconditionalBlocks';
import {eachInstructionValueOperand} from '../HIR/visitors';
import {Err, Ok, Result} from '../Utils/Result';
import {Result} from '../Utils/Result';
/**
* Validates that the given function does not have an infinite update loop
@@ -39,9 +39,11 @@ import {Err, Ok, Result} from '../Utils/Result';
* y();
* ```
*/
export function validateNoSetStateInRender(fn: HIRFunction): void {
export function validateNoSetStateInRender(
fn: HIRFunction,
): Result<void, CompilerError> {
const unconditionalSetStateFunctions: Set<IdentifierId> = new Set();
validateNoSetStateInRenderImpl(fn, unconditionalSetStateFunctions).unwrap();
return validateNoSetStateInRenderImpl(fn, unconditionalSetStateFunctions);
}
function validateNoSetStateInRenderImpl(
@@ -145,9 +147,5 @@ function validateNoSetStateInRenderImpl(
}
}
if (errors.hasErrors()) {
return Err(errors);
} else {
return Ok(undefined);
}
return errors.asResult();
}

View File

@@ -5,9 +5,10 @@
* LICENSE file in the root directory of this source tree.
*/
import {CompilerError, Effect, ErrorSeverity} from '..';
import {CompilerError, ErrorSeverity} from '../CompilerError';
import {
DeclarationId,
Effect,
GeneratedSource,
Identifier,
IdentifierId,
@@ -30,6 +31,7 @@ import {
ReactiveFunctionVisitor,
visitReactiveFunction,
} from '../ReactiveScopes/visitors';
import {Result} from '../Utils/Result';
import {getOrInsertDefault} from '../Utils/utils';
/**
@@ -39,15 +41,15 @@ import {getOrInsertDefault} from '../Utils/utils';
* This can occur if a value's mutable range somehow extended to include a hook and
* was pruned.
*/
export function validatePreservedManualMemoization(fn: ReactiveFunction): void {
export function validatePreservedManualMemoization(
fn: ReactiveFunction,
): Result<void, CompilerError> {
const state = {
errors: new CompilerError(),
manualMemoState: null,
};
visitReactiveFunction(fn, new Visitor(), state);
if (state.errors.hasErrors()) {
throw state.errors;
}
return state.errors.asResult();
}
const DEBUG = false;

View File

@@ -0,0 +1,83 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {CompilerError, ErrorSeverity} from '../CompilerError';
import {HIRFunction, IdentifierId, SourceLocation} from '../HIR';
import {Result} from '../Utils/Result';
/**
* Validates against components that are created dynamically and whose identity is not guaranteed
* to be stable (which would cause the component to reset on each re-render).
*/
export function validateStaticComponents(
fn: HIRFunction,
): Result<void, CompilerError> {
const error = new CompilerError();
const knownDynamicComponents = new Map<IdentifierId, SourceLocation>();
for (const block of fn.body.blocks.values()) {
phis: for (const phi of block.phis) {
for (const operand of phi.operands.values()) {
const loc = knownDynamicComponents.get(operand.identifier.id);
if (loc != null) {
knownDynamicComponents.set(phi.place.identifier.id, loc);
continue phis;
}
}
}
for (const instr of block.instructions) {
const {lvalue, value} = instr;
switch (value.kind) {
case 'FunctionExpression':
case 'NewExpression':
case 'MethodCall':
case 'CallExpression': {
knownDynamicComponents.set(lvalue.identifier.id, value.loc);
break;
}
case 'LoadLocal': {
const loc = knownDynamicComponents.get(value.place.identifier.id);
if (loc != null) {
knownDynamicComponents.set(lvalue.identifier.id, loc);
}
break;
}
case 'StoreLocal': {
const loc = knownDynamicComponents.get(value.value.identifier.id);
if (loc != null) {
knownDynamicComponents.set(lvalue.identifier.id, loc);
knownDynamicComponents.set(value.lvalue.place.identifier.id, loc);
}
break;
}
case 'JsxExpression': {
if (value.tag.kind === 'Identifier') {
const location = knownDynamicComponents.get(
value.tag.identifier.id,
);
if (location != null) {
error.push({
reason: `Components created during render will reset their state each time they are created. Declare components outside of render. `,
severity: ErrorSeverity.InvalidReact,
loc: value.tag.loc,
description: null,
suggestions: null,
});
error.push({
reason: `The component may be created during render`,
severity: ErrorSeverity.InvalidReact,
loc: location,
description: null,
suggestions: null,
});
}
}
}
}
}
}
return error.asResult();
}

View File

@@ -5,10 +5,12 @@
* LICENSE file in the root directory of this source tree.
*/
import {CompilerError} from '..';
import {CompilerError, ErrorSeverity} from '..';
import {FunctionExpression, HIRFunction, IdentifierId} from '../HIR';
import {Result} from '../Utils/Result';
export function validateUseMemo(fn: HIRFunction): void {
export function validateUseMemo(fn: HIRFunction): Result<void, CompilerError> {
const errors = new CompilerError();
const useMemos = new Set<IdentifierId>();
const react = new Set<IdentifierId>();
const functions = new Map<IdentifierId, FunctionExpression>();
@@ -61,7 +63,8 @@ export function validateUseMemo(fn: HIRFunction): void {
}
if (body.loweredFunc.func.params.length > 0) {
CompilerError.throwInvalidReact({
errors.push({
severity: ErrorSeverity.InvalidReact,
reason: 'useMemo callbacks may not accept any arguments',
description: null,
loc: body.loc,
@@ -70,7 +73,8 @@ export function validateUseMemo(fn: HIRFunction): void {
}
if (body.loweredFunc.func.async || body.loweredFunc.func.generator) {
CompilerError.throwInvalidReact({
errors.push({
severity: ErrorSeverity.InvalidReact,
reason:
'useMemo callbacks may not be async or generator functions',
description: null,
@@ -84,4 +88,5 @@ export function validateUseMemo(fn: HIRFunction): void {
}
}
}
return errors.asResult();
}

View File

@@ -12,6 +12,7 @@ globalThis.constantValue = 'global test value';
test('literal-constant-propagation', () => {
function Component() {
'use memo';
const x = 'test value 1';
return <div>{x}</div>;
}
@@ -38,6 +39,7 @@ test('literal-constant-propagation', () => {
test('global-constant-propagation', () => {
function Component() {
'use memo';
const x = constantValue;
return <div>{x}</div>;
@@ -65,6 +67,7 @@ test('global-constant-propagation', () => {
test('lambda-constant-propagation', () => {
function Component() {
'use memo';
const x = 'test value 1';
const getDiv = () => <div>{x}</div>;
return getDiv();
@@ -92,6 +95,7 @@ test('lambda-constant-propagation', () => {
test('lambda-constant-propagation-of-phi-node', () => {
function Component({noopCallback}) {
'use memo';
const x = 'test value 1';
if (constantValue) {
noopCallback();

View File

@@ -16,6 +16,7 @@ function Button({label}) {
let currentTheme = 'light';
function useTheme() {
'use memo';
return currentTheme;
}

View File

@@ -10,6 +10,7 @@ import * as React from 'react';
import {expectLogsAndClear, log} from './expectLogs';
function Counter(props) {
'use memo';
let value = props.value;
let a = value++;
expect(a).toBe(props.value); // postfix

View File

@@ -1,35 +0,0 @@
## Input
```javascript
// @gating
const ErrorView = (error, _retry) => <MessageBox error={error}></MessageBox>;
export default ErrorView;
```
## Code
```javascript
import { isForgetEnabled_Fixtures } from "ReactForgetFeatureFlag";
import { c as _c } from "react/compiler-runtime"; // @gating
const ErrorView = isForgetEnabled_Fixtures()
? (error, _retry) => {
const $ = _c(2);
let t0;
if ($[0] !== error) {
t0 = <MessageBox error={error} />;
$[0] = error;
$[1] = t0;
} else {
t0 = $[1];
}
return t0;
}
: (error, _retry) => <MessageBox error={error}></MessageBox>;
export default ErrorView;
```

View File

@@ -1,4 +0,0 @@
// @gating
const ErrorView = (error, _retry) => <MessageBox error={error}></MessageBox>;
export default ErrorView;

View File

@@ -0,0 +1,39 @@
## Input
```javascript
// @compilationMode(infer)
const Test = () => <div />;
export const FIXTURE_ENTRYPOINT = {
fn: Test,
params: [{}],
};
```
## Code
```javascript
import { c as _c } from "react/compiler-runtime"; // @compilationMode(infer)
const Test = () => {
const $ = _c(1);
let t0;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t0 = <div />;
$[0] = t0;
} else {
t0 = $[0];
}
return t0;
};
export const FIXTURE_ENTRYPOINT = {
fn: Test,
params: [{}],
};
```
### Eval output
(kind: ok) <div></div>

View File

@@ -0,0 +1,7 @@
// @compilationMode(infer)
const Test = () => <div />;
export const FIXTURE_ENTRYPOINT = {
fn: Test,
params: [{}],
};

View File

@@ -21,7 +21,7 @@ import {
import { c as _c } from "react/compiler-runtime"; // @enableEmitFreeze @enableEmitInstrumentForget
function useFoo(props) {
if (__DEV__ && shouldInstrument)
if (DEV && shouldInstrument)
useRenderCounter("useFoo", "/codegen-emit-imports-same-source.ts");
const $ = _c(2);
let t0;

View File

@@ -28,7 +28,7 @@ import { c as _c } from "react/compiler-runtime"; // @enableEmitInstrumentForget
function Bar(props) {
"use forget";
if (__DEV__ && shouldInstrument)
if (DEV && shouldInstrument)
useRenderCounter("Bar", "/codegen-instrument-forget-test.ts");
const $ = _c(2);
let t0;
@@ -48,7 +48,7 @@ function NoForget(props) {
function Foo(props) {
"use forget";
if (__DEV__ && shouldInstrument)
if (DEV && shouldInstrument)
useRenderCounter("Foo", "/codegen-instrument-forget-test.ts");
const $ = _c(2);
let t0;

View File

@@ -1,24 +0,0 @@
## Input
```javascript
// @flow @gating
component Foo(ref: React.RefSetter<Controls>) {
return <Bar ref={ref} />;
}
```
## Error
```
1 | // @flow @gating
> 2 | component Foo(ref: React.RefSetter<Controls>) {
| ^^^ Invariant: Encountered a function used before its declaration, which breaks Forget's gating codegen due to hoisting. Rewrite the reference to Foo_withRef to not rely on hoisting to fix this issue (2:2)
3 | return <Bar ref={ref} />;
4 | }
5 |
```

View File

@@ -1,4 +0,0 @@
// @flow @gating
component Foo(ref: React.RefSetter<Controls>) {
return <Bar ref={ref} />;
}

View File

@@ -1,26 +0,0 @@
## Input
```javascript
// @gating
const Foo = React.forwardRef(Foo_withRef);
function Foo_withRef(props, ref) {
return <Bar ref={ref} {...props}></Bar>;
}
```
## Error
```
1 | // @gating
2 | const Foo = React.forwardRef(Foo_withRef);
> 3 | function Foo_withRef(props, ref) {
| ^^^^^^^^^^^ Invariant: Encountered a function used before its declaration, which breaks Forget's gating codegen due to hoisting. Rewrite the reference to Foo_withRef to not rely on hoisting to fix this issue (3:3)
4 | return <Bar ref={ref} {...props}></Bar>;
5 | }
6 |
```

View File

@@ -1,5 +0,0 @@
// @gating
const Foo = React.forwardRef(Foo_withRef);
function Foo_withRef(props, ref) {
return <Bar ref={ref} {...props}></Bar>;
}

View File

@@ -1,24 +0,0 @@
## Input
```javascript
// @gating
import {memo} from 'react';
export default memo(Foo);
function Foo() {}
```
## Error
```
3 |
4 | export default memo(Foo);
> 5 | function Foo() {}
| ^^^ Invariant: Encountered a function used before its declaration, which breaks Forget's gating codegen due to hoisting. Rewrite the reference to Foo to not rely on hoisting to fix this issue (5:5)
6 |
```

View File

@@ -1,5 +0,0 @@
// @gating
import {memo} from 'react';
export default memo(Foo);
function Foo() {}

View File

@@ -1,38 +0,0 @@
## Input
```javascript
// @validateNoJSXInTryStatements
import {identity} from 'shared-runtime';
function Component(props) {
let el;
try {
let value;
try {
value = identity(props.foo);
} catch {
el = <div value={value} />;
}
} catch {
return null;
}
return el;
}
```
## Error
```
9 | value = identity(props.foo);
10 | } catch {
> 11 | el = <div value={value} />;
| ^^^^^^^^^^^^^^^^^^^^^ InvalidReact: Unexpected JSX element within a try statement. To catch errors in rendering a given component, wrap that component in an error boundary. (https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary) (11:11)
12 | }
13 | } catch {
14 | return null;
```

View File

@@ -1,31 +0,0 @@
## Input
```javascript
// @validateNoJSXInTryStatements
function Component(props) {
let el;
try {
el = <div />;
} catch {
return null;
}
return el;
}
```
## Error
```
3 | let el;
4 | try {
> 5 | el = <div />;
| ^^^^^^^ InvalidReact: Unexpected JSX element within a try statement. To catch errors in rendering a given component, wrap that component in an error boundary. (https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary) (5:5)
6 | } catch {
7 | return null;
8 | }
```

View File

@@ -1,37 +0,0 @@
## Input
```javascript
// @validateNoSetStateInPassiveEffects
import {useEffect, useState} from 'react';
function Component() {
const [state, setState] = useState(0);
const f = () => {
setState(s => s + 1);
};
const g = () => {
f();
};
useEffect(() => {
g();
});
return state;
}
```
## Error
```
11 | };
12 | useEffect(() => {
> 13 | g();
| ^ InvalidReact: Calling setState directly within a useEffect causes cascading renders and is not recommended. Consider alternatives to useEffect. (https://react.dev/learn/you-might-not-need-an-effect) (13:13)
14 | });
15 | return state;
16 | }
```

View File

@@ -1,31 +0,0 @@
## Input
```javascript
// @validateNoSetStateInPassiveEffects
import {useEffect, useState} from 'react';
function Component() {
const [state, setState] = useState(0);
useEffect(() => {
setState(s => s + 1);
});
return state;
}
```
## Error
```
5 | const [state, setState] = useState(0);
6 | useEffect(() => {
> 7 | setState(s => s + 1);
| ^^^^^^^^ InvalidReact: Calling setState directly within a useEffect causes cascading renders and is not recommended. Consider alternatives to useEffect. (https://react.dev/learn/you-might-not-need-an-effect) (7:7)
8 | });
9 | return state;
10 | }
```

View File

@@ -23,11 +23,11 @@ import { c as _c } from "react/compiler-runtime";
function Component(props) {
const $ = _c(4);
let t0;
if ($[0] !== props.name) {
if ($[0] !== props) {
t0 = function () {
return <div>{props.name}</div>;
};
$[0] = props.name;
$[0] = props;
$[1] = t0;
} else {
t0 = $[1];

View File

@@ -1,14 +0,0 @@
// @gating @compilationMode(annotation)
export default function Bar(props) {
'use forget';
return <div>{props.bar}</div>;
}
function NoForget(props) {
return <Bar>{props.noForget}</Bar>;
}
export function Foo(props) {
'use forget';
return <Foo>{props.bar}</Foo>;
}

View File

@@ -0,0 +1,50 @@
## Input
```javascript
// @gating
import {Stringify} from 'shared-runtime';
const ErrorView = ({error, _retry}) => <Stringify error={error}></Stringify>;
export default ErrorView;
export const FIXTURE_ENTRYPOINT = {
fn: eval('ErrorView'),
params: [{}],
};
```
## Code
```javascript
import { isForgetEnabled_Fixtures } from "ReactForgetFeatureFlag";
import { c as _c } from "react/compiler-runtime"; // @gating
import { Stringify } from "shared-runtime";
const ErrorView = isForgetEnabled_Fixtures()
? (t0) => {
const $ = _c(2);
const { error } = t0;
let t1;
if ($[0] !== error) {
t1 = <Stringify error={error} />;
$[0] = error;
$[1] = t1;
} else {
t1 = $[1];
}
return t1;
}
: ({ error, _retry }) => <Stringify error={error}></Stringify>;
export default ErrorView;
export const FIXTURE_ENTRYPOINT = {
fn: eval("ErrorView"),
params: [{}],
};
```
### Eval output
(kind: ok) <div>{}</div>

View File

@@ -0,0 +1,10 @@
// @gating
import {Stringify} from 'shared-runtime';
const ErrorView = ({error, _retry}) => <Stringify error={error}></Stringify>;
export default ErrorView;
export const FIXTURE_ENTRYPOINT = {
fn: eval('ErrorView'),
params: [{}],
};

View File

@@ -15,9 +15,22 @@ function NoForget(props) {
function Foo(props) {
'use forget';
return <Foo>{props.bar}</Foo>;
if (props.bar < 0) {
return props.children;
}
return (
<Foo bar={props.bar - 1}>
<NoForget />
</Foo>
);
}
global.DEV = true;
export const FIXTURE_ENTRYPOINT = {
fn: eval('Foo'),
params: [{bar: 2}],
};
```
## Code
@@ -29,7 +42,7 @@ import { c as _c } from "react/compiler-runtime"; // @enableEmitInstrumentForget
const Bar = isForgetEnabled_Fixtures()
? function Bar(props) {
"use forget";
if (__DEV__ && shouldInstrument)
if (DEV && shouldInstrument)
useRenderCounter("Bar", "/codegen-instrument-forget-gating-test.ts");
const $ = _c(2);
let t0;
@@ -53,23 +66,50 @@ function NoForget(props) {
const Foo = isForgetEnabled_Fixtures()
? function Foo(props) {
"use forget";
if (__DEV__ && shouldInstrument)
if (DEV && shouldInstrument)
useRenderCounter("Foo", "/codegen-instrument-forget-gating-test.ts");
const $ = _c(2);
let t0;
if ($[0] !== props.bar) {
t0 = <Foo>{props.bar}</Foo>;
$[0] = props.bar;
$[1] = t0;
} else {
t0 = $[1];
const $ = _c(3);
if (props.bar < 0) {
return props.children;
}
return t0;
const t0 = props.bar - 1;
let t1;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t1 = <NoForget />;
$[0] = t1;
} else {
t1 = $[0];
}
let t2;
if ($[1] !== t0) {
t2 = <Foo bar={t0}>{t1}</Foo>;
$[1] = t0;
$[2] = t2;
} else {
t2 = $[2];
}
return t2;
}
: function Foo(props) {
"use forget";
return <Foo>{props.bar}</Foo>;
if (props.bar < 0) {
return props.children;
}
return (
<Foo bar={props.bar - 1}>
<NoForget />
</Foo>
);
};
global.DEV = true;
export const FIXTURE_ENTRYPOINT = {
fn: eval("Foo"),
params: [{ bar: 2 }],
};
```
### Eval output
(kind: ok) <div></div>

View File

@@ -11,5 +11,18 @@ function NoForget(props) {
function Foo(props) {
'use forget';
return <Foo>{props.bar}</Foo>;
if (props.bar < 0) {
return props.children;
}
return (
<Foo bar={props.bar - 1}>
<NoForget />
</Foo>
);
}
global.DEV = true;
export const FIXTURE_ENTRYPOINT = {
fn: eval('Foo'),
params: [{bar: 2}],
};

View File

@@ -0,0 +1,62 @@
## Input
```javascript
// @flow @gating
import {Stringify} from 'shared-runtime';
import * as React from 'react';
component Foo(ref: React.RefSetter<Controls>) {
return <Stringify ref={ref} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: eval('(...args) => React.createElement(Foo, args)'),
params: [{ref: React.createRef()}],
};
```
## Code
```javascript
import { isForgetEnabled_Fixtures } from "ReactForgetFeatureFlag";
import { c as _c } from "react/compiler-runtime";
import { Stringify } from "shared-runtime";
import * as React from "react";
const Foo = React.forwardRef(Foo_withRef);
const _isForgetEnabled_Fixtures_result = isForgetEnabled_Fixtures();
function _Foo_withRef_optimized(_$$empty_props_placeholder$$, ref) {
const $ = _c(2);
let t0;
if ($[0] !== ref) {
t0 = <Stringify ref={ref} />;
$[0] = ref;
$[1] = t0;
} else {
t0 = $[1];
}
return t0;
}
function _Foo_withRef_unoptimized(
_$$empty_props_placeholder$$: $ReadOnly<{}>,
ref: React.RefSetter<Controls>,
): React.Node {
return <Stringify ref={ref} />;
}
function Foo_withRef(arg0, arg1) {
if (_isForgetEnabled_Fixtures_result)
return _Foo_withRef_optimized(arg0, arg1);
else return _Foo_withRef_unoptimized(arg0, arg1);
}
export const FIXTURE_ENTRYPOINT = {
fn: eval("(...args) => React.createElement(Foo, args)"),
params: [{ ref: React.createRef() }],
};
```
### Eval output
(kind: ok) <div>{"ref":null}</div>

View File

@@ -0,0 +1,12 @@
// @flow @gating
import {Stringify} from 'shared-runtime';
import * as React from 'react';
component Foo(ref: React.RefSetter<Controls>) {
return <Stringify ref={ref} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: eval('(...args) => React.createElement(Foo, args)'),
params: [{ref: React.createRef()}],
};

View File

@@ -0,0 +1,60 @@
## Input
```javascript
// @gating
import {identity, useHook as useRenamed} from 'shared-runtime';
const _ = {
useHook: () => {},
};
identity(_.useHook);
function useHook() {
useRenamed();
return <div>hello world!</div>;
}
export const FIXTURE_ENTRYPOINT = {
fn: useHook,
params: [{}],
};
```
## Code
```javascript
import { isForgetEnabled_Fixtures } from "ReactForgetFeatureFlag";
import { c as _c } from "react/compiler-runtime"; // @gating
import { identity, useHook as useRenamed } from "shared-runtime";
const _ = {
useHook: isForgetEnabled_Fixtures() ? () => {} : () => {},
};
identity(_.useHook);
const useHook = isForgetEnabled_Fixtures()
? function useHook() {
const $ = _c(1);
useRenamed();
let t0;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t0 = <div>hello world!</div>;
$[0] = t0;
} else {
t0 = $[0];
}
return t0;
}
: function useHook() {
useRenamed();
return <div>hello world!</div>;
};
export const FIXTURE_ENTRYPOINT = {
fn: useHook,
params: [{}],
};
```
### Eval output
(kind: ok) <div>hello world!</div>

View File

@@ -0,0 +1,16 @@
// @gating
import {identity, useHook as useRenamed} from 'shared-runtime';
const _ = {
useHook: () => {},
};
identity(_.useHook);
function useHook() {
useRenamed();
return <div>hello world!</div>;
}
export const FIXTURE_ENTRYPOINT = {
fn: useHook,
params: [{}],
};

View File

@@ -17,6 +17,11 @@ function Foo(props) {
return <Foo>{props.bar}</Foo>;
}
export const FIXTURE_ENTRYPOINT = {
fn: eval('Bar'),
params: [{bar: 2}],
};
```
## Code
@@ -66,5 +71,12 @@ const Foo = isForgetEnabled_Fixtures()
return <Foo>{props.bar}</Foo>;
};
export const FIXTURE_ENTRYPOINT = {
fn: eval("Bar"),
params: [{ bar: 2 }],
};
```
### Eval output
(kind: ok) <div>2</div>

View File

@@ -12,3 +12,8 @@ function Foo(props) {
'use forget';
return <Foo>{props.bar}</Foo>;
}
export const FIXTURE_ENTRYPOINT = {
fn: eval('Bar'),
params: [{bar: 2}],
};

View File

@@ -12,11 +12,23 @@ function NoForget(props) {
return <Bar>{props.noForget}</Bar>;
}
export function Foo(props) {
function Foo(props) {
'use forget';
return <Foo>{props.bar}</Foo>;
if (props.bar < 0) {
return props.children;
}
return (
<Foo bar={props.bar - 1}>
<NoForget />
</Foo>
);
}
export const FIXTURE_ENTRYPOINT = {
fn: eval('Bar'),
params: [{bar: 2}],
};
```
## Code
@@ -47,25 +59,50 @@ export default Bar;
function NoForget(props) {
return <Bar>{props.noForget}</Bar>;
}
export const Foo = isForgetEnabled_Fixtures()
const Foo = isForgetEnabled_Fixtures()
? function Foo(props) {
"use forget";
const $ = _c(2);
let t0;
if ($[0] !== props.bar) {
t0 = <Foo>{props.bar}</Foo>;
$[0] = props.bar;
$[1] = t0;
} else {
t0 = $[1];
const $ = _c(3);
if (props.bar < 0) {
return props.children;
}
return t0;
const t0 = props.bar - 1;
let t1;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t1 = <NoForget />;
$[0] = t1;
} else {
t1 = $[0];
}
let t2;
if ($[1] !== t0) {
t2 = <Foo bar={t0}>{t1}</Foo>;
$[1] = t0;
$[2] = t2;
} else {
t2 = $[2];
}
return t2;
}
: function Foo(props) {
"use forget";
return <Foo>{props.bar}</Foo>;
if (props.bar < 0) {
return props.children;
}
return (
<Foo bar={props.bar - 1}>
<NoForget />
</Foo>
);
};
export const FIXTURE_ENTRYPOINT = {
fn: eval("Bar"),
params: [{ bar: 2 }],
};
```
### Eval output
(kind: ok) <div>2</div>

View File

@@ -0,0 +1,26 @@
// @gating @compilationMode(annotation)
export default function Bar(props) {
'use forget';
return <div>{props.bar}</div>;
}
function NoForget(props) {
return <Bar>{props.noForget}</Bar>;
}
function Foo(props) {
'use forget';
if (props.bar < 0) {
return props.children;
}
return (
<Foo bar={props.bar - 1}>
<NoForget />
</Foo>
);
}
export const FIXTURE_ENTRYPOINT = {
fn: eval('Bar'),
params: [{bar: 2}],
};

View File

@@ -17,6 +17,11 @@ export function Foo(props) {
return <Foo>{props.bar}</Foo>;
}
export const FIXTURE_ENTRYPOINT = {
fn: eval('Bar'),
params: [{bar: 2}],
};
```
## Code
@@ -66,5 +71,12 @@ export const Foo = isForgetEnabled_Fixtures()
return <Foo>{props.bar}</Foo>;
};
export const FIXTURE_ENTRYPOINT = {
fn: eval("Bar"),
params: [{ bar: 2 }],
};
```
### Eval output
(kind: ok) <div>2</div>

View File

@@ -12,3 +12,8 @@ export function Foo(props) {
'use forget';
return <Foo>{props.bar}</Foo>;
}
export const FIXTURE_ENTRYPOINT = {
fn: eval('Bar'),
params: [{bar: 2}],
};

View File

@@ -17,6 +17,11 @@ function Foo(props) {
return <Foo>{props.bar}</Foo>;
}
export const FIXTURE_ENTRYPOINT = {
fn: eval('Bar'),
params: [{bar: 2}],
};
```
## Code
@@ -65,5 +70,12 @@ const Foo = isForgetEnabled_Fixtures()
return <Foo>{props.bar}</Foo>;
};
export const FIXTURE_ENTRYPOINT = {
fn: eval("Bar"),
params: [{ bar: 2 }],
};
```
### Eval output
(kind: ok) <div>2</div>

View File

@@ -12,3 +12,8 @@ function Foo(props) {
'use forget';
return <Foo>{props.bar}</Foo>;
}
export const FIXTURE_ENTRYPOINT = {
fn: eval('Bar'),
params: [{bar: 2}],
};

View File

@@ -0,0 +1,61 @@
## Input
```javascript
// @gating
import {createRef, forwardRef} from 'react';
import {Stringify} from 'shared-runtime';
const Foo = forwardRef(Foo_withRef);
function Foo_withRef(props, ref) {
return <Stringify ref={ref} {...props} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: eval('(...args) => React.createElement(Foo, args)'),
params: [{prop1: 1, prop2: 2, ref: createRef()}],
};
```
## Code
```javascript
import { isForgetEnabled_Fixtures } from "ReactForgetFeatureFlag";
import { c as _c } from "react/compiler-runtime"; // @gating
import { createRef, forwardRef } from "react";
import { Stringify } from "shared-runtime";
const Foo = forwardRef(Foo_withRef);
const _isForgetEnabled_Fixtures_result = isForgetEnabled_Fixtures();
function _Foo_withRef_optimized(props, ref) {
const $ = _c(3);
let t0;
if ($[0] !== props || $[1] !== ref) {
t0 = <Stringify ref={ref} {...props} />;
$[0] = props;
$[1] = ref;
$[2] = t0;
} else {
t0 = $[2];
}
return t0;
}
function _Foo_withRef_unoptimized(props, ref) {
return <Stringify ref={ref} {...props} />;
}
function Foo_withRef(arg0, arg1) {
if (_isForgetEnabled_Fixtures_result)
return _Foo_withRef_optimized(arg0, arg1);
else return _Foo_withRef_unoptimized(arg0, arg1);
}
export const FIXTURE_ENTRYPOINT = {
fn: eval("(...args) => React.createElement(Foo, args)"),
params: [{ prop1: 1, prop2: 2, ref: createRef() }],
};
```
### Eval output
(kind: ok) <div>{"0":{"prop1":1,"prop2":2,"ref":{"current":null}},"ref":"[[ cyclic ref *3 ]]"}</div>

View File

@@ -0,0 +1,13 @@
// @gating
import {createRef, forwardRef} from 'react';
import {Stringify} from 'shared-runtime';
const Foo = forwardRef(Foo_withRef);
function Foo_withRef(props, ref) {
return <Stringify ref={ref} {...props} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: eval('(...args) => React.createElement(Foo, args)'),
params: [{prop1: 1, prop2: 2, ref: createRef()}],
};

View File

@@ -0,0 +1,64 @@
## Input
```javascript
// @gating
import {memo} from 'react';
import {Stringify} from 'shared-runtime';
export default memo(Foo);
function Foo({prop1, prop2}) {
'use memo';
return <Stringify prop1={prop1} prop2={prop2} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: eval('Foo'),
params: [{prop1: 1, prop2: 2}],
};
```
## Code
```javascript
import { isForgetEnabled_Fixtures } from "ReactForgetFeatureFlag";
import { c as _c } from "react/compiler-runtime"; // @gating
import { memo } from "react";
import { Stringify } from "shared-runtime";
export default memo(Foo);
const _isForgetEnabled_Fixtures_result = isForgetEnabled_Fixtures();
function _Foo_optimized(t0) {
"use memo";
const $ = _c(3);
const { prop1, prop2 } = t0;
let t1;
if ($[0] !== prop1 || $[1] !== prop2) {
t1 = <Stringify prop1={prop1} prop2={prop2} />;
$[0] = prop1;
$[1] = prop2;
$[2] = t1;
} else {
t1 = $[2];
}
return t1;
}
function _Foo_unoptimized({ prop1, prop2 }) {
"use memo";
return <Stringify prop1={prop1} prop2={prop2} />;
}
function Foo(arg0) {
if (_isForgetEnabled_Fixtures_result) return _Foo_optimized(arg0);
else return _Foo_unoptimized(arg0);
}
export const FIXTURE_ENTRYPOINT = {
fn: eval("Foo"),
params: [{ prop1: 1, prop2: 2 }],
};
```
### Eval output
(kind: ok) <div>{"prop1":1,"prop2":2}</div>

Some files were not shown because too many files have changed in this diff Show More