Enforce pre-commit in CI so lint debt cannot re-accumulate #58

Closed
opened 2026-07-15 15:38:31 +00:00 by claude-bot · 2 comments
Contributor

From the 2026-07-15 review follow-ups. .pre-commit-config.yaml exists but is evidently not being run — the codebase failed ruff check in 159 places (#41). Keep #41's cleanup from eroding:

  • Add a pre-commit run --all-files CI job (or verify the ruff/mypy/eslint CI jobs cover every hook in the config, and delete redundancy in one direction or the other)
  • Ensure hook versions in .pre-commit-config.yaml match the versions CI installs (Renovate can manage pre-commit hooks: add pre-commit to renovate.json managers)
  • CONTRIBUTING.md: make pre-commit install a prominent first-time setup step

Depends on: #41 (must be green first).

From the 2026-07-15 review follow-ups. `.pre-commit-config.yaml` exists but is evidently not being run — the codebase failed `ruff check` in 159 places (#41). Keep #41's cleanup from eroding: - [ ] Add a `pre-commit run --all-files` CI job (or verify the ruff/mypy/eslint CI jobs cover every hook in the config, and delete redundancy in one direction or the other) - [ ] Ensure hook versions in `.pre-commit-config.yaml` match the versions CI installs (Renovate can manage pre-commit hooks: add `pre-commit` to renovate.json managers) - [ ] CONTRIBUTING.md: make `pre-commit install` a prominent first-time setup step Depends on: #41 (must be green first).
claude-bot added this to the v1.0.0 milestone 2026-07-15 15:38:31 +00:00
Author
Contributor

Audited 2026-09-01 — not started, and the second half of the first checkbox turns out to matter.

This issue offers a choice: add a pre-commit run --all-files job, or verify the existing CI jobs already cover every hook. I checked the second option, and they don't.

.pre-commit-config.yaml declares 8 hooks. CI covers 2 of them:

Hook Covered by CI?
ruff Ruff lint
ruff-format Ruff format check
trailing-whitespace
end-of-file-fixer
check-yaml
check-merge-conflict
check-added-large-files
prettier

So the "delete the redundancy in one direction" escape hatch isn't available — six hooks have no CI equivalent at all. check-added-large-files and check-merge-conflict in particular guard against things that are annoying to undo once merged.

Also confirmed: pre-commit is not in renovate.json, so the pinned revs (v4.6.0, v0.6.9, v3.1.0) drift silently. Renovate has a first-class pre-commit manager; it needs enabling explicitly since it's off by default.

Remaining work is unchanged, but now with the ambiguity resolved:

  • Add a pre-commit run --all-files job (the alternative is ruled out — 6 of 8 hooks are uncovered)
  • Add pre-commit to Renovate's enabled managers so hook revs track
  • CONTRIBUTING.md: make pre-commit install a prominent first-time setup step

One caveat for whoever picks this up: ruff and ruff-format would then run twice per push, and the pinned hook rev (v0.6.9) can disagree with the ruff version uv installs — a version skew that produces a job failing on formatting CI considers clean. Either pin both to the same version or drop the duplicate ruff hooks from the pre-commit job.

**Audited 2026-09-01 — not started, and the second half of the first checkbox turns out to matter.** This issue offers a choice: add a `pre-commit run --all-files` job, *or* verify the existing CI jobs already cover every hook. I checked the second option, and they don't. `.pre-commit-config.yaml` declares 8 hooks. CI covers 2 of them: | Hook | Covered by CI? | |---|---| | `ruff` | ✅ `Ruff lint` | | `ruff-format` | ✅ `Ruff format check` | | `trailing-whitespace` | ❌ | | `end-of-file-fixer` | ❌ | | `check-yaml` | ❌ | | `check-merge-conflict` | ❌ | | `check-added-large-files` | ❌ | | `prettier` | ❌ | So the "delete the redundancy in one direction" escape hatch isn't available — six hooks have no CI equivalent at all. `check-added-large-files` and `check-merge-conflict` in particular guard against things that are annoying to undo once merged. Also confirmed: **`pre-commit` is not in `renovate.json`**, so the pinned `rev`s (`v4.6.0`, `v0.6.9`, `v3.1.0`) drift silently. Renovate has a first-class `pre-commit` manager; it needs enabling explicitly since it's off by default. Remaining work is unchanged, but now with the ambiguity resolved: - [ ] Add a `pre-commit run --all-files` job (the alternative is ruled out — 6 of 8 hooks are uncovered) - [ ] Add `pre-commit` to Renovate's enabled managers so hook revs track - [ ] CONTRIBUTING.md: make `pre-commit install` a prominent first-time setup step One caveat for whoever picks this up: `ruff` and `ruff-format` would then run twice per push, and the pinned hook `rev` (v0.6.9) can disagree with the ruff version `uv` installs — a version skew that produces a job failing on formatting CI considers clean. Either pin both to the same version or drop the duplicate ruff hooks from the pre-commit job.
Author
Contributor

Done in #108.

  • pre-commit run --all-files CI job added. The alternative this issue offered — verifying the existing jobs already cover every hook — was checked and ruled out: they covered 2 of 8.
  • pre-commit added to Renovate's managers. It is off by default, which is exactly why the hook revs had gone stale.
  • CONTRIBUTING.md makes pre-commit install a first-time step ahead of the backend/frontend sections.

What running them for the first time found

  • check-yaml was failing on docker-compose.registry.yml — Compose's !reset tag is not standard YAML. Excluded; Compose validates that file on every deploy.
  • The ruff skew this issue's follow-up warned about was real: hook pinned v0.6.9, uv sync resolved 0.15.21. Pinned together, with Renovate now keeping them in step.
  • The prettier hook was removed. It had never run, prettier is not a frontend dependency, and mirrors-prettier is archived upstream — it would have reformatted 62 files / ~4,950 lines. Frontend style stays gated by ESLint's --max-warnings 0. Adopting prettier properly is separate work and deserves its own issue if wanted.

The one that nearly went wrong

trailing-whitespace needed --markdown-linebreak-ext=md. Two trailing spaces are a hard line break in Markdown, and without the flag the hook stripped them and silently reflowed the docs — merging consecutive lines of iris-spec.md's schema list into one paragraph. The full suite had already run green and the change was staged before I read the fixer's actual diff. Worth remembering that "it only removes whitespace" is not a safe assumption for a formatter.

Accumulated debt after that turned out to be two lines — a stray blank line at the end of iris-spec.md and a missing final newline in DayCell.test.tsx. Better than #41's history suggested.

Closing.

**Done in #108.** - [x] **`pre-commit run --all-files` CI job added.** The alternative this issue offered — verifying the existing jobs already cover every hook — was checked and ruled out: they covered **2 of 8**. - [x] **`pre-commit` added to Renovate's managers.** It is off by default, which is exactly why the hook revs had gone stale. - [x] **CONTRIBUTING.md** makes `pre-commit install` a first-time step ahead of the backend/frontend sections. ### What running them for the first time found - **`check-yaml` was failing** on `docker-compose.registry.yml` — Compose's `!reset` tag is not standard YAML. Excluded; Compose validates that file on every deploy. - **The ruff skew this issue's follow-up warned about was real**: hook pinned `v0.6.9`, `uv sync` resolved `0.15.21`. Pinned together, with Renovate now keeping them in step. - **The prettier hook was removed.** It had never run, `prettier` is not a frontend dependency, and `mirrors-prettier` is archived upstream — it would have reformatted 62 files / ~4,950 lines. Frontend style stays gated by ESLint's `--max-warnings 0`. Adopting prettier properly is separate work and deserves its own issue if wanted. ### The one that nearly went wrong `trailing-whitespace` needed `--markdown-linebreak-ext=md`. **Two trailing spaces are a hard line break in Markdown**, and without the flag the hook stripped them and silently reflowed the docs — merging consecutive lines of `iris-spec.md`'s schema list into one paragraph. The full suite had already run green and the change was staged before I read the fixer's actual diff. Worth remembering that "it only removes whitespace" is not a safe assumption for a formatter. Accumulated debt after that turned out to be **two lines** — a stray blank line at the end of `iris-spec.md` and a missing final newline in `DayCell.test.tsx`. Better than #41's history suggested. Closing.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rbrooks/Iris-WLED#58
No description provided.