Files
oxc/.github/workflows/ci.yml
T
Dunqing 563cf449a9 chore(runtime): sync helpers with Babel 8.0.8 (#28172)
Sync the complete published `@babel/runtime@8.0.8` helper tree so future updates have a recorded upstream baseline.

Import all 95 CommonJS/ESM helper pairs, the MIT license, conditional exports, and `sideEffects: false`. Preserve 26 legacy Babel helper pairs, three TypeScript decorator helper pairs, and existing import paths.

189 of the 191 upstream files are byte-identical. The two `setFunctionName` implementations retain Oxc's existing behavior and match main. Add a hash manifest, a repeatable sync script, CJS/ESM tests in CI, and an async-generator execution regression. No new helper optimizations or correctness patches are included.

Validation: upstream hashes, compatibility preservation, sync idempotence and drift refusal, formatting, lint, syntax, and whitespace checks passed. Runtime tests were not rerun after restoring this tree because automatic approval blocked helper execution; the newer Babel fixture revision pinned by main was not run locally.

AI assistance: Claude.
2026-11-02 09:38:54 +00:00

963 lines
41 KiB
YAML

name: CI
permissions: {}
on:
workflow_dispatch:
pull_request:
types: [opened, synchronize]
merge_group:
push:
branches:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: ${{ github.ref_name != 'main' }}
env:
INSTA_REQUIRE_FULL_MATCH: 1
jobs:
test-ubuntu:
name: Test Linux
runs-on: namespace-profile-linux-x64-default
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- uses: oxc-project/setup-node@f46a72f95efdc55273fcd042d61c84e723b2892c # v1.4.1
- uses: namespacelabs/nscloud-cache-action@1124a6f3ce44e5cf84cc22111530961f4d2a15f9 # v1.7.0
with:
path: /home/runner/.rustup
cache: |
rust
pnpm
- run: cargo ck
- run: cargo test --all-features
- run: git diff --exit-code # Must commit everything
test-ubuntu-aarch64:
if: ${{ github.ref_name == 'main' }}
name: Test Linux ARM64
runs-on: ubuntu-24.04-arm
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- parallel:
- uses: oxc-project/setup-node@f46a72f95efdc55273fcd042d61c84e723b2892c # v1.4.1
- uses: oxc-project/setup-rust@3d6fb132fbe7cdcb66bf8ec193911c2945369d12 # v1.0.17
with:
save-cache: ${{ github.ref_name == 'main' }}
cache-key: warm-aarch64
- run: cargo ck
- run: cargo test --all-features
- run: git diff --exit-code # Must commit everything
test-mac: # Separate job to save a job on PRs
if: ${{ github.ref_name == 'main' }}
name: Test Mac
runs-on: namespace-profile-mac-default
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
# `cache: pnpm` is intentionally omitted. On Mac OS, `cache: pnpm` replaces the pnpm store directory
# (`~/setup-pnpm/node_modules/.bin/store/v11`) with a symlink into the Namespace cache volume.
# But `oxc-project/setup-node` also caches that same path via `actions/cache`, and at job end
# `tar` archives the symlink record itself rather than the store contents - producing a faulty cache.
# `actions/cache` already handles pnpm correctly here, only `rust` needs the NS volume.
# Note: On Linux this action uses bind-mounts, which don't have this problem - it's a Mac OS problem only.
- parallel:
- uses: oxc-project/setup-node@f46a72f95efdc55273fcd042d61c84e723b2892c # v1.4.1
- uses: namespacelabs/nscloud-cache-action@1124a6f3ce44e5cf84cc22111530961f4d2a15f9 # v1.7.0
with:
cache: rust
- run: cargo ck
- run: cargo test --all-features
- run: git diff --exit-code # Must commit everything
test-windows:
if: ${{ github.ref_name == 'main' || github.event_name == 'workflow_dispatch' }}
name: Test Windows
runs-on: windows-latest
steps:
- run: git config --system core.longpaths true
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
# Unsung heroes of the internet, who led me here to speed up Windows' slowness:
# https://github.com/actions/cache/issues/752#issuecomment-1847036770
# https://github.com/astral-sh/uv/blob/502e04200d52de30d3159894833b3db4f0d6644d/.github/workflows/ci.yml#L158
- uses: samypr100/setup-dev-drive@562171fe8df7401fdf582d766cd3b6ab80d5b1a0 # v4.1.0
with:
workspace-copy: true
drive-size: 12GB
drive-format: ReFS
env-mapping: |
CARGO_HOME,{{ DEV_DRIVE }}/.cargo
RUSTUP_HOME,{{ DEV_DRIVE }}/.rustup
# Copy before installing: the Dev Drive action does not preserve pnpm 12 directory symlinks.
- parallel:
- uses: oxc-project/setup-node@f46a72f95efdc55273fcd042d61c84e723b2892c # v1.4.1
- name: Install Rust
working-directory: ${{ env.DEV_DRIVE_WORKSPACE }}
shell: bash
run: |
# This `awk` command will find the value of our Minimum Supported Rust Version and store it as `MSRV`.
# NOTE: this will fail if there are any other items named `rust-version`. We assume there is only one in our `Cargo.toml`.
MSRV=$(awk -F'=' '/rust-version/ {gsub(/[" ]/, "", $2); printf "%s", ($2 + "")}' Cargo.toml)
# Set profile to minimal and channel to our Minimum Supported Rust Version.
# Running our tests on this channel ensures that our code uses APIs that are supported in our `MSRV`.
sed -i -e 's/profile = "default"/profile = "minimal"/g' -e "s/channel = .*/channel = \"$MSRV\"/g" rust-toolchain.toml
rustup set profile minimal
rustup show
git restore .
- name: Install dependencies on Dev Drive
id: dependencies
working-directory: ${{ env.DEV_DRIVE_WORKSPACE }}
run: pnpm install --frozen-lockfile --ignore-scripts
background: true
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
with:
workspaces: ${{ env.DEV_DRIVE_WORKSPACE }}
save-if: ${{ github.ref_name == 'main' }}
shared-key: windows-latest
- name: Compile tests
run: cargo test --all-features --no-run
working-directory: ${{ env.DEV_DRIVE_WORKSPACE }}
shell: bash
- wait: dependencies
- name: Run tests
# No need for `cargo ck` because it's already checked in linux
# Run `website` tests separately to avoid feature unification problems with `oxlint`
run: cargo test --all-features
working-directory: ${{ env.DEV_DRIVE_WORKSPACE }}
shell: bash
test-big-endian:
if: ${{ github.ref_name == 'main' }}
name: Test big-endian # s390x-unknown-linux-gnu is a big-endian
runs-on: namespace-profile-linux-x64-default
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- uses: namespacelabs/nscloud-cache-action@1124a6f3ce44e5cf84cc22111530961f4d2a15f9 # v1.7.0
with:
path: /home/runner/.rustup
cache: rust
- uses: taiki-e/install-action@f7e5d7c961414b23f5b25b2da9294395d08513ad # v2.87.26
with:
tool: cross
# `--lib --bins --tests` to skip doctests which are very slow to run via `cross`.
# https://github.com/cross-rs/cross/issues/1703
- run: cross test --lib --bins --tests --all-features --target s390x-unknown-linux-gnu
test-32bit:
if: ${{ github.ref_name == 'main' }}
name: Test 32-bit # armv7-unknown-linux-gnueabihf is a 32-bit target
runs-on: namespace-profile-linux-x64-default
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- uses: namespacelabs/nscloud-cache-action@1124a6f3ce44e5cf84cc22111530961f4d2a15f9 # v1.7.0
with:
path: /home/runner/.rustup
cache: rust
- uses: taiki-e/install-action@f7e5d7c961414b23f5b25b2da9294395d08513ad # v2.87.26
with:
tool: cross
# `--lib --bins --tests` to skip doctests which are very slow to run via `cross`.
# https://github.com/cross-rs/cross/issues/1703
- run: cross test --workspace --lib --bins --tests --all-features --exclude oxc_language_server --exclude oxc_linter --exclude oxlint --target armv7-unknown-linux-gnueabihf
test-wasm32-wasip1-threads:
name: Test wasm32-wasip1-threads
runs-on: namespace-profile-linux-x64-default
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- uses: $/.github/actions/check-changes
id: filter
with:
exclude: oxc_linter
paths: napi/,npm/,apps/,pnpm-lock.yaml,package.json
token: ${{ secrets.GITHUB_TOKEN }}
pr-number: ${{ github.event.pull_request.number }}
- uses: oxc-project/setup-node@f46a72f95efdc55273fcd042d61c84e723b2892c # v1.4.1
if: steps.filter.outputs.changed == 'true'
- uses: namespacelabs/nscloud-cache-action@1124a6f3ce44e5cf84cc22111530961f4d2a15f9 # v1.7.0
if: steps.filter.outputs.changed == 'true'
with:
path: /home/runner/.rustup
cache: |
rust
pnpm
- name: Install Playwright Chromium
id: playwright
if: steps.filter.outputs.changed == 'true'
working-directory: napi/parser
run: pnpm exec playwright install chromium
background: true
- name: Build
if: steps.filter.outputs.changed == 'true'
run: |
rustup target add wasm32-wasip1
rustup target add wasm32-wasip1-threads
pnpm run build-wasm-dev
pnpm run build-wasip1-dev
git diff --exit-code # Must commit everything
- wait: playwright
- name: Test wasi in browser
if: steps.filter.outputs.changed == 'true'
working-directory: napi/parser
run: |
rm -rf *.wasm
pnpm run build-wasi
pnpm run build-wasm-dev
pnpm run build-wasip1-dev
pnpm run build-npm-dir
pnpm run test-browser
pnpm build-browser-bundle --npmDir npm-dir
test-napi-compiler:
name: Test NAPI Compiler
runs-on: namespace-profile-linux-x64-default
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- uses: $/.github/actions/check-changes
id: filter
with:
exclude: oxc_linter,oxc_language_server
paths: napi/parser/,napi/minify/,napi/transform/,napi/transform-react/,napi/transform-relay/,npm/oxc-types/,npm/runtime/,tasks/e2e/,pnpm-lock.yaml,package.json
token: ${{ secrets.GITHUB_TOKEN }}
pr-number: ${{ github.event.pull_request.number }}
- uses: $/.github/actions/clone-submodules
id: napi-fixtures
if: steps.filter.outputs.changed == 'true'
with:
babel: false
node-compat-table: false
background: true
- uses: oxc-project/setup-node@f46a72f95efdc55273fcd042d61c84e723b2892c # v1.4.1
if: steps.filter.outputs.changed == 'true'
- uses: namespacelabs/nscloud-cache-action@1124a6f3ce44e5cf84cc22111530961f4d2a15f9 # v1.7.0
if: steps.filter.outputs.changed == 'true'
with:
path: /home/runner/.rustup
cache: |
rust
pnpm
- wait: napi-fixtures
- if: steps.filter.outputs.changed == 'true'
name: Build packages
run: pnpm --workspace-concurrency=1 --filter "./napi/parser" --filter "./napi/minify" --filter "./napi/transform" --filter "./napi/transform-react" --filter "./napi/transform-relay" build-test
- if: steps.filter.outputs.changed == 'true'
name: Run runtime helper tests
working-directory: npm/runtime
run: node --run test
- parallel:
- if: steps.filter.outputs.changed == 'true'
name: Run tests
env:
RUN_RAW_RANGE_TESTS: "true"
RUN_RAW_TOKENS_TESTS: "true"
run: pnpm --workspace-concurrency=1 --filter "./napi/parser" --filter "./napi/minify" --filter "./napi/transform" --filter "./napi/transform-react" --filter "./napi/transform-relay" test
- if: steps.filter.outputs.changed == 'true'
name: Run e2e tests
working-directory: tasks/e2e
run: pnpm run test
- if: steps.filter.outputs.changed == 'true'
run: |
git diff --exit-code # Must commit everything
test-napi-shared:
name: Test NAPI Shared
runs-on: namespace-profile-linux-x64-default
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- uses: $/.github/actions/check-changes
id: filter
with:
paths: apps/shared/,pnpm-lock.yaml,package.json
token: ${{ secrets.GITHUB_TOKEN }}
pr-number: ${{ github.event.pull_request.number }}
- uses: oxc-project/setup-node@f46a72f95efdc55273fcd042d61c84e723b2892c # v1.4.1
if: steps.filter.outputs.changed == 'true'
- uses: namespacelabs/nscloud-cache-action@1124a6f3ce44e5cf84cc22111530961f4d2a15f9 # v1.7.0
if: steps.filter.outputs.changed == 'true'
with:
path: /home/runner/.rustup
cache: |
pnpm
- if: steps.filter.outputs.changed == 'true'
name: Run tests
run: pnpm --filter "@oxapps/shared" test
test-napi-oxlint:
name: Test NAPI Oxlint
runs-on: namespace-profile-linux-x64-default
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- uses: $/.github/actions/check-changes
id: filter
with:
paths: apps/oxlint/,apps/shared/,npm/oxlint/,npm/oxlint-plugin-eslint/,npm/oxlint-plugins/,npm/oxc-types/,crates/oxc_config/,pnpm-lock.yaml,package.json
token: ${{ secrets.GITHUB_TOKEN }}
pr-number: ${{ github.event.pull_request.number }}
- uses: oxc-project/setup-node@f46a72f95efdc55273fcd042d61c84e723b2892c # v1.4.1
if: steps.filter.outputs.changed == 'true'
- uses: namespacelabs/nscloud-cache-action@1124a6f3ce44e5cf84cc22111530961f4d2a15f9 # v1.7.0
if: steps.filter.outputs.changed == 'true'
with:
path: /home/runner/.rustup
cache: |
rust
pnpm
- if: steps.filter.outputs.changed == 'true'
name: Run tests
run: |
pnpm --filter "./apps/oxlint" build-test
pnpm --filter "./apps/oxlint" test
- if: steps.filter.outputs.changed == 'true'
run: |
git diff --exit-code # Must commit everything
test-napi-oxfmt:
name: Test NAPI Oxfmt
runs-on: namespace-profile-linux-x64-default
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- uses: $/.github/actions/check-changes
id: filter
with:
paths: apps/oxfmt/,apps/shared/,npm/oxfmt/,crates/oxc_formatter/,crates/oxc_formatter_core/,crates/oxc_formatter_css/,crates/oxc_formatter_graphql/,crates/oxc_formatter_json/,crates/oxc_formatter_yaml/,crates/oxc_formatter_markdown/,crates/oxc_formatter_htmlish/,crates/oxc_formatter_toml/,crates/oxc_config/,pnpm-lock.yaml,package.json
token: ${{ secrets.GITHUB_TOKEN }}
pr-number: ${{ github.event.pull_request.number }}
- uses: $/.github/actions/check-changes
id: filter-conformance
with:
# Every crate oxfmt formats with (parsers, AST, ...), not only the formatters
packages: oxfmt
paths: apps/oxfmt/,npm/oxfmt/,pnpm-lock.yaml,package.json
token: ${{ secrets.GITHUB_TOKEN }}
pr-number: ${{ github.event.pull_request.number }}
- uses: oxc-project/setup-node@f46a72f95efdc55273fcd042d61c84e723b2892c # v1.4.1
if: steps.filter.outputs.changed == 'true' || steps.filter-conformance.outputs.changed == 'true'
- uses: namespacelabs/nscloud-cache-action@1124a6f3ce44e5cf84cc22111530961f4d2a15f9 # v1.7.0
if: steps.filter.outputs.changed == 'true' || steps.filter-conformance.outputs.changed == 'true'
with:
path: /home/runner/.rustup
cache: |
rust
pnpm
# Conformance ---
- uses: namespacelabs/nscloud-cache-action@1124a6f3ce44e5cf84cc22111530961f4d2a15f9 # v1.7.0
id: conformance-fixtures
if: steps.filter-conformance.outputs.changed == 'true'
with:
# Warm fixtures skip download entirely (`.version` stamps in download-fixtures.ts)
path: ./apps/oxfmt/conformance/fixtures/externals
background: true
- if: steps.filter.outputs.changed == 'true' || steps.filter-conformance.outputs.changed == 'true'
name: Build tests
run: pnpm --filter "./apps/oxfmt" build-test
- wait: conformance-fixtures
- if: steps.filter-conformance.outputs.changed == 'true'
name: Download conformance fixtures
run: pnpm --filter "./apps/oxfmt" download-fixtures
- parallel:
- if: steps.filter.outputs.changed == 'true'
name: Run tests
run: pnpm --filter "./apps/oxfmt" test
- if: steps.filter-conformance.outputs.changed == 'true'
name: Run conformance tests
run: pnpm --filter "./apps/oxfmt" conformance
# --- Conformance
- if: steps.filter.outputs.changed == 'true' || steps.filter-conformance.outputs.changed == 'true'
run: |
git diff --exit-code # Must commit everything
test-napi-compiler-windows:
name: Test NAPI Compiler (windows)
runs-on: windows-latest
if: ${{ github.ref_name == 'main' || github.event_name == 'workflow_dispatch' }}
# Keep steps sequential to avoid event.json locking: https://github.com/actions/runner/issues/4641
steps:
- run: git config --system core.longpaths true
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- uses: $/.github/actions/check-changes
id: filter
with:
exclude: oxc_linter,oxc_language_server
paths: napi/parser/,napi/minify/,napi/transform/,napi/transform-react/,napi/transform-relay/,npm/oxc-types/,npm/runtime/,tasks/e2e/,pnpm-lock.yaml,package.json
token: ${{ secrets.GITHUB_TOKEN }}
pr-number: ${{ github.event.pull_request.number }}
- uses: samypr100/setup-dev-drive@562171fe8df7401fdf582d766cd3b6ab80d5b1a0 # v4.1.0
if: steps.filter.outputs.changed == 'true'
with:
workspace-copy: true
drive-size: 12GB
drive-format: ReFS
env-mapping: |
CARGO_HOME,{{ DEV_DRIVE }}/.cargo
RUSTUP_HOME,{{ DEV_DRIVE }}/.rustup
# Copy before installing: the Dev Drive action does not preserve pnpm 12 directory symlinks.
- uses: oxc-project/setup-node@f46a72f95efdc55273fcd042d61c84e723b2892c # v1.4.1
if: steps.filter.outputs.changed == 'true'
- uses: oxc-project/setup-rust@3d6fb132fbe7cdcb66bf8ec193911c2945369d12 # v1.0.17
if: steps.filter.outputs.changed == 'true'
with:
cache-key: napi
save-cache: ${{ github.ref_name == 'main' }}
- uses: $/.github/actions/clone-submodules
if: steps.filter.outputs.changed == 'true'
with:
babel: false
node-compat-table: false
- name: Install dependencies on Dev Drive
if: steps.filter.outputs.changed == 'true'
working-directory: ${{ env.DEV_DRIVE_WORKSPACE }}
run: pnpm install --frozen-lockfile --ignore-scripts
- if: steps.filter.outputs.changed == 'true'
name: Build packages
working-directory: ${{ env.DEV_DRIVE_WORKSPACE }}
shell: bash
run: |
cargo build --profile coverage \
-p oxc_parser_napi \
-p oxc_minify_napi \
-p oxc_transform_napi \
-p oxc_transform_react_napi \
-p oxc_transform_relay_napi \
--features oxc_parser_napi/tokens
artifacts=(
"oxc_parser_napi.dll:napi/parser/src-js/parser.win32-x64-msvc.node"
"oxc_minify_napi.dll:napi/minify/minify.win32-x64-msvc.node"
"oxc_transform_napi.dll:napi/transform/transform.win32-x64-msvc.node"
"oxc_transform_react_napi.dll:napi/transform-react/transform-react.win32-x64-msvc.node"
"oxc_transform_relay_napi.dll:napi/transform-relay/transform-relay.win32-x64-msvc.node"
)
for artifact in "${artifacts[@]}"; do
IFS=: read -r source destination <<< "$artifact"
source="target/coverage/$source"
test -f "$source"
cp "$source" "$destination"
done
- if: steps.filter.outputs.changed == 'true'
name: Run tests
working-directory: ${{ env.DEV_DRIVE_WORKSPACE }}
env:
RUN_RAW_RANGE_TESTS: "true"
run: pnpm --workspace-concurrency=1 --filter "./napi/parser" --filter "./napi/minify" --filter "./napi/transform" --filter "./napi/transform-react" --filter "./napi/transform-relay" test
- if: steps.filter.outputs.changed == 'true'
name: Run e2e tests
working-directory: ${{ env.DEV_DRIVE_WORKSPACE }}/tasks/e2e
run: |
pnpm install --frozen-lockfile
pnpm run test
- if: steps.filter.outputs.changed == 'true'
working-directory: ${{ env.DEV_DRIVE_WORKSPACE }}
run: |
git diff --exit-code # Must commit everything
test-napi-oxlint-windows:
name: Test NAPI Oxlint (windows)
runs-on: windows-latest
if: ${{ github.ref_name == 'main' }}
steps:
- run: git config --system core.longpaths true
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- uses: $/.github/actions/check-changes
id: filter
with:
paths: apps/oxlint/,apps/shared/,npm/oxlint/,npm/oxlint-plugin-eslint/,npm/oxlint-plugins/,npm/oxc-types/,crates/oxc_config/,pnpm-lock.yaml,package.json
token: ${{ secrets.GITHUB_TOKEN }}
pr-number: ${{ github.event.pull_request.number }}
- uses: samypr100/setup-dev-drive@562171fe8df7401fdf582d766cd3b6ab80d5b1a0 # v4.1.0
if: steps.filter.outputs.changed == 'true'
with:
workspace-copy: true
drive-size: 12GB
drive-format: ReFS
env-mapping: |
CARGO_HOME,{{ DEV_DRIVE }}/.cargo
RUSTUP_HOME,{{ DEV_DRIVE }}/.rustup
# Copy before installing: the Dev Drive action does not preserve pnpm 12 directory symlinks.
- parallel:
- uses: oxc-project/setup-node@f46a72f95efdc55273fcd042d61c84e723b2892c # v1.4.1
if: steps.filter.outputs.changed == 'true'
- uses: oxc-project/setup-rust@3d6fb132fbe7cdcb66bf8ec193911c2945369d12 # v1.0.17
if: steps.filter.outputs.changed == 'true'
with:
cache-key: napi
save-cache: ${{ github.ref_name == 'main' }}
- name: Install dependencies on Dev Drive
if: steps.filter.outputs.changed == 'true'
working-directory: ${{ env.DEV_DRIVE_WORKSPACE }}
run: pnpm install --frozen-lockfile --ignore-scripts
- if: steps.filter.outputs.changed == 'true'
name: Run tests
working-directory: ${{ env.DEV_DRIVE_WORKSPACE }}
run: |
pnpm --filter "./apps/oxlint" build-test
pnpm --filter "./apps/oxlint" test
- if: steps.filter.outputs.changed == 'true'
working-directory: ${{ env.DEV_DRIVE_WORKSPACE }}
run: |
git diff --exit-code # Must commit everything
test-napi-oxfmt-windows:
name: Test NAPI Oxfmt (windows)
runs-on: windows-latest
if: ${{ github.ref_name == 'main' }}
steps:
- run: git config --system core.longpaths true
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- uses: $/.github/actions/check-changes
id: filter
with:
paths: apps/oxfmt/,apps/shared/,npm/oxfmt/,crates/oxc_formatter/,crates/oxc_formatter_core/,crates/oxc_formatter_css/,crates/oxc_formatter_graphql/,crates/oxc_formatter_json/,crates/oxc_formatter_yaml/,crates/oxc_formatter_markdown/,crates/oxc_formatter_htmlish/,crates/oxc_formatter_toml/,crates/oxc_config/,pnpm-lock.yaml,package.json
token: ${{ secrets.GITHUB_TOKEN }}
pr-number: ${{ github.event.pull_request.number }}
- uses: samypr100/setup-dev-drive@562171fe8df7401fdf582d766cd3b6ab80d5b1a0 # v4.1.0
if: steps.filter.outputs.changed == 'true'
with:
workspace-copy: true
drive-size: 12GB
drive-format: ReFS
env-mapping: |
CARGO_HOME,{{ DEV_DRIVE }}/.cargo
RUSTUP_HOME,{{ DEV_DRIVE }}/.rustup
# Copy before installing: the Dev Drive action does not preserve pnpm 12 directory symlinks.
- parallel:
- uses: oxc-project/setup-node@f46a72f95efdc55273fcd042d61c84e723b2892c # v1.4.1
if: steps.filter.outputs.changed == 'true'
- uses: oxc-project/setup-rust@3d6fb132fbe7cdcb66bf8ec193911c2945369d12 # v1.0.17
if: steps.filter.outputs.changed == 'true'
with:
cache-key: napi
save-cache: ${{ github.ref_name == 'main' }}
- name: Install dependencies on Dev Drive
if: steps.filter.outputs.changed == 'true'
working-directory: ${{ env.DEV_DRIVE_WORKSPACE }}
run: pnpm install --frozen-lockfile --ignore-scripts
- if: steps.filter.outputs.changed == 'true'
name: Run tests
working-directory: ${{ env.DEV_DRIVE_WORKSPACE }}
run: |
pnpm --filter "./apps/oxfmt" build-test
pnpm --filter "./apps/oxfmt" test
- if: steps.filter.outputs.changed == 'true'
working-directory: ${{ env.DEV_DRIVE_WORKSPACE }}
run: |
git diff --exit-code # Must commit everything
typos:
name: Spell Check
runs-on: ubuntu-slim
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- uses: crate-ci/typos@7f9d0819ca1c008ade73f4b41fa9d258d48f605b # v1.51.1
with:
files: .
lint:
name: Lint
runs-on: namespace-profile-linux-x64-default
env:
CARGO_BUILD_WARNINGS: deny
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- uses: oxc-project/setup-node@f46a72f95efdc55273fcd042d61c84e723b2892c # v1.4.1
- uses: namespacelabs/nscloud-cache-action@1124a6f3ce44e5cf84cc22111530961f4d2a15f9 # v1.7.0
with:
path: /home/runner/.rustup
cache: |
rust
pnpm
- name: JavaScript lint
id: javascript-lint
run: |
pnpm --filter oxlint-app build-js
pnpm --filter oxfmt-app build-js
pnpm --filter oxc-codegen build
node --run lint
background: true
- run: rustup component add clippy
- run: cargo lint
# Catch lints which only fire with `debug_assertions` off (i.e. release mode),
# e.g. code becoming unused when a `#[cfg(debug_assertions)]` block vanishes.
# Main-only and without `--all-targets`: these failures are rare and a post-merge
# failure pinpoints the culprit commit, so not worth doubling clippy time on every PR.
# `--all-targets` is omitted because test/bench code is never built in release mode
# with warnings denied.
- if: ${{ github.ref_name == 'main' }}
run: cargo clippy --all-features --profile dev-no-debug-assertions
- wait: javascript-lint
doc:
name: Doc
runs-on: namespace-profile-linux-x64-default
env:
TOOLCHAIN: nightly-2026-09-30
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- uses: namespacelabs/nscloud-cache-action@1124a6f3ce44e5cf84cc22111530961f4d2a15f9 # v1.7.0
with:
path: /home/runner/.rustup
cache: rust
- run: rustup toolchain install "${TOOLCHAIN}" --profile minimal --component rust-docs
# https://github.com/rust-lang/rust/issues/146895
- run: RUSTDOCFLAGS='-D warnings' cargo +"${TOOLCHAIN}" doc --no-deps --document-private-items --all-features -Zrustdoc-mergeable-info
conformance:
name: Conformance
runs-on: namespace-profile-linux-x64-default
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- name: Check if conformance should run
id: filter
uses: $/.github/actions/check-changes
with:
packages: oxc_coverage,oxc_transform_conformance
paths: tasks/coverage/,tasks/common/,tasks/transform_conformance/,pnpm-lock.yaml
token: ${{ secrets.GITHUB_TOKEN }}
pr-number: ${{ github.event.pull_request.number }}
- uses: $/.github/actions/clone-submodules
id: conformance-fixtures
if: steps.filter.outputs.changed == 'true'
with:
node-compat-table: false
background: true
- uses: oxc-project/setup-node@f46a72f95efdc55273fcd042d61c84e723b2892c # v1.4.1
if: steps.filter.outputs.changed == 'true'
- uses: namespacelabs/nscloud-cache-action@1124a6f3ce44e5cf84cc22111530961f4d2a15f9 # v1.7.0
if: steps.filter.outputs.changed == 'true'
with:
path: /home/runner/.rustup
cache: |
rust
pnpm
- uses: taiki-e/install-action@f7e5d7c961414b23f5b25b2da9294395d08513ad # v2.87.26
if: steps.filter.outputs.changed == 'true'
with:
tool: just
- wait: conformance-fixtures
- name: Check Conformance
if: steps.filter.outputs.changed == 'true'
run: |
just update-transformer-fixtures
just coverage
git diff --exit-code
lexer:
# `oxc_lexer` compiles to one of 3 implementations, chosen at build time:
# 1. AVX2 on x86_64 with `avx2` + `bmi2` + `popcnt`.
# 2. Neon on aarch64.
# 3. Generic everywhere else.
#
# Each leg of this job builds one of them. The AVX2 and generic legs run on x86_64, the Neon leg on aarch64.
#
# Coverage by other jobs:
# - None of `avx2`, `bmi2` and `popcnt` is in the x86_64 baseline on any platform, so the AVX2 implementation
# is never built unless asked for explicitly - which means no other job here lints, tests or runs it.
# - No other job builds Neon on PRs (the aarch64 test jobs only run on `main`), and no other job lints it.
# - Generic is already linted by the "Lint" job and tested by the "Test Linux" job,
# so this job only runs conformance for it.
#
# All legs regenerate the committed conformance snapshots and fail on any diff,
# which ensures the 3 implementations behave identically to each other.
#
# See the LEXER section of `justfile` for the recipes.
name: Lexer (${{ matrix.variant }})
runs-on: ${{ matrix.runner }}
env:
CARGO_BUILD_WARNINGS: deny
strategy:
fail-fast: false
matrix:
include:
- variant: generic
runner: namespace-profile-linux-x64-default
suffix: ""
- variant: AVX2
runner: namespace-profile-linux-x64-default
suffix: "-avx2"
- variant: Neon
runner: ubuntu-24.04-arm
suffix: ""
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- name: Check if lexer checks should run
id: filter
uses: $/.github/actions/check-changes
with:
packages: oxc_lexer,oxc_lexer_macros,oxc_coverage
paths: crates/oxc_lexer/,crates/oxc_lexer_macros/,tasks/coverage/,.cargo/lexer-avx2.toml,justfile,.github/workflows/ci.yml
token: ${{ secrets.GITHUB_TOKEN }}
pr-number: ${{ github.event.pull_request.number }}
- uses: $/.github/actions/clone-submodules
id: lexer-fixtures
if: steps.filter.outputs.changed == 'true'
with:
node-compat-table: false
background: true
# The x86_64 legs run on Namespace runners, which provide the cache
- uses: namespacelabs/nscloud-cache-action@1124a6f3ce44e5cf84cc22111530961f4d2a15f9 # v1.7.0
if: ${{ steps.filter.outputs.changed == 'true' && matrix.variant != 'Neon' }}
with:
path: /home/runner/.rustup
cache: rust
- uses: taiki-e/install-action@f7e5d7c961414b23f5b25b2da9294395d08513ad # v2.87.26
if: ${{ steps.filter.outputs.changed == 'true' && matrix.variant != 'Neon' }}
with:
tool: just
- run: rustup component add clippy
# No need to run on generic - linting already covered by "Lint" job
if: ${{ steps.filter.outputs.changed == 'true' && matrix.variant == 'AVX2' }}
# The Neon leg runs on a GitHub-hosted runner, where Namespace's cache isn't available.
# Set up the same way as the "Test Linux ARM64" job, but with its own cache.
- uses: oxc-project/setup-rust@3d6fb132fbe7cdcb66bf8ec193911c2945369d12 # v1.0.17
if: ${{ steps.filter.outputs.changed == 'true' && matrix.variant == 'Neon' }}
with:
save-cache: ${{ github.ref_name == 'main' }}
cache-key: lexer-aarch64
tools: just
components: clippy
- name: Lint
# No need to run on generic - already covered by "Lint" job
if: ${{ steps.filter.outputs.changed == 'true' && matrix.variant != 'generic' }}
run: just lint-lexer${{ matrix.suffix }}
- name: Test
# No need to run on generic - already covered by "Test Linux" job
if: ${{ steps.filter.outputs.changed == 'true' && matrix.variant != 'generic' }}
run: just test-lexer${{ matrix.suffix }}
- wait: lexer-fixtures
- name: Conformance
# Run on all 3 implementations - none of them is run anywhere else.
# The harness prints which implementation it was built with (`oxc_lexer::IMPLEMENTATION`).
# Checking it here is what guarantees this leg exercised the build it asked for.
if: steps.filter.outputs.changed == 'true'
run: |
set -o pipefail
just conformance-lexer${{ matrix.suffix }} | tee "$RUNNER_TEMP/lexer.log"
grep -qxF "Lexer implementation: ${{ matrix.variant }}" "$RUNNER_TEMP/lexer.log" ||
{ echo "::error::Expected ${{ matrix.variant }}, but the harness reported otherwise"; exit 1; }
git diff --exit-code
test-codegen:
name: Test Codegen
runs-on: namespace-profile-linux-x64-default
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- name: Check if codegen tests should run
id: filter
uses: $/.github/actions/check-changes
with:
packages: oxc_codegen_conformance,oxc_parser_napi
paths: .github/workflows/ci.yml,packages/codegen/,tasks/codegen_conformance/,napi/parser/,npm/oxc-types/,tasks/coverage/,pnpm-lock.yaml,pnpm-workspace.yaml,package.json
token: ${{ secrets.GITHUB_TOKEN }}
pr-number: ${{ github.event.pull_request.number }}
- uses: $/.github/actions/clone-submodules
id: codegen-fixtures
if: steps.filter.outputs.changed == 'true'
with:
node-compat-table: false
background: true
- uses: oxc-project/setup-node@f46a72f95efdc55273fcd042d61c84e723b2892c # v1.4.1
if: steps.filter.outputs.changed == 'true'
- uses: namespacelabs/nscloud-cache-action@1124a6f3ce44e5cf84cc22111530961f4d2a15f9 # v1.7.0
if: steps.filter.outputs.changed == 'true'
with:
path: /home/runner/.rustup
cache: |
rust
pnpm
- wait: codegen-fixtures
- name: Run codegen tests
if: steps.filter.outputs.changed == 'true'
run: |
pnpm --filter oxc-codegen build-test
pnpm --filter oxc-codegen test
git diff --exit-code
minification:
name: Minification Size
runs-on: namespace-profile-linux-x64-default
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- uses: $/.github/actions/check-changes
id: filter
with:
packages: oxc_minsize
token: ${{ secrets.GITHUB_TOKEN }}
pr-number: ${{ github.event.pull_request.number }}
- uses: namespacelabs/nscloud-cache-action@1124a6f3ce44e5cf84cc22111530961f4d2a15f9 # v1.7.0
if: steps.filter.outputs.changed == 'true'
with:
path: /home/runner/.rustup
cache: rust
- name: Check minification size
if: steps.filter.outputs.changed == 'true'
run: |
cargo minsize
git diff --exit-code
# Write a human-readable diff of the minified output vs the base branch
# to the job summary for review (same flow as `just minifier-diff`).
- name: Diff minify output
if: ${{ !cancelled() && steps.filter.outputs.changed == 'true' && github.event_name == 'pull_request' }}
env:
BASE_REF: ${{ github.event.pull_request.base.ref }}
run: |
cargo minsize --compress-only pr
if fetch_output=$(git fetch --depth 1 origin "$BASE_REF" 2>&1); then
printf '%s\n' "$fetch_output" >&2
else
fetch_status=$?
printf '%s\n' "$fetch_output" >&2
if [[ "$BASE_REF" == graphite-base/* ]] &&
grep -Fxq "fatal: couldn't find remote ref $BASE_REF" <<< "$fetch_output"; then
printf 'Skipped minify output diff: base ref `%s` is no longer available on origin.\n' "$BASE_REF" >> "$GITHUB_STEP_SUMMARY"
exit 0
fi
exit "$fetch_status"
fi
git checkout -f FETCH_HEAD
cargo minsize --compress-only main
echo '# Minify Output Diff' >> "$GITHUB_STEP_SUMMARY"
changed=false
for pr_file in target/minifier/pr/*.js; do
name=$(basename "$pr_file")
if ! diff -uN "target/minifier/main/$name" "$pr_file" > /tmp/minify.diff; then
changed=true
{
echo "## $name"
echo '```diff'
head -n 200 /tmp/minify.diff
if [ "$(wc -l < /tmp/minify.diff)" -gt 200 ]; then echo '... (truncated)'; fi
echo '```'
} >> "$GITHUB_STEP_SUMMARY"
fi
done
if [ "$changed" = false ]; then
echo 'No difference in compress-only output compared to the base branch.' >> "$GITHUB_STEP_SUMMARY"
fi
allocs:
name: Allocations
runs-on: namespace-profile-linux-x64-default
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- uses: $/.github/actions/check-changes
id: filter
with:
packages: oxc_track_memory_allocations
paths: tasks/track_memory_allocations/
token: ${{ secrets.GITHUB_TOKEN }}
pr-number: ${{ github.event.pull_request.number }}
- uses: namespacelabs/nscloud-cache-action@1124a6f3ce44e5cf84cc22111530961f4d2a15f9 # v1.7.0
if: steps.filter.outputs.changed == 'true'
with:
path: /home/runner/.rustup
cache: rust
- name: Check allocations
if: steps.filter.outputs.changed == 'true'
run: |
cargo allocs
git diff --exit-code ||
(echo 'Allocations have changed. Run the `cargo allocs` command to update the allocation snapshot, otherwise please fix the regression.' && exit 1)
ast_changes:
name: AST Changes
runs-on: namespace-profile-linux-x64-default
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: filter
with:
filters: ".github/generated/ast_changes_watch_list.yml"
- uses: oxc-project/setup-node@f46a72f95efdc55273fcd042d61c84e723b2892c # v1.4.1
if: steps.filter.outputs.src == 'true'
- uses: namespacelabs/nscloud-cache-action@1124a6f3ce44e5cf84cc22111530961f4d2a15f9 # v1.7.0
if: steps.filter.outputs.src == 'true'
with:
path: /home/runner/.rustup
cache: |
rust
pnpm
- run: rustup component add rustfmt
if: steps.filter.outputs.src == 'true'
- name: Check AST Changes
if: steps.filter.outputs.src == 'true'
run: |
cargo run -p oxc_ast_tools
git diff --exit-code ||
(echo 'AST changes caused the "generated" code to get outdated. Have you forgotten to run the `just ast` command and/or commit generated codes?' && exit 1)
lintgen:
name: Linter changes
runs-on: namespace-profile-linux-x64-default
steps:
- uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2
- uses: $/.github/actions/check-changes
id: filter
with:
packages: oxc_linter,oxc_track_linter_timings
paths: tasks/linter_codegen/,tasks/track_linter_timings/,npm/oxlint/configuration_schema.json,apps/oxlint/src-js/package/config.generated.ts,apps/oxlint/scripts/generate-config-types.ts,apps/oxlint/package.json,pnpm-lock.yaml,package.json
token: ${{ secrets.GITHUB_TOKEN }}
pr-number: ${{ github.event.pull_request.number }}
- uses: oxc-project/setup-node@f46a72f95efdc55273fcd042d61c84e723b2892c # v1.4.1
if: steps.filter.outputs.changed == 'true'
- uses: namespacelabs/nscloud-cache-action@1124a6f3ce44e5cf84cc22111530961f4d2a15f9 # v1.7.0
if: steps.filter.outputs.changed == 'true'
with:
path: /home/runner/.rustup
cache: |
rust
pnpm
- run: rustup component add rustfmt
if: steps.filter.outputs.changed == 'true'
- name: Check linter changes
if: steps.filter.outputs.changed == 'true'
run: |
cargo lintgen
pnpm --filter oxlint-app generate-config-types
cargo lint-timings
git diff --exit-code ||
(echo 'Linter generated files or timing snapshots have changed. Run `cargo lintgen`, `just linter-schema-json`, `just linter-config-ts`, and `cargo lint-timings`, then commit the generated files.' && exit 1)