Skip to content

perf(core): enable rspack experiments.nativeWatcher #4669

perf(core): enable rspack experiments.nativeWatcher

perf(core): enable rspack experiments.nativeWatcher #4669

Workflow file for this run

name: Test
on:
pull_request:
branches: [main]
push:
branches: [main]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: ${{ github.ref_name != 'main' }}
permissions:
contents: read
env:
# Configure Node.js memory limit to 6GB (default GitHub Actions limit is 7GB)
NODE_OPTIONS: --max-old-space-size=6144
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
changed: ${{ steps.changes.outputs.changed }}
# Full e2e sweep: push to main (post-merge gate) or release PR (pre-publish gate)
is_full_run: ${{ github.event_name == 'push' || startsWith(github.event.pull_request.title, 'release:') }}
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 1
- uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
id: changes
with:
predicate-quantifier: 'every'
filters: |
changed:
- "!**/*.md"
- "!**/*.mdx"
- "!**/_meta.json"
- "!**/dictionary.txt"
# ======== lint ========
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 1
- name: Install pnpm
run: |
npm install -g corepack@latest --force
corepack enable
- name: Setup Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 22
cache: 'pnpm'
- name: Install Dependencies
run: pnpm install --ignore-scripts
- name: Build Packages
run: pnpm run build
- name: Lint
run: pnpm run lint
- name: Check Dependency Version
run: pnpm run check-dependency-version
- name: Check pnpm Dedupe
run: pnpm dedupe --check --config.minimum-release-age=0
- name: Check Unused Code
run: pnpm run check-unused
# ======== ut ========
ut:
needs: prepare
if: needs.prepare.outputs.changed == 'true'
runs-on: ${{ matrix.os }}
timeout-minutes: 15
strategy:
matrix:
# run ut in macOS, as SWC cases will fail in Ubuntu CI
os: [macos-14, windows-latest]
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 1
- name: Setup pnpm
uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
- name: Setup Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 22
cache: 'pnpm'
cache-dependency-path: pnpm-lock.yaml
- name: pnpm fetch
run: pnpm fetch
- name: Install Dependencies
run: pnpm install --frozen-lockfile --prefer-offline
- name: Set Playwright cache path
shell: bash
run: |
if [ "$RUNNER_OS" = "Windows" ]; then
echo "PLAYWRIGHT_BROWSERS_PATH=$USERPROFILE/AppData/Local/ms-playwright" >> "$GITHUB_ENV"
else
echo "PLAYWRIGHT_BROWSERS_PATH=$HOME/Library/Caches/ms-playwright" >> "$GITHUB_ENV"
fi
- name: Cache Playwright Browsers
continue-on-error: true
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ${{ env.PLAYWRIGHT_BROWSERS_PATH }}
key: playwright-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
- name: Install Playwright Browsers
run: npx playwright install chromium webkit
- name: Run Type Check
run: pnpm run typecheck
- name: Run Test
run: pnpm run test
- name: Run Examples Test
run: pnpm run test:examples
# ======== e2e ========
e2e:
needs: [prepare, lint, ut]
if: needs.prepare.outputs.changed == 'true'
runs-on: ${{ matrix.os }}
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
# run ut in macOS, as SWC cases will fail in Ubuntu CI
os: [macos-14, windows-latest]
# Trigger-dependent axes (gated by prepare.outputs.is_full_run):
#
# trigger | node_version | test_script | exclude
# -------------+--------------+---------------------------------------+-----------
# PR (regular) | [20, 24] | [test] | -
# push to main | [20, 22, 24] | [test, commonjs, no-isolate, threads] | test × 22
# release PR | [20, 22, 24] | [test, commonjs, no-isolate, threads] | test × 22
#
# Node 20 + test:no-isolate can hit upstream vm native crashes under worker
# reuse; tolerated on full runs in exchange for coverage.
node_version: >-
${{ fromJson(
needs.prepare.outputs.is_full_run == 'true'
&& '["20","22","24"]'
|| '["20","24"]'
) }}
test_script: >-
${{ fromJson(
needs.prepare.outputs.is_full_run == 'true'
&& '["test","test:commonjs","test:no-isolate","test:threads"]'
|| '["test"]'
) }}
exclude: >-
${{ fromJson(
needs.prepare.outputs.is_full_run == 'true'
&& '[{"node_version":"22","test_script":"test"}]'
|| '[]'
) }}
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 1
- name: Setup pnpm
uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
- name: Setup Node.js ${{ matrix.node_version }}
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: ${{ matrix.node_version }}
cache: 'pnpm'
cache-dependency-path: pnpm-lock.yaml
- name: pnpm fetch
run: pnpm fetch
- name: Install Dependencies
run: pnpm install --frozen-lockfile --prefer-offline
- name: Set Playwright cache path
shell: bash
run: |
if [ "$RUNNER_OS" = "Windows" ]; then
echo "PLAYWRIGHT_BROWSERS_PATH=$USERPROFILE/AppData/Local/ms-playwright" >> "$GITHUB_ENV"
else
echo "PLAYWRIGHT_BROWSERS_PATH=$HOME/Library/Caches/ms-playwright" >> "$GITHUB_ENV"
fi
- name: Cache Playwright Browsers
continue-on-error: true
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ${{ env.PLAYWRIGHT_BROWSERS_PATH }}
key: playwright-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
- name: Install Playwright Browsers
run: npx playwright install chromium webkit
- name: E2E Test (${{ matrix.test_script }})
run: cd e2e && pnpm ${{ matrix.test_script }}
- name: VS Code Extension Test
if: matrix.test_script == 'test'
run: pnpm run test:vscode
# ======== stress test with RSPACK_WATCHER_TRACE ========
# macOS polling=on × unique-dir on/off × 20 rounds × node 22/24 = 80 jobs.
# We focus on the residual nativeWatcher flake (polling=off failures are
# unrelated chokidar issues already explained). All jobs set
# RSPACK_WATCHER_TRACE=1 so failing jobs dump the full event pipeline log.
stress-restart:
needs: prepare
if: needs.prepare.outputs.changed == 'true'
runs-on: macos-14
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
node_version: ['22', '24']
round:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
unique_dir: ['on', 'off']
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 1
- name: Setup pnpm
uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
- name: Setup Node.js ${{ matrix.node_version }}
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: ${{ matrix.node_version }}
cache: 'pnpm'
cache-dependency-path: pnpm-lock.yaml
- name: Install Dependencies
run: pnpm install --frozen-lockfile --prefer-offline
- name: Stress all watch tests
env:
STRESS_NO_UNIQUE_DIR: ${{ matrix.unique_dir == 'off' && '1' || '' }}
run: cd e2e && pnpm exec rstest run watch/
# ======== codspeed ========
# Temporarily disabled: CodSpeed runner quota exhausted.
# Re-enable once quota resets.
codspeed:
needs: e2e
if: false
permissions:
actions: read
contents: read
id-token: write
uses: ./.github/workflows/codspeed.yml
with:
ref: ${{ github.sha }}
# ======== gate ========
test-gate:
needs: [prepare, lint, ut, e2e]
if: always()
runs-on: ubuntu-latest
steps:
- name: Check test requirement
run: |
for result in \
"${{ needs.lint.result }}" \
"${{ needs.ut.result }}" \
"${{ needs.e2e.result }}"; do
if [ "$result" = "failure" ] || [ "$result" = "cancelled" ]; then
exit 1
fi
done