Skip to content

Ruff selection is documented org-wide but enforced per-repo, inconsistently #38

Description

@gavinbee

Follow-up to #36, which fixed this repo only. #36's root cause — a documented lint selection that no config file enforced — is not unique to .github. Verified against each repo's default branch on GitHub (not local checkouts):

Repo pyproject.toml select Lints in CI?
rems-sync yes ["E","F","I","W"] ci.yml
deck-eval-gen yes ["E","F","I","W"] ci.yml
.github no → added by #36 ci.yml
deck-eval-parser no notests.yml runs pytest only, and ruff isn't in requirements.txt or requirements-dev.txt
officials-admin no no workflows at all (CI arrives with #12)
swim-club-tech-survey no no — only run_survey.yml

Two distinct problems fall out.

1. Enforcement gap — lints, but with no config

A repo that runs ruff check . without a config uses the installed ruff's defaults, and with ruff>=0.6 those can change under it. That is #36 exactly: main green, next unrelated PR red. .github was the only repo in this state, which is the embarrassing part — the repo that publishes the standard was the one not following it.

2. Coverage gap — doesn't lint at all

deck-eval-parser and swim-club-tech-survey are outside the documented quality gate entirely. CONTRIBUTING.md § Quality gates says "Python repos use ruff", and for these it simply isn't true. deck-eval-parser has real code and its own tests.yml that never calls the shared reusable workflow.

Worth deciding whether that's intended (survey repo may be a scheduled script, not a maintained codebase) or drift. officials-admin is a known-pending case, not drift — #12 adds CI.

Why this can't just be "share the config"

Ruff has no remote config inheritance. extend takes a local path, so there is no way for six repos to point at one file in this one. Options, all with tradeoffs:

  1. Copy the config into each repo, plus a conformance check. reconcile-repo-defaults.yml already heals settings drift on a schedule; it could equally assert that every Python repo has a config whose selection matches the documented one. Keeps per-repo autonomy, catches drift, but the config itself is still duplicated.
  2. Centralize the flag in reusable-python-ci.yml — add a ruff-select input defaulting to the documented selection, so every consumer is deterministic without touching each repo. Recommended for enforcement. Caveat: a CLI --select overrides file config wholesale, including per-file-ignores, so a repo needing extra rules must pass the input rather than configure locally. No conflict today, since the two repos with config already match the default.
  3. Ship the config in a pip package and extend into site-packages. Genuinely shared, and fiddly enough that it probably isn't worth it at six repos.

1 and 2 compose well: 2 makes CI deterministic now, 1 keeps local ruff check . honest for developers, who don't run the workflow.

Acceptance criteria

  • Every repo that contains Python either lints with the documented selection or has an explicit, recorded reason not to.
  • Local ruff check . and CI agree — a developer can't be green locally and red in CI, or vice versa.
  • A new Python repo created via scripts/create-repo.sh starts out conformant, rather than relying on someone remembering to copy a config.
  • CONTRIBUTING.md § Quality gates describes what is actually enforced.

Known instance to fix in passing

officials-admin's requirements-dev.txt (added in swimblocks/officials-admin#16) declares no ruff, because that repo has no lint gate yet. Whatever this issue lands should cover it, or #12 should.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions