ci: run pre-commit on pull requests, and repair the hooks it runs - #22
Merged
Conversation
Nothing in CI ran the pre-commit hook set, so the eight hooks in .pre-commit-config.yaml only fired for contributors who had run `pre-commit install` locally. Two of them could never have fired for anyone. Fixes to .pre-commit-config.yaml: - The config has been invalid YAML since it was added (017ebcc, 2026-03-02, its only commit): branch-name-check's unquoted `entry:` contains ": " inside its error message, which YAML reads as a nested mapping. `pre-commit run` aborts with InvalidConfigError, so every hook in the file — trailing-whitespace, end-of-file-fixer, check-yaml, check-merge-conflict, check-added-large-files, codespell, dco-check, branch-name-check — has never executed. Rewritten as a folded block scalar. - dco-check inspected `git log -1`, which at commit-msg stage is the PARENT commit, not the message being written. It therefore passed whenever the previous commit happened to be signed off, regardless of the current one. It now greps the commit-msg file pre-commit passes in ("$1") and prints a usable hint on failure. - codespell gains `-L wit,WIT`. With the config repaired, codespell flags 14 occurrences of WIT/wit, the WebAssembly Interface Types format named throughout wasm-plugin.md, map/SKILL.md and README.md. smg's own codespell args already carry `wit,WIT` for this reason. New workflow .github/workflows/pr-checks.yml, three jobs: - pre-commit — installs pre-commit and runs `--all-files --show-diff-on-failure`, skipping the two local git-stage hooks that cannot run over a checkout. Mirrors smg's pre-commit job. - commit-messages — DCO sign-off on every commit in the PR range, and the forbidden AI co-author/sign-off check, ported from smg's pr-naming-check.yml. - branch-name — enforces the same prefixes branch-name-check allows, on internal PRs only (forks exempt). Existing pr-title-check.yml is untouched. Verified locally with pre-commit 4.6.2: all six checkout-stage hooks pass; branch-name-check passes on chore/* and fails with the right message on a bad name; dco-check now passes a signed message and fails an unsigned one; the DCO loop and attribution grep were run against real commit ranges in both directions. Signed-off-by: Alex McC <319643551+hello-alexmcc@users.noreply.github.com>
On pull_request events actions/checkout checks out GitHub's generated merge commit (refs/pull/N/merge), which carries no Signed-off-by and never will. The DCO walk flagged it and failed every PR. Both commit range walks now pass --no-merges, which also matches the usual DCO convention of exempting merge commits. Signed-off-by: Alex McC <319643551+hello-alexmcc@users.noreply.github.com>
slin1237
approved these changes
Aug 26, 2026
The main branch ruleset requires three status checks that nothing in this repo produced, so every PR sat BLOCKED with all its checks green, waiting on contexts that would never report: finish (GitHub Actions) -- no such job Conventional Commit Title (GitHub Actions) -- job reported as check-title DCO (DCO app, 1861) -- app not enabled on this repo The contexts were copied from smg, where all three are real. This fixes the two an Actions workflow can satisfy, rather than editing the ruleset: - pr-title-check.yml: the job now carries name: Conventional Commit Title, so its check run reports under the required context. - pr-checks.yml: new aggregate finish job (needs all three PR jobs, if: always()) that fails when any of them failed or was cancelled. skipped is allowed, since commit-messages and branch-name do not run on push and branch-name is skipped for fork PRs. The DCO context needs an org owner to add this repo to the existing smg-project dco app installation (150406607); it cannot be satisfied from Actions because the ruleset pins it to integration 1861. Signed-off-by: Alex McC <319643551+hello-alexmcc@users.noreply.github.com>
hello-alexmcc
force-pushed
the
chore/pre-commit-ci
branch
from
August 26, 2026 14:13
a31c4a8 to
d1802b3
Compare
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.
Follow-up to #21. While checking that PR's CI I found that only
PR Title Checkran — because it is the only workflow in the repo. Digging in, the pre-commit hook set has never worked at all.Two bugs in
.pre-commit-config.yaml1. The config has been invalid YAML since the day it was added (
017ebcc, 2026-03-02 — its only commit).branch-name-check's unquotedentry:contains": "inside its own error message, which YAML parses as a nested mapping:So
pre-commit installandpre-commit runhave always aborted, and none of the eight hooks has ever executed for anyone — nottrailing-whitespace,end-of-file-fixer,check-yaml,check-merge-conflict,check-added-large-files,codespell,dco-check, norbranch-name-check. Rewritten as a folded block scalar.2.
dco-checkvalidated the wrong commit. It rangit log -1, which atcommit-msgstage is the parent commit — the one being written doesn't exist yet. It passed whenever the previous commit happened to carry a sign-off, regardless of the current one. Demonstrated before the fix:It now greps the commit-msg file pre-commit passes in (
"$1") and prints an actionable hint. After the fix, that same message fails and a signed one passes.3.
codespellgains-L wit,WIT. With the config repaired, codespell fires for the first time and flags 14 occurrences ofWIT/wit— the WebAssembly Interface Types format name, used throughoutwasm-plugin.md,map/SKILL.mdandREADME.md. smg's own codespell args already carrywit,WITfor exactly this reason, so this mirrors the sibling repo rather than inventing an exception.New workflow
.github/workflows/pr-checks.yml, three jobs.pr-title-check.ymlis untouched.pre-commitpre-commit run --all-files --show-diff-on-failure, skipping the two local git-stage hooks that cannot run over a checkout. Mirrors smg'spre-commitjob.commit-messagespr-naming-check.yml.branch-namebranch-name-checkallows. Internal PRs only; forks exempt, as in smg.Verification
Run locally with pre-commit 4.6.2 against a repaired config:
Both repaired hooks were tested in both directions:
branch-name-checkpasses onchore/*and fails with the correct message on a bad name;dco-checkpasses a signed message and fails an unsigned one. The workflow's DCO loop and attribution grep were run against real commit ranges, including a deliberately unsigned commit, which the loop correctly rejected.One thing for you to decide
There is a pre-existing mismatch this PR mirrors rather than resolves:
pr-title-check.ymlaccepts the title typeci:, but the branch-prefix list (setup|feat|fix|docs|chore|refactor) has noci/*. This PR is therefore onchore/pre-commit-ciwith aci:title. If you would rather allowci/*branches, that is a one-line addition to both.pre-commit-config.yamland the newbranch-namejob — say the word and I will add it.Follow-up commit (
9eca55d): the first CI run of this very workflow failed its own DCO job — the only "unsigned commit" it found wase6d3561 Merge e357bb5 into e119304, GitHub's generated merge commit, whichactions/checkoutchecks out onpull_requestevents and which carries no sign-off. Both commit-range walks now pass--no-merges, matching the usual DCO convention of exempting merges. All four checks green after the fix.Why PRs were showing no CI at all (
a31c4a8)The deeper cause of "CI never runs": the
mainruleset ("PRs & conventional commits", active, no bypass actors) requires three status checks that nothing in this repo produced, so every PR satBLOCKEDwaiting on contexts that would never report:finishConventional Commit Titlecheck-titleDCO1861)All three were copied from smg, where they are real (
finishatpr-test-rust.yml:1192,PR Title & Commit Messagesatpr-naming-check.yml:59, plus the DCO app). The guide's copy hand-edited one name and never created matching jobs. Nobody hit it because the last merge was #20 on 2026-07-15 and the ruleset was tightened on 2026-07-31 — #21 and #22 are the first PRs since.Fixed on the runner side rather than by weakening the ruleset:
pr-title-check.yml— job now carriesname: Conventional Commit Title, so its check run reports under the required context.pr-checks.yml— new aggregatefinishjob (needsall three PR jobs,if: always()) that fails if any failed or was cancelled.skippedis allowed, sincecommit-messagesandbranch-namedo not run onpushandbranch-nameis skipped for fork PRs.finishandConventional Commit Titlenow report and pass.DCOstill needs an org owner to add this repo (1170922059) to the existing smg-projectdcoinstallation (150406607) — it cannot be satisfied from Actions, because the ruleset pins that context to integration1861.