mirror of
https://github.com/astral-sh/ruff.git
synced 2026-10-28 10:45:37 +08:00
Pinning `cloudflare/wrangler-action` does not pin the `wrangler@4` package it installs during deployment. Install Wrangler from a dedicated, committed lockfile with lifecycle scripts disabled, then invoke that local executable directly. Require `npm>=11.10.0` with `engines.npm` and `engine-strict` so older clients cannot silently ignore the seven-day `min-release-age` policy, and pin Node.js to `24.19.0` at the install sites. Both playgrounds now use the reviewed dependency tree already recorded for the playground API, and Cloudflare credentials are passed only to the deployment command. Related: astral-sh/ruff#27839 isolates the playground builds from deployment credentials, and astral-sh/ruff#27844 enforces the corresponding `npm` floor in the existing package roots. astral-sh/ruff-vscode#1152 and astral-sh/ty-vscode#526 likewise give credentialed publishers their own locked toolchains. --------- Co-authored-by: zaniebot <242828183+zaniebot@users.noreply.github.com>
1398 lines
54 KiB
YAML
1398 lines
54 KiB
YAML
name: CI
|
|
|
|
permissions: {}
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
workflow_dispatch:
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.event.pull_request.number || github.sha }}
|
|
cancel-in-progress: true
|
|
|
|
defaults:
|
|
run:
|
|
shell: bash
|
|
|
|
env:
|
|
CARGO_INCREMENTAL: 0
|
|
CARGO_NET_RETRY: 10
|
|
CARGO_PROFILE_DEV_LTO: "false"
|
|
CARGO_PROFILE_DEV_OPT_LEVEL: 0
|
|
CARGO_TERM_COLOR: always
|
|
RUSTUP_MAX_RETRIES: 10
|
|
PACKAGE_NAME: ruff
|
|
PYTHON_VERSION: "3.14"
|
|
NEXTEST_PROFILE: ci
|
|
# Enable mdtests that require external dependencies
|
|
MDTEST_EXTERNAL: "1"
|
|
|
|
jobs:
|
|
determine_changes:
|
|
name: "Determine changes"
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
comparison_base: ${{ steps.merge_base.outputs.sha }}
|
|
# Flag that is raised when any code that affects parser is changed
|
|
parser: ${{ steps.check_parser.outputs.changed }}
|
|
# Flag that is raised when any code that affects linter is changed
|
|
linter: ${{ steps.check_linter.outputs.changed }}
|
|
# Flag that is raised when any code that affects formatter is changed
|
|
formatter: ${{ steps.check_formatter.outputs.changed }}
|
|
# Flag that is raised when any code is changed
|
|
# This is superset of the linter and formatter
|
|
code: ${{ steps.check_code.outputs.changed }}
|
|
# Flag that is raised when any code that affects the fuzzer is changed
|
|
fuzz: ${{ steps.check_fuzzer.outputs.changed }}
|
|
# Flag that is set to "true" when code related to ty changes.
|
|
ty: ${{ steps.check_ty.outputs.changed }}
|
|
# Flag that is set to "true" when code related to the py-fuzzer folder changes.
|
|
py-fuzzer: ${{ steps.check_py_fuzzer.outputs.changed }}
|
|
# Flag that is set to "true" when code related to the playground changes.
|
|
playground: ${{ steps.check_playground.outputs.changed }}
|
|
# Flag that is set to "true" when code related to the benchmarks changes.
|
|
benchmarks: ${{ steps.check_benchmarks.outputs.changed }}
|
|
# Flag that is set to "true" when release build inputs change.
|
|
release: ${{ steps.check_release.outputs.changed }}
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
|
|
# Faster to do this separately than to use `fetch-depth: 0` with `actions/checkout`
|
|
- name: Fetch full history without tags
|
|
run: git fetch --no-tags --filter=blob:none --unshallow origin
|
|
|
|
- name: Determine merge base
|
|
id: merge_base
|
|
env:
|
|
BASE_REF: ${{ github.event.pull_request.base.ref || 'main' }}
|
|
run: |
|
|
if [[ "$GITHUB_EVENT_NAME" == "pull_request" ]]; then
|
|
# The first parent contains any preceding layers in a stacked pull request.
|
|
sha="$(git rev-parse "${GITHUB_SHA}^1")"
|
|
else
|
|
sha="$(git merge-base HEAD "origin/${BASE_REF}")"
|
|
fi
|
|
echo "sha=${sha}" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Check if release build inputs changed
|
|
id: check_release
|
|
env:
|
|
MERGE_BASE: ${{ steps.merge_base.outputs.sha }}
|
|
run: |
|
|
if git diff --quiet "${MERGE_BASE}...HEAD" -- \
|
|
':pyproject.toml' \
|
|
':.github/workflows/build-binaries.yml' \
|
|
':scripts/build_ruff_pgo.py' \
|
|
; then
|
|
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: Check if the parser code changed
|
|
id: check_parser
|
|
env:
|
|
MERGE_BASE: ${{ steps.merge_base.outputs.sha }}
|
|
run: |
|
|
if git diff --quiet "${MERGE_BASE}...HEAD" -- \
|
|
':Cargo.toml' \
|
|
':Cargo.lock' \
|
|
':rust-toolchain.toml' \
|
|
':cargo/config.toml' \
|
|
':crates/ruff_python_trivia/**' \
|
|
':crates/ruff_source_file/**' \
|
|
':crates/ruff_text_size/**' \
|
|
':crates/ruff_python_ast/**' \
|
|
':crates/ruff_python_parser/**' \
|
|
':.github/workflows/ci.yaml' \
|
|
; then
|
|
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: Check if the linter code changed
|
|
id: check_linter
|
|
env:
|
|
MERGE_BASE: ${{ steps.merge_base.outputs.sha }}
|
|
run: |
|
|
if git diff --quiet "${MERGE_BASE}...HEAD" -- ':Cargo.toml' \
|
|
':Cargo.lock' \
|
|
':rust-toolchain.toml' \
|
|
':cargo/config.toml' \
|
|
':crates/**' \
|
|
':!crates/ty*/**' \
|
|
':!crates/ruff_python_formatter/**' \
|
|
':!crates/ruff_formatter/**' \
|
|
':!crates/ruff_dev/**' \
|
|
':!crates/ruff_benchmark/**' \
|
|
':scripts/*' \
|
|
':python/**' \
|
|
':.github/workflows/ci.yaml' \
|
|
; then
|
|
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: Check if the formatter code changed
|
|
id: check_formatter
|
|
env:
|
|
MERGE_BASE: ${{ steps.merge_base.outputs.sha }}
|
|
run: |
|
|
if git diff --quiet "${MERGE_BASE}...HEAD" -- ':Cargo.toml' \
|
|
':Cargo.lock' \
|
|
':rust-toolchain.toml' \
|
|
':cargo/config.toml' \
|
|
':crates/ruff_python_formatter/**' \
|
|
':crates/ruff_formatter/**' \
|
|
':crates/ruff_python_trivia/**' \
|
|
':crates/ruff_python_ast/**' \
|
|
':crates/ruff_source_file/**' \
|
|
':crates/ruff_python_index/**' \
|
|
':crates/ruff_python_index/**' \
|
|
':crates/ruff_text_size/**' \
|
|
':crates/ruff_python_parser/**' \
|
|
':scripts/*' \
|
|
':python/**' \
|
|
':.github/workflows/ci.yaml' \
|
|
; then
|
|
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: Check if the fuzzer code changed
|
|
id: check_fuzzer
|
|
env:
|
|
MERGE_BASE: ${{ steps.merge_base.outputs.sha }}
|
|
run: |
|
|
if git diff --quiet "${MERGE_BASE}...HEAD" -- ':Cargo.toml' \
|
|
':Cargo.lock' \
|
|
':rust-toolchain.toml' \
|
|
':cargo/config.toml' \
|
|
':fuzz/fuzz_targets/**' \
|
|
':.github/workflows/ci.yaml' \
|
|
; then
|
|
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: Check if the py-fuzzer code changed
|
|
id: check_py_fuzzer
|
|
env:
|
|
MERGE_BASE: ${{ steps.merge_base.outputs.sha }}
|
|
run: |
|
|
if git diff --quiet "${MERGE_BASE}...HEAD" -- 'python/py-fuzzer/**' \
|
|
; then
|
|
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: Check if there was any code related change
|
|
id: check_code
|
|
env:
|
|
MERGE_BASE: ${{ steps.merge_base.outputs.sha }}
|
|
run: |
|
|
# NOTE: Do not exclude all Markdown files here, but rather use
|
|
# specific exclude patterns like 'docs/**'), because tests for
|
|
# 'ty' are written in Markdown.
|
|
if git diff --quiet "${MERGE_BASE}...HEAD" -- \
|
|
':!docs/**' \
|
|
':!assets/**' \
|
|
; then
|
|
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: Check if there was any playground related change
|
|
id: check_playground
|
|
env:
|
|
MERGE_BASE: ${{ steps.merge_base.outputs.sha }}
|
|
run: |
|
|
if git diff --quiet "${MERGE_BASE}...HEAD" -- \
|
|
':playground/**' \
|
|
; then
|
|
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: Check if the ty code changed
|
|
id: check_ty
|
|
env:
|
|
MERGE_BASE: ${{ steps.merge_base.outputs.sha }}
|
|
run: |
|
|
if git diff --quiet "${MERGE_BASE}...HEAD" -- \
|
|
':Cargo.toml' \
|
|
':Cargo.lock' \
|
|
':rust-toolchain.toml' \
|
|
':cargo/config.toml' \
|
|
':crates/ty*/**' \
|
|
':crates/ruff_db/**' \
|
|
':crates/ruff_annotate_snippets/**' \
|
|
':crates/ruff_python_ast/**' \
|
|
':crates/ruff_python_parser/**' \
|
|
':crates/ruff_python_trivia/**' \
|
|
':crates/ruff_source_file/**' \
|
|
':crates/ruff_text_size/**' \
|
|
':.github/workflows/ci.yaml' \
|
|
; then
|
|
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: Check if the benchmark code changed
|
|
id: check_benchmarks
|
|
env:
|
|
MERGE_BASE: ${{ steps.merge_base.outputs.sha }}
|
|
run: |
|
|
if git diff --quiet "${MERGE_BASE}...HEAD" -- \
|
|
':Cargo.toml' \
|
|
':Cargo.lock' \
|
|
':rust-toolchain.toml' \
|
|
':cargo/config.toml' \
|
|
':crates/ruff_benchmark/**' \
|
|
':.github/workflows/ci.yaml' \
|
|
; then
|
|
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
cargo-fmt:
|
|
name: "cargo fmt"
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
- name: "Install Rust toolchain"
|
|
run: rustup component add rustfmt
|
|
- run: cargo fmt --all --check
|
|
|
|
shellcheck:
|
|
name: "shellcheck"
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
|
|
with:
|
|
go-version: "1.26.5"
|
|
- name: "Run ShellCheck"
|
|
env:
|
|
GOSUMDB: sum.golang.org
|
|
run: |
|
|
files=()
|
|
while IFS= read -r -d '' file; do
|
|
files+=("${file}")
|
|
done < <(git ls-files -z '*.sh')
|
|
if ((${#files[@]} == 0)); then
|
|
exit 0
|
|
fi
|
|
go run github.com/wasilibs/go-shellcheck/cmd/shellcheck@v0.11.1 "${files[@]}"
|
|
|
|
cargo-clippy:
|
|
name: "cargo clippy"
|
|
runs-on: ubuntu-latest
|
|
needs: determine_changes
|
|
if: ${{ needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main' }}
|
|
timeout-minutes: 20
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
|
|
with:
|
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
|
- name: "Install Rust toolchain"
|
|
run: |
|
|
rustup component add clippy
|
|
rustup target add wasm32-unknown-unknown
|
|
- name: "Clippy"
|
|
run: cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
|
|
- name: "Clippy (wasm)"
|
|
run: cargo clippy -p ruff_wasm -p ty_wasm --target wasm32-unknown-unknown --all-features --locked -- -D warnings
|
|
|
|
cargo-publish-dry-run:
|
|
name: "cargo publish dry-run"
|
|
runs-on: ${{ github.repository == 'astral-sh/ruff' && 'depot-ubuntu-22.04-8' || 'ubuntu-latest' }}
|
|
needs: determine_changes
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
|
|
timeout-minutes: 20
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
|
|
with:
|
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
|
- name: "cargo publish dry-run"
|
|
run: cargo publish --workspace --dry-run
|
|
|
|
cargo-test-linux:
|
|
name: "cargo test (linux)"
|
|
runs-on: ${{ github.repository == 'astral-sh/ruff' && 'depot-ubuntu-22.04-16' || 'ubuntu-latest' }}
|
|
needs: determine_changes
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
|
|
timeout-minutes: 20
|
|
env:
|
|
# Line-tables-only debug info: faster builds, backtraces still work.
|
|
CARGO_PROFILE_DEV_DEBUG: line-tables-only
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
|
|
with:
|
|
shared-key: ruff-linux-debug
|
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
|
- name: "Install Rust toolchain"
|
|
run: rustup show
|
|
- name: "Install mold"
|
|
uses: rui314/setup-mold@9c9c13bf4c3f1adef0cc596abc155580bcb04444 # v1
|
|
- name: "Install cargo nextest and insta"
|
|
uses: taiki-e/install-action@cb33e69fad06166ca28a42b2575e4dadabf62ee8 # v2.85.8
|
|
with:
|
|
tool: |
|
|
cargo-nextest
|
|
cargo-insta
|
|
- name: "Install uv"
|
|
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
with:
|
|
version: "0.12.5"
|
|
enable-cache: "true"
|
|
- name: ty mdtests (GitHub annotations)
|
|
if: ${{ needs.determine_changes.outputs.ty == 'true' }}
|
|
env:
|
|
NO_COLOR: 1
|
|
MDTEST_GITHUB_ANNOTATIONS_FORMAT: 1
|
|
# Ignore errors if this step fails; we want to continue to later steps in the workflow anyway.
|
|
# This step is just to get nice GitHub annotations on the PR diff in the files-changed tab.
|
|
run: cargo test -p ty_python_semantic --test mdtest || true
|
|
- name: "Run tests"
|
|
run: cargo insta test --all-features --unreferenced reject --test-runner nextest --disable-nextest-doctest
|
|
- name: "Run doctests"
|
|
run: cargo test --doc --all-features
|
|
- name: Dogfood ty on py-fuzzer
|
|
run: uv run --quiet --project=./python/py-fuzzer cargo run --quiet -p ty check --project=./python/py-fuzzer --color=always
|
|
- name: Dogfood ty on ty_benchmark
|
|
run: uv run --quiet --project=./scripts/ty_benchmark cargo run --quiet -p ty check --project=./scripts/ty_benchmark --color=always
|
|
- name: Dogfood ty on scripts
|
|
run: |
|
|
for script in scripts/*.py; do
|
|
echo "Checking $script"
|
|
uv sync --quiet --locked --script "$script"
|
|
cargo run --quiet -p ty check "$script" --python "$(uv python find --script "$script")" --color=always
|
|
done
|
|
# Check for broken links in the documentation.
|
|
- run: cargo doc --all --no-deps
|
|
env:
|
|
RUSTDOCFLAGS: "-D warnings"
|
|
# Use --document-private-items so that all our doc comments are kept in
|
|
# sync, not just public items. Eventually we should do this for all
|
|
# crates; for now add crates here as they are warning-clean to prevent
|
|
# regression.
|
|
- run: cargo doc --no-deps -p ty_python_semantic -p ty_python_core -p ty_module_resolver -p ty_site_packages -p ty_combine -p ty_project -p ty_ide -p ty_wasm -p ty_vendored -p ty_static -p ty -p ty_test -p ruff_db -p ruff_python_formatter --document-private-items
|
|
env:
|
|
# Setting RUSTDOCFLAGS because `cargo doc --check` isn't yet implemented (https://github.com/rust-lang/cargo/issues/10025).
|
|
RUSTDOCFLAGS: "-D warnings"
|
|
|
|
cargo-test-linux-release:
|
|
name: "cargo test (linux, release)"
|
|
# release builds timeout on GitHub runners, so this job is just skipped on forks in the `if` check
|
|
runs-on: depot-ubuntu-22.04-16
|
|
needs: determine_changes
|
|
if: |
|
|
github.repository == 'astral-sh/ruff' &&
|
|
!contains(github.event.pull_request.labels.*.name, 'no-test') &&
|
|
(needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main')
|
|
timeout-minutes: 20
|
|
env:
|
|
# Line-tables-only debug info: faster builds, backtraces still work.
|
|
CARGO_PROFILE_PROFILING_DEBUG: line-tables-only
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
|
|
with:
|
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
|
- name: "Install Rust toolchain"
|
|
run: rustup show
|
|
- name: "Install mold"
|
|
uses: rui314/setup-mold@9c9c13bf4c3f1adef0cc596abc155580bcb04444 # v1
|
|
- name: "Install cargo nextest"
|
|
uses: taiki-e/install-action@cb33e69fad06166ca28a42b2575e4dadabf62ee8 # v2.85.8
|
|
with:
|
|
tool: cargo-nextest
|
|
- name: "Install uv"
|
|
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
with:
|
|
version: "0.12.5"
|
|
enable-cache: "true"
|
|
- name: "Run tests"
|
|
run: cargo nextest run --cargo-profile profiling --all-features
|
|
- name: "Run doctests"
|
|
run: cargo test --doc --profile profiling --all-features
|
|
|
|
cargo-test-other:
|
|
strategy:
|
|
matrix:
|
|
platform:
|
|
- ${{ github.repository == 'astral-sh/ruff' && 'namespace-profile-windows-2022-x86-64-16x32' || 'windows-latest' }}
|
|
- ${{ github.repository == 'astral-sh/ruff' && 'namespace-profile-macos-15' || 'macos-latest' }}
|
|
name: "cargo test (${{ matrix.platform }})"
|
|
runs-on: ${{ matrix.platform }}
|
|
needs: determine_changes
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
|
|
timeout-minutes: 20
|
|
env:
|
|
# Line-tables-only debug info: faster builds, backtraces still work.
|
|
CARGO_PROFILE_DEV_DEBUG: line-tables-only
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
|
|
with:
|
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
|
# Fix for https://github.com/Swatinem/rust-cache/issues/341
|
|
cache-bin: "false"
|
|
- name: "Install Rust toolchain"
|
|
run: rustup show
|
|
- name: "Install cargo nextest"
|
|
uses: taiki-e/install-action@cb33e69fad06166ca28a42b2575e4dadabf62ee8 # v2.85.8
|
|
with:
|
|
tool: cargo-nextest
|
|
- name: "Install uv"
|
|
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
with:
|
|
version: "0.12.5"
|
|
enable-cache: "true"
|
|
- name: "Run tests"
|
|
run: |
|
|
cargo nextest run --all-features --profile ci
|
|
cargo test --all-features --doc
|
|
|
|
cargo-test-wasm:
|
|
name: "cargo test (wasm)"
|
|
runs-on: ubuntu-latest
|
|
needs: determine_changes
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
|
|
timeout-minutes: 10
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
|
|
with:
|
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
|
- name: "Install Rust toolchain"
|
|
run: rustup target add wasm32-unknown-unknown
|
|
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
with:
|
|
node-version: 24.19.0
|
|
cache: "npm"
|
|
cache-dependency-path: playground/package-lock.json
|
|
- uses: jetli/wasm-pack-action@0d096b08b4e5a7de8c28de67e11e945404e9eefa # v0.4.0
|
|
with:
|
|
version: v0.13.1
|
|
- name: "Test ruff_wasm"
|
|
run: |
|
|
cd crates/ruff_wasm
|
|
wasm-pack test --node
|
|
- name: "Test ty_wasm"
|
|
run: |
|
|
cd crates/ty_wasm
|
|
wasm-pack test --node
|
|
|
|
cargo-build-msrv:
|
|
name: "cargo build (msrv)"
|
|
runs-on: ${{ github.repository == 'astral-sh/ruff' && 'depot-ubuntu-24.04-8' || 'ubuntu-latest' }}
|
|
needs: determine_changes
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
|
|
timeout-minutes: 20
|
|
env:
|
|
# Line-tables-only debug info: faster builds, backtraces still work.
|
|
CARGO_PROFILE_DEV_DEBUG: line-tables-only
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
- uses: SebRollen/toml-action@b1b3628f55fc3a28208d4203ada8b737e9687876 # v1.2.0
|
|
id: msrv
|
|
with:
|
|
file: "Cargo.toml"
|
|
field: "workspace.package.rust-version"
|
|
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
|
|
with:
|
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
|
- name: "Install Rust toolchain"
|
|
env:
|
|
MSRV: ${{ steps.msrv.outputs.value }}
|
|
run: rustup default "${MSRV}"
|
|
- name: "Install mold"
|
|
uses: rui314/setup-mold@9c9c13bf4c3f1adef0cc596abc155580bcb04444 # v1
|
|
- name: "Build tests"
|
|
env:
|
|
MSRV: ${{ steps.msrv.outputs.value }}
|
|
run: cargo "+${MSRV}" test --no-run --all-features
|
|
|
|
cargo-fuzz-build:
|
|
name: "cargo fuzz build"
|
|
runs-on: ubuntu-latest
|
|
needs: determine_changes
|
|
if: ${{ github.ref == 'refs/heads/main' || needs.determine_changes.outputs.fuzz == 'true' || needs.determine_changes.outputs.code == 'true' }}
|
|
timeout-minutes: 10
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
|
|
with:
|
|
workspaces: "fuzz -> target"
|
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
|
- name: "Install Rust toolchain"
|
|
run: rustup show
|
|
- name: "Install mold"
|
|
uses: rui314/setup-mold@9c9c13bf4c3f1adef0cc596abc155580bcb04444 # v1
|
|
- name: "Install cargo-binstall"
|
|
uses: cargo-bins/cargo-binstall@e00d2c94cc0067b77737821097a62d91c0301baa # v1.21.1
|
|
- name: "Install cargo-fuzz"
|
|
# Download the latest version from quick install and not the github releases because github releases only has MUSL targets.
|
|
run: cargo binstall cargo-fuzz --force --disable-strategies crate-meta-data --no-confirm
|
|
- run: cargo fuzz build -s none
|
|
|
|
fuzz-parser:
|
|
name: "fuzz parser"
|
|
runs-on: ubuntu-latest
|
|
needs: determine_changes
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.parser == 'true' || needs.determine_changes.outputs.py-fuzzer == 'true') }}
|
|
timeout-minutes: 20
|
|
env:
|
|
FORCE_COLOR: 1
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
with:
|
|
version: "0.12.5"
|
|
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
|
|
with:
|
|
shared-key: ruff-linux-debug
|
|
save-if: false
|
|
- name: "Install Rust toolchain"
|
|
run: rustup show
|
|
- name: "Install mold"
|
|
uses: rui314/setup-mold@9c9c13bf4c3f1adef0cc596abc155580bcb04444 # v1
|
|
- name: Build Ruff binary
|
|
env:
|
|
# Line-tables-only debug info: faster builds, backtraces still work.
|
|
CARGO_PROFILE_DEV_DEBUG: line-tables-only
|
|
run: cargo build --bin ruff
|
|
- name: Fuzz
|
|
run: |
|
|
(
|
|
uv run \
|
|
--python="${PYTHON_VERSION}" \
|
|
--project=./python/py-fuzzer \
|
|
--locked \
|
|
fuzz \
|
|
--test-executable=target/debug/ruff \
|
|
--bin=ruff \
|
|
0-500
|
|
)
|
|
|
|
scripts:
|
|
name: "test scripts"
|
|
runs-on: ubuntu-latest
|
|
needs: determine_changes
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
|
|
timeout-minutes: 5
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
|
|
with:
|
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
|
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
with:
|
|
version: "0.12.5"
|
|
- name: "Install Rust toolchain"
|
|
run: rustup component add rustfmt
|
|
# Run all code generation scripts, and verify that the current output is
|
|
# already checked into git.
|
|
- run: python crates/ruff_python_ast/generate.py
|
|
- run: python crates/ruff_python_formatter/generate.py
|
|
- run: test -z "$(git status --porcelain)"
|
|
# Verify that adding a plugin or rule produces clean code.
|
|
- run: ./scripts/add_rule.py --name DoTheThing --prefix F --code 999 --linter pyflakes
|
|
- run: cargo check
|
|
- run: |
|
|
./scripts/add_plugin.py test --url https://pypi.org/project/-test/0.1.0/ --prefix TST
|
|
./scripts/add_rule.py --name FirstRule --prefix TST --code 001 --linter test
|
|
- run: cargo check
|
|
# Lint/format/type-check py-fuzzer
|
|
# (dogfooding with ty is done in a separate job)
|
|
- run: uv run --directory=./python/py-fuzzer mypy
|
|
- run: uv run --directory=./python/py-fuzzer ruff format --check
|
|
- run: uv run --directory=./python/py-fuzzer ruff check
|
|
|
|
ecosystem:
|
|
name: "ecosystem"
|
|
runs-on: ${{ github.repository == 'astral-sh/ruff' && 'depot-ubuntu-24.04-8' || 'ubuntu-latest' }}
|
|
needs: determine_changes
|
|
# Only runs on pull requests, since that is the only we way we can find the base version for comparison.
|
|
# Ecosystem check needs linter and/or formatter changes.
|
|
if: |
|
|
!contains(github.event.pull_request.labels.*.name, 'no-test') && github.event_name == 'pull_request' &&
|
|
(
|
|
needs.determine_changes.outputs.linter == 'true' ||
|
|
needs.determine_changes.outputs.formatter == 'true'
|
|
)
|
|
timeout-minutes: 20
|
|
env:
|
|
# Line-tables-only debug info: faster builds, backtraces still work.
|
|
CARGO_PROFILE_DEV_DEBUG: line-tables-only
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
ref: ${{ needs.determine_changes.outputs.comparison_base }}
|
|
persist-credentials: false
|
|
|
|
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
with:
|
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
activate-environment: true
|
|
version: "0.12.5"
|
|
|
|
- name: "Install Rust toolchain"
|
|
run: rustup show
|
|
|
|
- name: "Install mold"
|
|
uses: rui314/setup-mold@9c9c13bf4c3f1adef0cc596abc155580bcb04444 # v1
|
|
|
|
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
|
|
with:
|
|
shared-key: ruff-linux-debug
|
|
save-if: false
|
|
|
|
- name: Build baseline version
|
|
run: |
|
|
cargo build --bin ruff
|
|
mv target/debug/ruff target/debug/ruff-baseline
|
|
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
clean: false
|
|
|
|
- name: Build comparison version
|
|
run: cargo build --bin ruff
|
|
|
|
- name: Install ruff-ecosystem
|
|
run: |
|
|
uv pip install ./python/ruff-ecosystem
|
|
|
|
- name: Run `ruff check` stable ecosystem check
|
|
if: ${{ needs.determine_changes.outputs.linter == 'true' }}
|
|
run: |
|
|
# Set pipefail to avoid hiding errors with tee
|
|
set -eo pipefail
|
|
|
|
ruff-ecosystem check ./target/debug/ruff-baseline ./target/debug/ruff --cache ./checkouts --output-format markdown | tee ecosystem-result-check-stable
|
|
|
|
cat ecosystem-result-check-stable > "$GITHUB_STEP_SUMMARY"
|
|
echo "### Linter (stable)" > ecosystem-result
|
|
cat ecosystem-result-check-stable >> ecosystem-result
|
|
echo "" >> ecosystem-result
|
|
|
|
- name: Run `ruff check` preview ecosystem check
|
|
if: ${{ needs.determine_changes.outputs.linter == 'true' }}
|
|
run: |
|
|
# Set pipefail to avoid hiding errors with tee
|
|
set -eo pipefail
|
|
|
|
ruff-ecosystem check ./target/debug/ruff-baseline ./target/debug/ruff --cache ./checkouts --output-format markdown --force-preview | tee ecosystem-result-check-preview
|
|
|
|
cat ecosystem-result-check-preview > "$GITHUB_STEP_SUMMARY"
|
|
echo "### Linter (preview)" >> ecosystem-result
|
|
cat ecosystem-result-check-preview >> ecosystem-result
|
|
echo "" >> ecosystem-result
|
|
|
|
- name: Run `ruff format` stable ecosystem check
|
|
if: ${{ needs.determine_changes.outputs.formatter == 'true' }}
|
|
run: |
|
|
# Set pipefail to avoid hiding errors with tee
|
|
set -eo pipefail
|
|
|
|
ruff-ecosystem format ./target/debug/ruff-baseline ./target/debug/ruff --cache ./checkouts --output-format markdown | tee ecosystem-result-format-stable
|
|
|
|
cat ecosystem-result-format-stable > "$GITHUB_STEP_SUMMARY"
|
|
echo "### Formatter (stable)" >> ecosystem-result
|
|
cat ecosystem-result-format-stable >> ecosystem-result
|
|
echo "" >> ecosystem-result
|
|
|
|
- name: Run `ruff format` preview ecosystem check
|
|
if: ${{ needs.determine_changes.outputs.formatter == 'true' }}
|
|
run: |
|
|
# Set pipefail to avoid hiding errors with tee
|
|
set -eo pipefail
|
|
|
|
ruff-ecosystem format ./target/debug/ruff-baseline ./target/debug/ruff --cache ./checkouts --output-format markdown --force-preview | tee ecosystem-result-format-preview
|
|
|
|
cat ecosystem-result-format-preview > "$GITHUB_STEP_SUMMARY"
|
|
echo "### Formatter (preview)" >> ecosystem-result
|
|
cat ecosystem-result-format-preview >> ecosystem-result
|
|
echo "" >> ecosystem-result
|
|
|
|
# NOTE: astral-sh-bot uses this artifact to post comments on PRs.
|
|
# Make sure to update the bot if you rename the artifact.
|
|
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
name: Upload Results
|
|
with:
|
|
name: ecosystem-result
|
|
path: ecosystem-result
|
|
if-no-files-found: "error"
|
|
|
|
- name: Fail on ecosystem errors
|
|
run: |
|
|
if grep -q "project error" ecosystem-result; then
|
|
exit 1
|
|
fi
|
|
|
|
fuzz-ty:
|
|
name: "Fuzz for new ty panics"
|
|
runs-on: ${{ github.repository == 'astral-sh/ruff' && 'depot-ubuntu-22.04-16' || 'ubuntu-latest' }}
|
|
needs:
|
|
- determine_changes
|
|
# Only runs on pull requests, since that is the only we way we can find the base version for comparison.
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && github.event_name == 'pull_request' && (needs.determine_changes.outputs.ty == 'true' || needs.determine_changes.outputs.py-fuzzer == 'true') }}
|
|
timeout-minutes: ${{ github.repository == 'astral-sh/ruff' && 10 || 20 }}
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
# Faster to do this separately than to use `fetch-depth: 0` with `actions/checkout`
|
|
- name: Fetch full history without tags
|
|
run: git fetch --no-tags --filter=blob:none --unshallow origin
|
|
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
with:
|
|
version: "0.12.5"
|
|
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
|
|
with:
|
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
|
- name: "Install Rust toolchain"
|
|
run: rustup show
|
|
- name: "Install mold"
|
|
uses: rui314/setup-mold@9c9c13bf4c3f1adef0cc596abc155580bcb04444 # v1
|
|
- name: Fuzz
|
|
env:
|
|
FORCE_COLOR: 1
|
|
MERGE_BASE: ${{ needs.determine_changes.outputs.comparison_base }}
|
|
# Line-tables-only debug info: faster builds, backtraces still work.
|
|
CARGO_PROFILE_PROFILING_DEBUG: line-tables-only
|
|
run: |
|
|
echo "new commit"
|
|
git rev-list --format=%s --max-count=1 "$GITHUB_SHA"
|
|
cargo build --profile=profiling --bin=ty
|
|
mv target/profiling/ty ty-new
|
|
|
|
git checkout -b old_commit "$MERGE_BASE"
|
|
echo "old commit (merge base)"
|
|
git rev-list --format=%s --max-count=1 old_commit
|
|
cargo build --profile=profiling --bin=ty
|
|
mv target/profiling/ty ty-old
|
|
|
|
(
|
|
uv run \
|
|
--python="${PYTHON_VERSION}" \
|
|
--project=./python/py-fuzzer \
|
|
--locked \
|
|
fuzz \
|
|
--test-executable=ty-new \
|
|
--baseline-executable=ty-old \
|
|
--only-new-bugs \
|
|
--bin=ty \
|
|
0-1000
|
|
)
|
|
|
|
cargo-shear:
|
|
name: "cargo shear"
|
|
runs-on: ubuntu-latest
|
|
needs: determine_changes
|
|
if: ${{ needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main' }}
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
- uses: cargo-bins/cargo-binstall@e00d2c94cc0067b77737821097a62d91c0301baa # v1.21.1
|
|
- run: cargo binstall --no-confirm cargo-shear@1.12.4
|
|
- run: cargo shear --deny-warnings
|
|
|
|
ty-completion-evaluation:
|
|
name: "ty completion evaluation"
|
|
runs-on: ${{ github.repository == 'astral-sh/ruff' && 'depot-ubuntu-22.04-16' || 'ubuntu-latest' }}
|
|
needs: determine_changes
|
|
if: ${{ needs.determine_changes.outputs.ty == 'true' || github.ref == 'refs/heads/main' }}
|
|
env:
|
|
# Line-tables-only debug info: faster builds, backtraces still work.
|
|
CARGO_PROFILE_PROFILING_DEBUG: line-tables-only
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
with:
|
|
version: "0.12.5"
|
|
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
|
|
with:
|
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
|
- name: "Install Rust toolchain"
|
|
run: rustup show
|
|
- name: "Install mold"
|
|
uses: rui314/setup-mold@9c9c13bf4c3f1adef0cc596abc155580bcb04444 # v1
|
|
- name: "Run ty completion evaluation"
|
|
run: cargo run --profile profiling --package ty_completion_eval -- all --threshold 0.4 --tasks /tmp/completion-evaluation-tasks.csv
|
|
- name: "Ensure there are no changes"
|
|
run: diff ./crates/ty_completion_eval/completion-evaluation-tasks.csv /tmp/completion-evaluation-tasks.csv
|
|
|
|
python-package:
|
|
name: "python package"
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 20
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') }}
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
with:
|
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
architecture: x64
|
|
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
|
|
with:
|
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
|
- name: "Prep README.md"
|
|
run: python scripts/transform_readme.py --target pypi
|
|
- name: "Build wheels"
|
|
uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0
|
|
with:
|
|
args: --out dist
|
|
- name: "Test wheel"
|
|
run: |
|
|
pip install --force-reinstall --find-links dist "${PACKAGE_NAME}"
|
|
ruff --help
|
|
python -m ruff --help
|
|
- name: "Remove wheels from cache"
|
|
run: rm -rf target/wheels
|
|
|
|
pgo:
|
|
name: "PGO"
|
|
runs-on: depot-ubuntu-24.04-8
|
|
needs: determine_changes
|
|
if: ${{ needs.determine_changes.outputs.release == 'true' && !contains(github.event.pull_request.labels.*.name, 'no-build') }}
|
|
timeout-minutes: 20
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
with:
|
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
architecture: x64
|
|
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
|
|
with:
|
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
|
- name: "Install LLVM profiling tools"
|
|
run: rustup component add llvm-tools-preview
|
|
- name: "Run PGO pipeline"
|
|
run: python scripts/build_ruff_pgo.py --debug
|
|
|
|
prek:
|
|
name: "prek"
|
|
runs-on: ${{ github.repository == 'astral-sh/ruff' && 'depot-ubuntu-22.04-16' || 'ubuntu-latest' }}
|
|
timeout-minutes: 10
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
with:
|
|
version: "0.12.5"
|
|
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
with:
|
|
node-version: 24
|
|
- name: "Cache prek"
|
|
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
with:
|
|
path: ~/.cache/prek
|
|
key: prek-${{ hashFiles('.pre-commit-config.yaml') }}
|
|
- name: "Run prek"
|
|
run: |
|
|
echo '```console' > "$GITHUB_STEP_SUMMARY"
|
|
# Enable color output for prek and remove it for the summary
|
|
# Use --hook-stage=manual to enable slower hooks that are skipped by default
|
|
SKIP=rustfmt uv run --only-group dev --locked prek run --all-files --show-diff-on-failure --color always --hook-stage manual | \
|
|
tee >(sed -E 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})*)?[mGK]//g' >> "$GITHUB_STEP_SUMMARY") >&1
|
|
exit_code="${PIPESTATUS[0]}"
|
|
echo '```' >> "$GITHUB_STEP_SUMMARY"
|
|
exit "$exit_code"
|
|
|
|
docs:
|
|
name: "mkdocs"
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
|
|
with:
|
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
|
- name: "Install Rust toolchain"
|
|
run: rustup show
|
|
- name: Install uv
|
|
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
with:
|
|
python-version: 3.13
|
|
version: "0.12.5"
|
|
- name: "Update README File"
|
|
run: uv run scripts/transform_readme.py --target mkdocs
|
|
- name: "Generate docs"
|
|
run: uv run scripts/generate_mkdocs.py
|
|
- name: "Check docs formatting"
|
|
run: uv run scripts/check_docs_formatted.py
|
|
- name: "Build docs"
|
|
run: uv run --only-group=docs mkdocs build --strict -f mkdocs.yml
|
|
|
|
check-formatter-instability-and-black-similarity:
|
|
name: "formatter instabilities and black similarity"
|
|
runs-on: ubuntu-latest
|
|
needs: determine_changes
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.formatter == 'true' || github.ref == 'refs/heads/main') }}
|
|
timeout-minutes: 10
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
|
|
with:
|
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
|
- name: "Install Rust toolchain"
|
|
run: rustup show
|
|
- name: "Run checks"
|
|
run: scripts/formatter_ecosystem_checks.sh
|
|
- name: "Github step summary"
|
|
run: cat target/formatter-ecosystem/stats.txt > "$GITHUB_STEP_SUMMARY"
|
|
- name: "Remove checkouts from cache"
|
|
run: rm -r target/formatter-ecosystem
|
|
|
|
check-ruff-lsp:
|
|
name: "test ruff-lsp"
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
needs: determine_changes
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }}
|
|
env:
|
|
# Line-tables-only debug info: faster builds, backtraces still work.
|
|
CARGO_PROFILE_DEV_DEBUG: line-tables-only
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
name: "Checkout ruff source"
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
|
|
with:
|
|
shared-key: ruff-linux-debug
|
|
save-if: false
|
|
|
|
- name: "Install Rust toolchain"
|
|
run: rustup show
|
|
|
|
- name: "Install mold"
|
|
uses: rui314/setup-mold@9c9c13bf4c3f1adef0cc596abc155580bcb04444 # v1
|
|
|
|
- name: Build Ruff binary
|
|
run: cargo build -p ruff --bin ruff
|
|
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
name: "Checkout ruff-lsp source"
|
|
with:
|
|
persist-credentials: false
|
|
repository: "astral-sh/ruff-lsp"
|
|
path: ruff-lsp
|
|
|
|
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
with:
|
|
# ruff-lsp's archived CI only tested through Python 3.12.
|
|
python-version: "3.12"
|
|
|
|
- name: Install ruff-lsp dependencies
|
|
run: uv sync --locked --only-group ruff-lsp-test --python 3.12
|
|
|
|
- name: Run ruff-lsp tests
|
|
run: |
|
|
# Setup development binary
|
|
export PATH="${PWD}/target/debug:${PWD}/.venv/bin:${PATH}"
|
|
ruff version
|
|
|
|
cd ruff-lsp
|
|
pytest
|
|
|
|
check-playground:
|
|
name: "check playground"
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
needs:
|
|
- determine_changes
|
|
if: ${{ (needs.determine_changes.outputs.playground == 'true') }}
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
- name: "Install Rust toolchain"
|
|
run: rustup target add wasm32-unknown-unknown
|
|
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
|
|
with:
|
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
|
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
with:
|
|
node-version: 24.19.0
|
|
cache: "npm"
|
|
cache-dependency-path: |
|
|
playground/package-lock.json
|
|
playground/deploy/package-lock.json
|
|
- uses: jetli/wasm-bindgen-action@20b33e20595891ab1a0ed73145d8a21fc96e7c29 # v0.2.0
|
|
- name: "Check deployment dependencies"
|
|
env:
|
|
WRANGLER_SEND_METRICS: "false"
|
|
WRANGLER_SEND_ERROR_REPORTS: "false"
|
|
run: |
|
|
npm ci --ignore-scripts
|
|
./node_modules/.bin/wrangler --version
|
|
working-directory: playground/deploy
|
|
- name: "Install Node dependencies"
|
|
run: npm ci --ignore-scripts
|
|
working-directory: playground
|
|
- name: "Build playgrounds"
|
|
run: npm run dev:build
|
|
working-directory: playground
|
|
- name: "Run TypeScript checks"
|
|
run: npm run check
|
|
working-directory: playground
|
|
- name: "Check formatting"
|
|
run: npm run fmt:check
|
|
working-directory: playground
|
|
|
|
benchmarks-instrumented-ruff:
|
|
name: "benchmarks instrumented (ruff)"
|
|
runs-on: ubuntu-24.04
|
|
needs: determine_changes
|
|
if: |
|
|
github.repository == 'astral-sh/ruff' &&
|
|
(
|
|
github.ref == 'refs/heads/main' ||
|
|
needs.determine_changes.outputs.formatter == 'true' ||
|
|
needs.determine_changes.outputs.linter == 'true' ||
|
|
needs.determine_changes.outputs.parser == 'true' ||
|
|
needs.determine_changes.outputs.benchmarks == 'true'
|
|
)
|
|
timeout-minutes: 20
|
|
permissions:
|
|
contents: read # required for actions/checkout
|
|
id-token: write # required for OIDC authentication with CodSpeed
|
|
steps:
|
|
- name: "Checkout Branch"
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
|
|
with:
|
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
|
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
with:
|
|
version: "0.12.5"
|
|
|
|
- name: "Install Rust toolchain"
|
|
run: rustup show
|
|
|
|
- name: "Install codspeed"
|
|
uses: taiki-e/install-action@cb33e69fad06166ca28a42b2575e4dadabf62ee8 # v2.85.8
|
|
with:
|
|
tool: cargo-codspeed
|
|
|
|
- name: "Build benchmarks"
|
|
run: cargo codspeed build -m simulation -m memory --features "codspeed,ruff_instrumented" --profile profiling --no-default-features -p ruff_benchmark --bench formatter --bench lexer --bench linter --bench parser
|
|
|
|
- name: "Run benchmarks"
|
|
uses: CodSpeedHQ/action@0ca9cbbf4623b599a6c3ed4fc8a922942705d9f1 # v5.0.2
|
|
with:
|
|
mode: "simulation,memory"
|
|
run: cargo codspeed run
|
|
|
|
benchmarks-instrumented-ty-build:
|
|
name: "benchmarks instrumented ty (build)"
|
|
runs-on: depot-ubuntu-24.04-4
|
|
needs: determine_changes
|
|
if: |
|
|
github.repository == 'astral-sh/ruff' &&
|
|
(
|
|
github.ref == 'refs/heads/main' ||
|
|
needs.determine_changes.outputs.ty == 'true' ||
|
|
needs.determine_changes.outputs.benchmarks == 'true'
|
|
)
|
|
timeout-minutes: 20
|
|
steps:
|
|
- name: "Checkout Branch"
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
|
|
with:
|
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
|
|
|
- name: "Install Rust toolchain"
|
|
run: rustup show
|
|
|
|
- name: "Install codspeed"
|
|
uses: taiki-e/install-action@cb33e69fad06166ca28a42b2575e4dadabf62ee8 # v2.85.8
|
|
with:
|
|
tool: cargo-codspeed
|
|
|
|
- name: "Build benchmarks"
|
|
run: cargo codspeed build -m simulation -m memory --features "codspeed,module_resolution,ty_instrumented" --profile profiling --no-default-features -p ruff_benchmark --bench module_resolution --bench ty --bench ty_constraint_set
|
|
|
|
- name: "Upload benchmark binary"
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: benchmarks-instrumented-ty-binary
|
|
compression-level: 1
|
|
path: target/codspeed
|
|
if-no-files-found: "error"
|
|
retention-days: 1
|
|
|
|
benchmarks-instrumented-ty-run:
|
|
name: "benchmarks instrumented ty (${{ matrix.mode }}: ${{ matrix.name }})"
|
|
runs-on: ubuntu-24.04
|
|
needs: benchmarks-instrumented-ty-build
|
|
timeout-minutes: 20
|
|
permissions:
|
|
contents: read # required for actions/checkout
|
|
id-token: write # required for OIDC authentication with CodSpeed
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- name: micro
|
|
target: ty
|
|
filter: micro
|
|
mode: simulation
|
|
- name: micro
|
|
target: ty
|
|
filter: micro
|
|
mode: memory
|
|
- name: constraint_set
|
|
target: ty_constraint_set
|
|
filter: micro
|
|
mode: simulation
|
|
- name: constraint_set
|
|
target: ty_constraint_set
|
|
filter: micro
|
|
mode: memory
|
|
- name: projects
|
|
target: ty
|
|
filter: "check_file|anyio|attrs|hydra|datetype"
|
|
mode: simulation
|
|
- name: projects
|
|
target: ty
|
|
filter: "check_file|anyio|attrs|hydra|datetype"
|
|
mode: memory
|
|
- name: module_resolution
|
|
target: module_resolution
|
|
filter: ty_module_resolver
|
|
mode: simulation
|
|
steps:
|
|
- name: "Checkout Branch"
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
with:
|
|
version: "0.12.5"
|
|
|
|
- name: "Install codspeed"
|
|
uses: taiki-e/install-action@cb33e69fad06166ca28a42b2575e4dadabf62ee8 # v2.85.8
|
|
with:
|
|
tool: cargo-codspeed
|
|
|
|
- name: "Download benchmark binary"
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: benchmarks-instrumented-ty-binary
|
|
path: target/codspeed
|
|
|
|
- name: "Restore binary permissions"
|
|
# codspeed keeps changing the paths to the executable, so we have to be a bit more flexible
|
|
run: find target/codspeed -type f -exec chmod +x {} +
|
|
|
|
- name: "Run benchmarks"
|
|
uses: CodSpeedHQ/action@0ca9cbbf4623b599a6c3ed4fc8a922942705d9f1 # v5.0.2
|
|
with:
|
|
mode: ${{ matrix.mode }}
|
|
cycle-estimation: false
|
|
run: cargo codspeed run --bench "${{ matrix.target }}" "${{ matrix.filter }}"
|
|
|
|
benchmarks-walltime-build:
|
|
name: "benchmarks walltime (build)"
|
|
# We only run this job if `github.repository == 'astral-sh/ruff'`,
|
|
# so hardcoding depot here is fine
|
|
runs-on: depot-ubuntu-22.04-arm-4
|
|
needs: determine_changes
|
|
if: |
|
|
github.repository == 'astral-sh/ruff' &&
|
|
(
|
|
!contains(github.event.pull_request.labels.*.name, 'no-test') &&
|
|
(
|
|
needs.determine_changes.outputs.ty == 'true' ||
|
|
needs.determine_changes.outputs.benchmarks == 'true' ||
|
|
github.ref == 'refs/heads/main'
|
|
)
|
|
)
|
|
timeout-minutes: 20
|
|
steps:
|
|
- name: "Checkout Branch"
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
|
|
with:
|
|
save-if: ${{ github.ref == 'refs/heads/main' }}
|
|
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
with:
|
|
version: "0.12.5"
|
|
|
|
- name: "Install Rust toolchain"
|
|
run: rustup show
|
|
|
|
- name: "Install codspeed"
|
|
uses: taiki-e/install-action@cb33e69fad06166ca28a42b2575e4dadabf62ee8 # v2.85.8
|
|
with:
|
|
tool: cargo-codspeed
|
|
|
|
- name: "Build benchmarks"
|
|
run: cargo codspeed build -m walltime --features "codspeed,ty_walltime" --profile profiling --no-default-features -p ruff_benchmark --bench ty_walltime
|
|
|
|
- name: "Upload benchmark binary"
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: benchmarks-walltime-binary
|
|
compression-level: 1
|
|
path: target/codspeed
|
|
if-no-files-found: "error"
|
|
retention-days: 1
|
|
|
|
benchmarks-walltime-run:
|
|
name: "benchmarks walltime (${{ matrix.benchmark.name }})"
|
|
runs-on: codspeed-macro
|
|
needs: benchmarks-walltime-build
|
|
timeout-minutes: 20
|
|
permissions:
|
|
contents: read # required for actions/checkout
|
|
id-token: write # required for OIDC authentication with CodSpeed
|
|
strategy:
|
|
matrix:
|
|
benchmark:
|
|
- name: sympy
|
|
target: ty_walltime
|
|
filter: sympy
|
|
- name: "pandas|tanjun"
|
|
target: ty_walltime
|
|
filter: "pandas|tanjun"
|
|
- name: "colour_science|static_frame"
|
|
target: ty_walltime
|
|
filter: "colour_science|static_frame"
|
|
- name: "pydantic|freqtrade|multithreaded|altair"
|
|
target: ty_walltime
|
|
filter: "pydantic|freqtrade|multithreaded|altair"
|
|
steps:
|
|
- name: "Checkout Branch"
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
|
|
with:
|
|
version: "0.12.5"
|
|
|
|
- name: "Install codspeed"
|
|
uses: taiki-e/install-action@cb33e69fad06166ca28a42b2575e4dadabf62ee8 # v2.85.8
|
|
with:
|
|
tool: cargo-codspeed
|
|
|
|
- name: "Download benchmark binary"
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: benchmarks-walltime-binary
|
|
path: target/codspeed
|
|
|
|
- name: "Restore binary permissions"
|
|
# codspeed keeps changing the paths to the executable, so we have to be a bit more flexible
|
|
run: find target/codspeed -type f -exec chmod +x {} +
|
|
|
|
- name: "Run benchmarks"
|
|
uses: CodSpeedHQ/action@0ca9cbbf4623b599a6c3ed4fc8a922942705d9f1 # v5.0.2
|
|
env:
|
|
# enabling walltime flamegraphs adds ~6 minutes to the CI time, and they don't
|
|
# appear to provide much useful insight for our walltime benchmarks right now
|
|
# (see https://github.com/astral-sh/ruff/pull/20419)
|
|
CODSPEED_PERF_ENABLED: false
|
|
with:
|
|
mode: walltime
|
|
run: cargo codspeed run --bench "${{ matrix.benchmark.target }}" -m walltime "${{ matrix.benchmark.filter }}"
|
|
|
|
required-checks-passed:
|
|
name: "all required checks passed"
|
|
if: always()
|
|
needs:
|
|
- cargo-fmt
|
|
- cargo-clippy
|
|
- cargo-test-linux
|
|
- cargo-test-wasm
|
|
- cargo-build-msrv
|
|
- shellcheck
|
|
- scripts
|
|
- prek
|
|
- docs
|
|
- python-package
|
|
runs-on: ubuntu-slim
|
|
steps:
|
|
- name: "Check required jobs passed"
|
|
run: |
|
|
failing=$(echo "$NEEDS_JSON" | jq -r 'to_entries[] | select(.value.result != "success" and .value.result != "skipped") | "\(.key): \(.value.result)"')
|
|
if [ -n "$failing" ]; then
|
|
echo "$failing"
|
|
exit 1
|
|
fi
|
|
env:
|
|
NEEDS_JSON: ${{ toJSON(needs) }}
|