| 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: |
| UV_LOCKED: 1 |
| CARGO_INCREMENTAL: 0 |
| CARGO_NET_RETRY: 10 |
| CARGO_PROFILE_DEV_LTO: "false" |
| CARGO_PROFILE_DEV_OPT_LEVEL: 0 |
| CARGO_TERM_COLOR: always |
| # renovate: datasource=github-releases depName=astral-sh/hawk |
| HAWK_VERSION: 0.1.13 |
| 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: ${{ github.repository == 'astral-sh/ruff' && 'github-ubuntu-24.04-x86_64-4' || '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_edits/**' \ |
| ':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: ${{ github.repository == 'astral-sh/ruff' && 'github-ubuntu-24.04-x86_64-4' || '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: ${{ github.repository == 'astral-sh/ruff' && 'github-ubuntu-24.04-x86_64-4' || '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: ${{ github.repository == 'astral-sh/ruff' && 'github-ubuntu-24.04-x86_64-4' || '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 |
| |
| hawk: |
| name: "cargo hawk" |
| runs-on: ${{ github.repository == 'astral-sh/ruff' && 'github-ubuntu-24.04-x86_64-4' || 'ubuntu-latest' }} |
| needs: determine_changes |
| if: ${{ needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main' }} |
| timeout-minutes: 15 |
| steps: |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 |
| with: |
| persist-credentials: false |
| - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 |
| with: |
| workspaces: ". -> target/hawk" |
| cache-workspace-crates: "false" |
| save-if: ${{ github.ref == 'refs/heads/main' }} |
| - name: "Install Rust toolchain" |
| run: rustup toolchain install 1.98.0 |
| - name: "Install Hawk" |
| run: | |
| curl --proto '=https' --tlsv1.2 -LsSf \ |
| "https://github.com/astral-sh/hawk/releases/download/${HAWK_VERSION}/cargo-hawk-installer.sh" | sh |
| - name: "Hawk" |
| run: cargo +1.98.0 hawk check --target-dir target/hawk -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 uv" |
| uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1 |
| with: |
| version: "0.12.11" |
| 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: uv run --locked --only-dev 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 |
| env: |
| # Enable experimental support for installing PEP 723 script dependencies. |
| TY_UV: scripts |
| UV_LOCKED: "true" |
| run: cargo run --quiet -p ty check scripts/*.py --color=always |
| # 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 uv" |
| uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1 |
| with: |
| version: "0.12.11" |
| enable-cache: "true" |
| - name: "Run tests" |
| run: uv run --locked --only-dev 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 uv" |
| uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1 |
| with: |
| version: "0.12.11" |
| enable-cache: "true" |
| - name: "Run tests" |
| run: | |
| uv run --locked --only-dev cargo nextest run --all-features --profile ci |
| cargo test --all-features --doc |
| |
| cargo-test-wasm: |
| name: "cargo test (wasm)" |
| runs-on: ${{ github.repository == 'astral-sh/ruff' && 'github-ubuntu-24.04-x86_64-4' || '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: ${{ github.repository == 'astral-sh/ruff' && 'github-ubuntu-24.04-x86_64-4' || '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 |
| - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1 |
| with: |
| version: "0.12.11" |
| - run: uv run --only-dev cargo fuzz build -s none |
| |
| fuzz-parser: |
| name: "fuzz parser" |
| runs-on: ${{ github.repository == 'astral-sh/ruff' && 'github-ubuntu-24.04-x86_64-4' || '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.11" |
| - 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: ${{ github.repository == 'astral-sh/ruff' && 'github-ubuntu-24.04-x86_64-4' || '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.11" |
| - 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 --category correctness |
| - 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 --category correctness |
| - 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.11" |
| |
| - 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 "$RUNNER_TEMP/ruff-ecosystem-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 "$RUNNER_TEMP/ruff-ecosystem-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 "$RUNNER_TEMP/ruff-ecosystem-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 "$RUNNER_TEMP/ruff-ecosystem-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.11" |
| - 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: ${{ github.repository == 'astral-sh/ruff' && 'github-ubuntu-24.04-x86_64-4' || '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: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1 |
| with: |
| version: "0.12.11" |
| - run: uv run --only-dev 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.11" |
| - 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: ${{ github.repository == 'astral-sh/ruff' && 'github-ubuntu-24.04-x86_64-4' || '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.11" |
| - 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-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: ${{ github.repository == 'astral-sh/ruff' && 'github-ubuntu-24.04-x86_64-4' || '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.11" |
| - 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: ${{ github.repository == 'astral-sh/ruff' && 'github-ubuntu-24.04-x86_64-4' || '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: ${{ github.repository == 'astral-sh/ruff' && 'github-ubuntu-24.04-x86_64-4' || '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: ${{ github.repository == 'astral-sh/ruff' && 'github-ubuntu-24.04-x86_64-4' || '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: depot-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.11" |
| |
| - name: "Install Rust toolchain" |
| run: rustup show |
| |
| - name: "Build benchmarks" |
| run: uv run --only-dev 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: "Configure apt mirror fallback" |
| run: | |
| # Let CodSpeed's dependency installation move past unhealthy mirrors quickly. |
| cat /etc/apt/apt-mirrors.txt |
| printf '%s\n' \ |
| 'Acquire::Retries "0";' \ |
| 'Acquire::http::Timeout "10";' \ |
| 'Acquire::https::Timeout "10";' \ |
| | sudo tee /etc/apt/apt.conf.d/80-retries > /dev/null |
| |
| - name: "Run benchmarks" |
| uses: CodSpeedHQ/action@4296e51e7041e24dadb86d1d6e8b9320d223dbe8 # v5.0.3 |
| with: |
| mode: "simulation,memory" |
| run: uv run --only-dev 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' }} |
| |
| - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1 |
| with: |
| version: "0.12.11" |
| |
| - name: "Install Rust toolchain" |
| run: rustup show |
| |
| - name: "Build benchmarks" |
| run: uv run --only-dev 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: depot-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-a-l |
| target: ty |
| filter: 'ty_micro\[[a-l]' |
| mode: simulation |
| - name: micro-m-z |
| target: ty |
| filter: 'ty_micro\[[^a-l]' |
| mode: simulation |
| - name: micro-a-l |
| target: ty |
| filter: 'ty_micro\[[a-l]' |
| mode: memory |
| - name: micro-m-z |
| target: ty |
| filter: 'ty_micro\[[^a-l]' |
| 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.11" |
| |
| - 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: "Configure apt mirror fallback" |
| if: matrix.mode == 'simulation' |
| run: | |
| # Let CodSpeed's dependency installation move past unhealthy mirrors quickly. |
| cat /etc/apt/apt-mirrors.txt |
| printf '%s\n' \ |
| 'Acquire::Retries "0";' \ |
| 'Acquire::http::Timeout "10";' \ |
| 'Acquire::https::Timeout "10";' \ |
| | sudo tee /etc/apt/apt.conf.d/80-retries > /dev/null |
| |
| - name: "Run benchmarks" |
| uses: CodSpeedHQ/action@4296e51e7041e24dadb86d1d6e8b9320d223dbe8 # v5.0.3 |
| with: |
| mode: ${{ matrix.mode }} |
| run: uv run --only-dev 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.11" |
| |
| - name: "Install Rust toolchain" |
| run: rustup show |
| |
| - name: "Build benchmarks" |
| run: uv run --only-dev cargo codspeed build -m walltime --features "codspeed,ty_walltime" --profile profiling --no-default-features -p ruff_benchmark --bench ty_walltime --bench ty_script |
| |
| - 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: script |
| target: ty_script |
| - 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.11" |
| |
| - 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@4296e51e7041e24dadb86d1d6e8b9320d223dbe8 # v5.0.3 |
| 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 |
| # Benchmarks manage any disposable uv environments they create. |
| UV_LOCKED: 0 |
| with: |
| mode: walltime |
| run: uv run --locked --only-dev 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 |
| - hawk |
| - cargo-test-linux |
| - cargo-test-wasm |
| - cargo-build-msrv |
| - shellcheck |
| - scripts |
| - prek |
| - docs |
| - python-package |
| runs-on: ${{ github.repository == 'astral-sh/ruff' && 'github-ubuntu-24.04-x86_64-2' || '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) }} |