Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (push) Skipped
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (push) Skipped
Build ErsatzTV Image / Delimiter ban (release path) (push) Successful in 28s
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 8m29s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 5m54s
Build ErsatzTV Image / Functional E2E (curl + UI contracts) (push) Successful in 5m59s
Build ErsatzTV Image / Build & push image (amd64) (push) Failing after 15s
Python lint here was a property of the operator's laptop: the global instructions
say to run ruff, no workflow ran it, and with no committed config ruff fell back
to whichever ~/.config/ruff/ruff.toml the machine happened to have.
- ruff.toml at the root, pinned ruff==0.12.11 in the script-tests job.
- Both lint steps pass an EXPLICIT population from `git ls-files` with
`--no-force-exclude`, never `ruff check .` — an `exclude` empties a
discovery-based run into a GREEN one (top level empties both commands, [lint]
empties check, [format] empties format --check), and `ruff check .` over zero
files exits 0 with only a stderr warning. Guarded by an empty-population arm.
- Tree clean: 74 findings at 706674272, 57 fixed in code, 17 per-site noqa with
reasons inline. S105 deliberately per-site, not a directory blanket. RUF100
selected so a suppression that suppresses nothing is itself a finding.
- pyright stays ungated; reasoning in the record.
Both steps witnessed red on the runner against the shipped bodies: run 2173 job
9176 (ruff check) and run 2170 job 9163 (ruff format --check).
Docs: new record ci.python-lint-ruff-config-committed, ci.script-tests-job
cross-ref, docs/ci-cd.md (also correcting a stale ~190-tests/~10s figure to the
measured 773 tests / ~4.5 min), docs/defect-shapes-773.md §5.2 resolved.
fixes #780
Co-authored-by: Timothy <timothy@noreply.gitea.tblindustries.be>
60 lines
3.2 KiB
TOML
60 lines
3.2 KiB
TOML
# Ruff configuration for this repo's Python surface (all of it lives under `scripts/`).
|
|
#
|
|
# WHY THIS FILE EXISTS (ersatztv#780). Without a committed config, ruff falls back to whatever
|
|
# `~/.config/ruff/ruff.toml` the operator's machine happens to have — so a second machine lints this
|
|
# repo differently, or not at all. That is the environment-divergence class #643/#647/#648 (a shell
|
|
# gate whose behaviour was a function of an untested interpreter version) and #512 (a test that
|
|
# passed on a fast laptop and flaked on a starved CI VM). The settings below are pinned HERE so the
|
|
# lint verdict is a property of the repo, not of the machine.
|
|
#
|
|
# It is enforced by the `script-tests` job (`Script lint and tests (ruff + pytest)`) in
|
|
# .gitea/workflows/pr-checks.yml. A config nobody runs is the same divergence one step later.
|
|
#
|
|
# That job does NOT invoke `ruff check .`: it passes an explicit population from `git ls-files` with
|
|
# `--no-force-exclude`. An `exclude` added to this file silently empties a discovery-based run into a
|
|
# GREEN one — a top-level `exclude` empties both commands, one under `[lint]` empties `check`, one
|
|
# under `[format]` (where an appended line lands, by TOML rules) empties `format --check`. Adding
|
|
# `exclude` here will therefore not do what you expect, which is the point. The measured matrix is in
|
|
# `ci.python-lint-ruff-config-committed`.
|
|
#
|
|
# `pyright` is deliberately NOT gated: its only findings here are `reportMissingImports` for
|
|
# `etv_client` in scripts/scripted-schedules/entrypoint.py, which resolves only inside that script's
|
|
# deploy environment, and gating it would put a node toolchain on the git-only `small` lane for zero
|
|
# real findings. Revisit if this repo grows a typed Python surface.
|
|
|
|
target-version = "py311"
|
|
line-length = 120
|
|
|
|
[lint]
|
|
select = [
|
|
"E", # pycodestyle errors
|
|
"W", # pycodestyle warnings
|
|
"F", # pyflakes
|
|
"I", # isort
|
|
"B", # flake8-bugbear
|
|
"UP", # pyupgrade
|
|
"SIM", # flake8-simplify
|
|
"S", # flake8-bandit (security)
|
|
# RUF100 is load-bearing, not tidiness: every `# noqa` below is an assertion that a real finding
|
|
# is being suppressed for a stated reason, and without this a suppression that suppresses nothing
|
|
# stays in the file reading as one. #780 did exactly that mid-branch — a `# noqa: UP031` on a site
|
|
# the same branch had already fixed in code — and found two more already in the tree: one whose
|
|
# rule had stopped firing, one for a rule this config never enables.
|
|
"RUF100",
|
|
]
|
|
ignore = [
|
|
"S603", # subprocess call - check for execution of untrusted input (too noisy for scripts)
|
|
"S607", # starting a process with a partial executable path
|
|
]
|
|
|
|
[lint.per-file-ignores]
|
|
# scripts/tests asserts, so S101 would fire on every test. S105 is deliberately NOT exempted here:
|
|
# the eight sites that trip it (`env["ETV_GITEA_TOKEN"] = "stub"`) carry a per-site `# noqa: S105`
|
|
# instead, so a real credential pasted into a fixture next year still reddens the gate. A directory
|
|
# blanket would have given up hardcoded-credential coverage over the largest Python surface in the
|
|
# repo, permanently, to suppress eight known lines.
|
|
"scripts/tests/**" = ["S101"]
|
|
|
|
[format]
|
|
quote-style = "double"
|