ci(lint): consolidate lint into pre-commit, front-load locally - #16
Merged
Conversation
Move the scattered lint definitions (typos job in quality.yml, markdownlint step in docs.yml) into a single .pre-commit-config.yaml that runs both as local git hooks (fast feedback before push) and as a consolidated `Quality / pre-commit` job (enforcement gate for --no-verify bypasses and contributors without hooks installed). - Add .pre-commit-config.yaml: hygiene hooks + typos + markdownlint (commit stage) reusing the existing _typos.toml / .markdownlint.jsonc, plus local cargo fmt (commit) and clippy (pre-push) honouring rust-toolchain.toml. - quality.yml: replace the typos job with a pre-commit job (SKIP=fmt,clippy — the lightweight job has no toolchain; rust.yml runs those). - docs.yml: drop the markdownlint step; rename lint -> links (offline link check only). - Add CONTRIBUTING.md (setup + what-runs-where) and link it from README. rust.yml is unchanged: cargo fmt --check / clippy / test / build / deny stay where the toolchain and build cache live.
The pre-commit job has failed since this branch was opened. Three hooks rewrite files and exit non-zero: trailing-whitespace and end-of-file-fixer on docs/mermaid.min.js, and typos on both that file and .claude/skills/leanMultisig/SKILL.md. The cause is the assumption that hook tools reuse the repo's existing config files. That holds only when the tool walks the tree itself. pre-commit invokes hooks with an explicit list of paths, which bypasses every walk-time exclusion: typos honours `[files] extend-exclude` in _typos.toml and skips dotted directories only while walking, so naming docs/mermaid.min.js checks it anyway, and .claude/** comes into scope for the first time. That is why the standalone typos job is green while the identical tool fails here. Adds a top-level exclude for content no hook may rewrite — the vendored mdbook-mermaid assets, mdBook output, and Cargo.lock. Reformatting any of them produces a diff against upstream that the next regeneration undoes. Also registers "symetric" in _typos.toml. It is the real directory name in leanMultisig (crates/backend/symetric), misspelled upstream; the typos hook "corrected" our reference to it, which would have pointed readers at a path that does not exist. Registering the word fixes that regardless of how typos is invoked. Verified with `SKIP=fmt,clippy pre-commit run --all-files`: all hooks pass and no file is modified.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #5 (base
ci/static-analysis-scaffold). Retarget tomainafter #5 merges, or merge after it.Why
CI lint is scattered across three workflow definitions, so lint failures only surface after push — forcing a push → fail → fix → re-push round-trip.
NyxFoundation/verityis public, so GitHub Actions is free; the burden to cut is (1) those CI round-trips and (2) maintaining lint rules in three places.What
Consolidate lint into a single
.pre-commit-config.yaml, run as local git hooks (fast feedback before push) and as oneQuality / pre-commitjob (enforcement gate that still catches--no-verifybypasses and contributors who never ranpre-commit install)..pre-commit-config.yaml(new) — hygiene hooks +typos+markdownlint-cli2(commit stage), reusing the existing_typos.toml/.markdownlint.jsonc; localcargo fmt(commit) andclippy(pre-push) honourrust-toolchain.toml. No lint settings are duplicated.quality.yml— replace thetyposjob with apre-commitjob (SKIP=fmt,clippy: the lightweight job has no toolchain;rust.ymlruns those where the cache lives).docs.yml— drop the markdownlint step; renamelint→links(offline link check only).dependabot.yml— track thepre-commitecosystem so hookrevs auto-update.CONTRIBUTING.md(new) + README pointer — setup and a what-runs-where table.rust.ymlis unchanged:cargo fmt --check/clippy/test/build/denystay where the toolchain and build cache live.Config / execution split
The same config runs in both places by design: local = fast feedback, CI = enforcement. Only the execution runs twice (local is free; the CI lint run is a few seconds on a public runner) — the lint rules live in one file, so they never drift.
Verification
pre-commit run --all-files→ all hooks pass on the current tree (hygiene, typos, markdownlint, cargo fmt).pre-commit run --all-files --hook-stage pre-push→cargo clippypasses.SKIP=fmt,clippy pre-commit run --all-files→ mirrors the CI job;cargo fmtcorrectly skipped, rest pass.dependabot.ymlparse; no dangling job references (deployneedsbuild).