name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
jobs:
test:
name: Test (${{ matrix.os }}, ${{ matrix.rust }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
rust: [stable, nightly, "1.94"]
env:
RUSTUP_TOOLCHAIN: ${{ matrix.rust }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - uses: dtolnay/rust-toolchain@e2a55d2ffb04f378e9626c28d38b36d230d1e12f with:
toolchain: ${{ matrix.rust }}
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 - name: Build
run: cargo build
- name: Test lib and api
run: cargo test --lib --test api_test
- name: Test doctests
run: cargo test --doc
- name: Test global_callouts
run: cargo test --test global_callouts
- name: Test default_case_fold_flag
run: cargo test --test default_case_fold_flag
- name: Test parse_limits
run: cargo test --test parse_limits
- name: Test subexp_call_limits
run: cargo test --test subexp_call_limits
- name: Test backtrack_lint
run: cargo test --test backtrack_lint
- name: Test backtrack_rewrite
run: cargo test --test backtrack_rewrite
- name: Test stack_cap
run: cargo test --test stack_cap
- name: Test compat_syntax
run: cargo test --test compat_syntax
- name: Test compat_options
run: cargo test --test compat_options
- name: Test compat_regset
run: cargo test --test compat_regset
- name: Test scanner_prefilter_regressions
run: cargo test --test scanner_prefilter_regressions
- name: Test compat_prefilter_differential
run: cargo test --test compat_prefilter_differential
- name: Test compat_utf8
run: cargo test --test compat_utf8 -- --test-threads=1
env:
RUST_MIN_STACK: "536870912"
- name: Test compat_back
run: cargo test --test compat_back -- --test-threads=1
env:
RUST_MIN_STACK: "268435456"
precompiled:
name: Precompiled scanner patterns (MSRV)
runs-on: ubuntu-latest
env:
RUSTUP_TOOLCHAIN: "1.94"
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - uses: dtolnay/rust-toolchain@e2a55d2ffb04f378e9626c28d38b36d230d1e12f with:
toolchain: "1.94"
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 - name: Round trips and captured calls with checked prefilter
run: cargo test --locked --features precompiled,prefilter-self-check --lib --test precompiled_scanner --test compat_prefilter_differential
- name: Round trips and captured calls without prefilter
run: cargo test --locked --no-default-features --features precompiled --lib --test precompiled_scanner --test compat_prefilter_differential
- name: Precompiled API examples
run: cargo test --locked --features precompiled --doc
- name: Portable Eager archives and load-phase diagnostics
run: cargo test --locked --features precompiled-eager,scanner-load-profile --lib --test precompiled_scanner --test compat_prefilter_differential
- name: Selective prepared records with checked prefilter
run: cargo test --locked --features precompiled-eager,prefilter-self-check --test precompiled_eager --test precompiled_eager_records
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 with:
node-version: '24'
- name: Zstd-19 portable package transport
run: node --test scripts/portable-eager-package.test.mjs
fresh-resolution:
name: Fresh dependency resolution
runs-on: ubuntu-latest
env:
RUSTUP_TOOLCHAIN: stable
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - uses: dtolnay/rust-toolchain@e2a55d2ffb04f378e9626c28d38b36d230d1e12f with:
toolchain: stable
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 - name: Remove Cargo.lock for fresh resolution
run: rm -f Cargo.lock
- name: Build
run: cargo build --all-targets
- name: Test lib and api
run: cargo test --lib --test api_test
- name: Test doctests
run: cargo test --doc
coverage:
name: Coverage
runs-on: ubuntu-latest
env:
RUSTUP_TOOLCHAIN: nightly
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - uses: dtolnay/rust-toolchain@e2a55d2ffb04f378e9626c28d38b36d230d1e12f with:
toolchain: nightly
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 - name: Install cargo-llvm-cov
uses: taiki-e/install-action@1168f6810a3cb30a3514bf5756a3b7f0422c6df8 with:
tool: cargo-llvm-cov
- name: Measure coverage and enforce the gate
run: ./scripts/coverage.sh
ffi-smoke:
name: FFI feature smoke
runs-on: ubuntu-latest
env:
RUSTUP_TOOLCHAIN: stable
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - uses: dtolnay/rust-toolchain@e2a55d2ffb04f378e9626c28d38b36d230d1e12f with:
toolchain: stable
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 - name: Prepare Oniguruma sources
run: ./scripts/prepare-oniguruma-sources.sh
- name: Check ffi feature
run: cargo check --features ffi --all-targets
- name: Check source-backed regex corpus and comparison rules
run: |
python3 scripts/check-production-corpus.py
python3 -m unittest discover -s scripts/tests -p 'test_production*.py'
python3 -m unittest discover -s scripts/tests -p 'test_scanner*.py'
- name: Validate production regex tasks against source oracles
run: python3 scripts/compare-production.py validate "$RUNNER_TEMP/production-validation" --engines rust,rust_erroraware,c,pcre2_jit,pcre2,fancy_regex,fancy_regex_seek,regex
- name: Check ffi feature from the packaged crate
run: |
cargo package --no-verify
crate=$(ls target/package/ferroni-*.crate)
tar -xzf "$crate" -C target/package
pkg_dir="${crate%.crate}"
FERRONI_ONIGURUMA_DIR="$GITHUB_WORKSPACE/.cache/upstream/oniguruma-orig" \
cargo check --features ffi --manifest-path "$pkg_dir/Cargo.toml"
clippy:
name: Clippy
runs-on: ubuntu-latest
env:
RUSTUP_TOOLCHAIN: stable
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - uses: dtolnay/rust-toolchain@e2a55d2ffb04f378e9626c28d38b36d230d1e12f with:
toolchain: stable
components: clippy
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 - name: Prepare Oniguruma and Onigmo sources
run: |
./scripts/prepare-oniguruma-sources.sh
./scripts/prepare-onigmo-sources.sh
- run: cargo clippy --all-targets --all-features --locked -- -D warnings
- name: Verify public regex feature matrix
run: cargo test --all-features --locked --test regex_feature_matrix
- run: cargo clippy --all-targets --no-default-features --locked -- -D warnings
no-prefilter:
name: Test without the DFA pre-filter
runs-on: ubuntu-latest
env:
RUSTUP_TOOLCHAIN: stable
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - uses: dtolnay/rust-toolchain@e2a55d2ffb04f378e9626c28d38b36d230d1e12f with:
toolchain: stable
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 - name: Test lib, api and RegSet compat without the feature
run: cargo test --lib --test api_test --test compat_regset --test scanner_prefilter_regressions --test compat_prefilter_differential --no-default-features
prefilter-self-check:
name: Test with the pre-filter self-check
runs-on: ubuntu-latest
env:
RUSTUP_TOOLCHAIN: stable
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - uses: dtolnay/rust-toolchain@e2a55d2ffb04f378e9626c28d38b36d230d1e12f with:
toolchain: stable
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 - name: Test lib, api and the pre-filter suites with the self-check
run: cargo test --features prefilter-self-check --lib --test api_test --test compat_prefilter_differential --test scanner_prefilter_regressions
wasm:
name: WebAssembly
runs-on: ubuntu-latest
env:
RUSTUP_TOOLCHAIN: stable
CARGO_TARGET_WASM32_WASIP1_RUNNER: wasmtime -W max-wasm-stack=2097152 --dir=${{ github.workspace }}::${{ github.workspace }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - uses: dtolnay/rust-toolchain@e2a55d2ffb04f378e9626c28d38b36d230d1e12f with:
toolchain: stable
targets: wasm32-unknown-unknown, wasm32-wasip1
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 - name: Install Wasmtime
uses: taiki-e/install-action@1168f6810a3cb30a3514bf5756a3b7f0422c6df8 with:
tool: wasmtime
- name: Build for wasm32-unknown-unknown
run: cargo build --lib --locked --target wasm32-unknown-unknown
- name: Build for wasm32-unknown-unknown without the DFA pre-filter
run: cargo build --lib --locked --target wasm32-unknown-unknown --no-default-features
- name: Build archive loading for wasm32-unknown-unknown
run: cargo build --lib --locked --target wasm32-unknown-unknown --features precompiled-eager
- name: Test lib and api on wasm32-wasip1
run: >-
cargo test --locked --target wasm32-wasip1 --lib --test api_test --
--exact
--skip api::tests::capture_gate_is_shared_and_thread_safe
--skip api::tests::seek_automaton_is_built_once_for_racing_threads
--skip api::tests::result_drop_during_thread_local_teardown_does_not_panic
--skip dfa_prefilter::tests::adaptive_single_seek_promotes_safely_across_threads
--skip dfa_prefilter::tests::adaptive_single_seek_promotion_panic_falls_back_without_retry
--skip scanner::tests::scanners_sharing_a_pattern_cache_search_on_several_threads
--skip nested_groups_above_depth_limit_fail_cleanly_on_two_mib_stack
--skip nested_groups_at_depth_limit_compile_on_two_mib_stack
--skip nested_classes_above_depth_limit_fail_cleanly_on_two_mib_stack
--skip nested_classes_at_depth_limit_compile_on_two_mib_stack
--skip flat_alternation_above_ast_node_limit_fails_cleanly_on_two_mib_stack
--skip start_checks_panic_for_every_at_method
- name: Prepared Eager API on WASI
run: cargo test --locked --target wasm32-wasip1 --features precompiled-eager,prefilter-self-check --test precompiled_eager --test precompiled_eager_records
- name: Build import-free browser conformance example
run: cargo rustc --locked --release --target wasm32-unknown-unknown --features precompiled-eager --example precompiled_eager_portability -- -C link-arg=--export=main
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 with:
node-version: '24'
- name: Native archive in browser Wasm (V8 and Chrome)
run: node scripts/test-precompiled-eager-wasm.mjs target/wasm32-unknown-unknown/release/examples/precompiled_eager_portability.wasm --browser google-chrome
docs:
name: Rustdoc
runs-on: ubuntu-latest
env:
RUSTUP_TOOLCHAIN: stable
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - uses: dtolnay/rust-toolchain@e2a55d2ffb04f378e9626c28d38b36d230d1e12f with:
toolchain: stable
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 - run: cargo doc --no-deps --locked
env:
RUSTDOCFLAGS: -D warnings
- run: cargo doc --no-deps --locked
env:
RUSTDOCFLAGS: -D warnings
sample:
name: Home page sample
runs-on: ubuntu-latest
env:
RUSTUP_TOOLCHAIN: stable
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - uses: dtolnay/rust-toolchain@e2a55d2ffb04f378e9626c28d38b36d230d1e12f with:
toolchain: stable
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 with:
node-version: '24'
- name: Check the committed sample against the example
run: node docs/scripts/render-regex-sample.mjs --check
deny:
name: cargo-deny
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - uses: EmbarkStudios/cargo-deny-action@3c6349835b2b7b196a839186cb8b78e02f7b5f25 with:
arguments: --all-features --locked
readme-family:
name: README themes
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - uses: jdx/mise-action@08ae2a091c038e1e05ec6f5115dc5c69d5a2a6b8 with:
version: 2026.10.10
install_args: --locked
- name: Check the generated README
run: ./scripts/readme-family.sh check
- name: Check the README figures against the tree
run: ./scripts/check-readme-figures.sh
docs-format:
name: Docs format
runs-on: ubuntu-latest
defaults:
run:
working-directory: docs
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 with:
version: 12.11.2
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 with:
node-version: '24'
cache: 'pnpm'
cache-dependency-path: docs/pnpm-lock.yaml
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Lint documentation
run: pnpm lint
- name: Typecheck documentation
run: pnpm typecheck
- name: Check formatting
run: pnpm format:check
- name: Build documentation
run: pnpm build
env:
FERRIKI_ASSETS_BASE_URL: https://raw.githubusercontent.com/sebastian-software/ferriki
fmt:
name: Format
runs-on: ubuntu-latest
env:
RUSTUP_TOOLCHAIN: stable
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - uses: dtolnay/rust-toolchain@e2a55d2ffb04f378e9626c28d38b36d230d1e12f with:
toolchain: stable
components: rustfmt
- run: cargo fmt -- --check
- run: cargo fmt --manifest-path fuzz/Cargo.toml -- --check
- name: Check that workflow actions are pinned by SHA
run: ./scripts/check-workflow-pins.sh
standards:
name: standards drift
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
- name: "Guard: agent step not yet completed for this PR"
run: test ! -f .standards/pending.json
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 with:
version: 12.11.2
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 with:
node-version: '24'
- run: pnpm --config.minimum-release-age=0 dlx @sebastian-software/standards@0.13.0 check