Reference configs

astral-sh/ruff: 8 internal crates without publish = false

Ruff's internal crates are meant to set publish = false so they can't reach crates.io by mistake, but only habit keeps it that way; CI doesn't check it. One toml_path_equals rule does, and found 8 crates without it, among them ruff_graph and ruff_markdown.This config was written to test alint; Ruff doesn't use alint.

What alint found

.alint.yml
- id: ruff-internal-crates-unpublished
  kind: toml_path_equals
  paths:
    include: ["crates/*/Cargo.toml"]
    exclude:
      - "crates/ruff/Cargo.toml"
      - "crates/ruff_linter/Cargo.toml"
      - "crates/ruff_wasm/Cargo.toml"
  path: "$.package.publish"
  equals: false
  level: warning

⚠︎ warning ruff-internal-crates-unpublished

Eight internal crates don't set publish = false, among them ruff_graph and ruff_markdown. Any that are meant to be published belong in the rule's exclude list.

.alint.yml
extends:
  - alint://bundled/oss-baseline@v1
  - alint://bundled/ci/github-actions@v1

ℹ︎ info oss-security-policy-exists

There's no SECURITY.md or code of conduct at the root. Astral keeps both in its organization's .github repository, which GitHub shows on every project; the rule reads only this repository.

The bundled GitHub Actions rules (alint 0.16.1, on the workflows as of 7 May 2026) flag notify-dependents.yml, which declares no permissions, and release.yml, which grants contents: write at the workflow level.

The config

Ruff has no structural checker of its own; crates/ruff_dev/ generates code and prints internals. The config checks the crate and pyproject.toml fields, that the JSON schemas for Ruff and ty are current, and that Ruff's linter and formatter don't import ty's crates. The pre-commit tools and the CI checks run from command rules. It extends seven bundled rulesets, among them rust, python and monorepo/cargo-workspace.

.alint.yml
- id: ruff-no-upward-ty-imports
  kind: import_gate
  paths:
    include: ["crates/ruff_linter/**/*.rs", "crates/ruff_python_formatter/**/*.rs"]
    exclude: ["crates/**/tests/**", "crates/**/resources/**"]
  language: rust
  forbid: "^ty_"
  level: warning

Ruff's linter and formatter crates may not import ty's type-checker crates. import_gate reads each use statement.

.alint.yml
- id: ruff-schema-json-fresh
  # fixed here: dry-run prints the schema; check mode prints "Up-to-date"
  kind: generated_file_fresh
  file: ruff.schema.json
  command: ["cargo", "dev", "generate-json-schema", "--mode", "dry-run"]
  workdir: "."
  normalize: final-newline
  timeout: 300
  level: error

ruff.schema.json has to match what cargo dev generate-json-schema prints. The companion rule for ty uses the same dry-run output and final-newline normalization.

What stays outside alint

Builds, tests and the tools' own analysis stay in CI:

  • about 18 CI jobs that build and test Ruff and ty;
  • Clippy's lints and cargo-shear's check for unused dependencies, which the config runs but doesn't replace;
  • the ecosystem check, which compares Ruff's results on other projects between versions, and the strict mkdocs build;
  • failing on snapshot files that no test uses. alint's pair rule checks only the other direction.