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 }} cancel-in-progress: true 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 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 runs-on: ubuntu-latest outputs: matrix: ${{ steps.set-matrix.outputs.result }} 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 }} - uses: actions/github-script@v7 id: set-matrix with: script: | const inlinedHostConfigs = require('./scripts/shared/inlinedHostConfigs.js'); return inlinedHostConfigs.map(config => config.shortName); flow: name: Flow check ${{ matrix.flow_inline_config_shortname }} needs: [discover_flow_inline_configs, runtime_node_modules_cache] runs-on: ubuntu-latest strategy: fail-fast: false matrix: flow_inline_config_shortname: ${{ fromJSON(needs.discover_flow_inline_configs.outputs.matrix) }} 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 }} - 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/restore@v4 id: node_modules 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. - 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.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/restore@v4 id: node_modules 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. - 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 --exit-code || (echo "There was a change to the Fizz runtime. Run \`yarn generate-inline-fizz-runtime\` and check in the result." && false) # ----- FEATURE FLAGS ----- flags: name: Check flags needs: [runtime_node_modules_cache] 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 }} - 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/restore@v4 id: node_modules with: 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 matrix: params: - "-r=stable --env=development" - "-r=stable --env=production" - "-r=experimental --env=development" - "-r=experimental --env=production" - "-r=www-classic --env=development --variant=false" - "-r=www-classic --env=production --variant=false" - "-r=www-classic --env=development --variant=true" - "-r=www-classic --env=production --variant=true" - "-r=www-modern --env=development --variant=false" - "-r=www-modern --env=production --variant=false" - "-r=www-modern --env=development --variant=true" - "-r=www-modern --env=production --variant=true" - "-r=xplat --env=development --variant=false" - "-r=xplat --env=development --variant=true" - "-r=xplat --env=production --variant=false" - "-r=xplat --env=production --variant=true" # TODO: Test more persistent configurations? - "-r=stable --env=development --persistent" - "-r=experimental --env=development --persistent" shard: - 1/5 - 2/5 - 3/5 - 4/5 - 5/5 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 }} - 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/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-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,20,21,22,23,24] release_channel: [stable, experimental] 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 }} - uses: actions/setup-node@v4 with: node-version-file: '.nvmrc' cache: yarn 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/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 build --index=${{ matrix.worker_id }} --total=25 --r=${{ matrix.release_channel }} --ci env: CI: github RELEASE_CHANNEL: ${{ matrix.release_channel }} NODE_INDEX: ${{ matrix.worker_id }} - name: Lint build run: yarn lint-build - name: Display structure of build run: ls -R build - name: Archive build uses: actions/upload-artifact@v4 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, runtime_compiler_node_modules_cache] strategy: fail-fast: false matrix: test_params: [ # Intentionally passing these as strings instead of creating a # separate parameter per CLI argument, since it's easier to # control/see which combinations we want to run. -r=stable --env=development, -r=stable --env=production, -r=experimental --env=development, -r=experimental --env=production, # Dev Tools --project=devtools -r=experimental, # TODO: Update test config to support www build tests # - "-r=www-classic --env=development --variant=false" # - "-r=www-classic --env=production --variant=false" # - "-r=www-classic --env=development --variant=true" # - "-r=www-classic --env=production --variant=true" # - "-r=www-modern --env=development --variant=false" # - "-r=www-modern --env=production --variant=false" # - "-r=www-modern --env=development --variant=true" # - "-r=www-modern --env=production --variant=true" # TODO: Update test config to support xplat build tests # - "-r=xplat --env=development --variant=false" # - "-r=xplat --env=development --variant=true" # - "-r=xplat --env=production --variant=false" # - "-r=xplat --env=production --variant=true" # TODO: Test more persistent configurations? ] shard: - 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.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 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' - name: Restore archived build uses: actions/download-artifact@v4 with: pattern: _build_* path: build merge-multiple: true - name: Display structure of build run: ls -R build - run: yarn test --build ${{ matrix.test_params }} --shard=${{ matrix.shard }} --ci process_artifacts_combined: name: Process artifacts combined needs: [build_and_lint, runtime_node_modules_cache] permissions: # https://github.com/actions/attest-build-provenance id-token: write attestations: write 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 }} - 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/restore@v4 id: node_modules 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. - 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: pattern: _build_* path: build merge-multiple: true - name: Display structure of build run: ls -R build - 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__ node ./scripts/print-warnings/print-warnings.js > build/__test_utils__/ReactAllWarnings.js # Compress build directory into a single tarball for easy download - run: tar -zcvf ./build.tgz ./build # TODO: Migrate scripts to use `build` directory instead of `build2` - run: cp ./build.tgz ./build2.tgz - name: Archive build artifacts id: upload_artifacts_combined uses: actions/upload-artifact@v4 with: name: artifacts_combined path: | ./build.tgz ./build2.tgz if-no-files-found: error - uses: actions/attest-build-provenance@v2 # We don't verify builds generated from pull requests not originating from facebook/react. # However, if the PR lands, the run on `main` will generate the attestation which can then # be used to download a build via scripts/release/download-experimental-build.js. # # Note that this means that scripts/release/download-experimental-build.js must be run with # --no-verify when downloading a build from a fork. if: github.event_name == 'push' && github.ref_name == 'main' || github.event.pull_request.head.repo.full_name == github.repository with: subject-name: artifacts_combined.zip subject-digest: sha256:${{ steps.upload_artifacts_combined.outputs.artifact-digest }} check_error_codes: name: Search build artifacts for unminified errors needs: [build_and_lint, runtime_node_modules_cache] 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 }} - 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/restore@v4 id: node_modules 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. - 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: pattern: _build_* path: build merge-multiple: true - name: Display structure of build run: ls -R build - name: Search build artifacts for unminified errors run: | yarn extract-errors git diff --exit-code || (echo "Found unminified errors. Either update the error codes map or disable error minification for the affected build, if appropriate." && false) check_release_dependencies: name: Check release dependencies needs: [build_and_lint, runtime_node_modules_cache] 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 }} - 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/restore@v4 id: node_modules 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. - 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: pattern: _build_* path: build merge-multiple: true - name: Display structure of build run: ls -R build - run: yarn check-release-dependencies RELEASE_CHANNEL_stable_yarn_test_dom_fixtures: name: Check fixtures DOM (stable) needs: build_and_lint 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 }} - 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 # 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-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'fixtures/dom/yarn.lock') }} - name: Ensure clean build directory run: rm -rf build - 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: pattern: _build_* path: build merge-multiple: true - name: Display structure of build run: ls -R build - name: Run DOM fixture tests run: | yarn predev yarn test working-directory: fixtures/dom env: RELEASE_CHANNEL: stable # ----- FLIGHT ----- run_fixtures_flight_tests: name: Run fixtures Flight tests needs: build_and_lint 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 }} - uses: actions/setup-node@v4 with: node-version-file: '.nvmrc' cache: yarn cache-dependency-path: yarn.lock # Fixture copies some built packages from the workroot after install. # 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 # 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-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: pattern: _build_* path: build merge-multiple: true - name: Display structure of build run: ls -R build - name: Run tests working-directory: fixtures/flight run: yarn test env: # Otherwise the webserver is a blackbox DEBUG: pw:webserver - name: Archive Flight fixture artifacts uses: actions/upload-artifact@v4 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, runtime_node_modules_cache] runs-on: ubuntu-latest strategy: fail-fast: false matrix: browser: [chrome, firefox, edge] 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 }} - 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/restore@v4 id: node_modules 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. - 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: pattern: _build_* path: build merge-multiple: true - run: ./scripts/ci/pack_and_store_devtools_artifacts.sh ${{ matrix.browser }} env: RELEASE_CHANNEL: experimental - name: Display structure of build run: ls -R build # Simplifies getting the extension for local testing - name: Archive ${{ matrix.browser }} extension uses: actions/upload-artifact@v4 with: name: react-devtools-${{ matrix.browser }}-extension path: build/devtools/${{ matrix.browser }}-extension.zip if-no-files-found: error - name: Archive ${{ matrix.browser }} metadata uses: actions/upload-artifact@v4 with: name: react-devtools-${{ matrix.browser }}-metadata path: build/devtools/webpack-stats.*.json merge_devtools_artifacts: name: Merge DevTools artifacts needs: build_devtools_and_process_artifacts runs-on: ubuntu-latest steps: - name: Merge artifacts uses: actions/upload-artifact/merge@v4 with: name: react-devtools pattern: react-devtools-* run_devtools_e2e_tests: name: Run DevTools e2e tests needs: [build_and_lint, runtime_node_modules_cache] 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 }} - 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/restore@v4 id: node_modules 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. - 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: pattern: _build_* path: build merge-multiple: 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' run: npx playwright install --with-deps chromium - run: ./scripts/ci/run_devtools_e2e_tests.js env: RELEASE_CHANNEL: experimental - name: Archive Playwright report uses: actions/upload-artifact@v4 with: name: devtools-playwright-artifacts path: tmp/playwright-artifacts if-no-files-found: warn # ----- SIZEBOT ----- sizebot: 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.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 # note: this does not reuse centralized cache since it has unique cache key 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 # The build could have been generated from a fork, so we must download the build without # any verification. This is safe since we only use this for sizebot calculation and the # unverified artifact is not used. Additionally this workflow runs in the pull_request # trigger so only restricted permissions are available. run: | GH_TOKEN=${{ github.token }} scripts/release/download-experimental-build.js --commit=$(git rev-parse ${{ github.event.pull_request.base.sha }}) ${{ (github.event.pull_request.head.repo.full_name != github.repository && '--noVerify') || ''}} mv ./build ./base-build - name: Delete extraneous files # TODO: The `download-experimental-build` script copies the npm # packages into the `node_modules` directory. This is a historical # quirk of how the release script works. Let's pretend they # don't exist. run: rm -rf ./base-build/node_modules - name: Display structure of base-build from origin/main run: ls -R base-build - name: Ensure clean build directory run: rm -rf build - name: Restore archived build for PR uses: actions/download-artifact@v4 with: pattern: _build_* path: build merge-multiple: true - name: Scrape warning messages run: | mkdir -p ./build/__test_utils__ 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.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