ci: make the lefthook pre-push hook actually install (#4642)

## Summary

`lefthook.yml` has been in the repo since #4147, but nothing installs
lefthook and nothing runs `lefthook install`, so the pre-push hook it
describes has never fired for anyone. #3977 had removed the `lefthook`
devDependency a week before #4147 landed, and #4147 only added the
config file.

This supplies the missing half:

```diff
+    "prepare": "lefthook install",
+    "lefthook": "^2.1.10",
       "onlyBuiltDependencies": [
+      "lefthook",
```

With those in place, `pnpm install` wires the hook up on clone, and the
format and lint checks actually run before a push instead of first
failing in CI.

Also here: the pre-push jobs run in parallel rather than in sequence,
and `CONTRIBUTING.md` documents the hook, including how to skip it and
the fact that GitButler only runs hooks when "Run hooks" is enabled in
its settings.

`lefthook@2.1.10` is the current release.
This commit is contained in:
nicktrn
2026-08-17 08:24:32 +01:00
committed by GitHub
parent 3d0b46fee5
commit 6e7710282c
6 changed files with 140 additions and 2 deletions
+1
View File
@@ -21,6 +21,7 @@
"**/storybook-static/",
"**/.changeset/",
"**/dist/",
"**/.worktrees/",
"internal-packages/tsql/src/grammar/",
"internal-packages/llm-model-catalog/src/defaultPrices.ts",
"internal-packages/llm-model-catalog/src/modelCatalog.ts",
+1
View File
@@ -12,6 +12,7 @@
"ignorePatterns": [
"**/dist/**",
"**/build/**",
"**/.worktrees/**",
"**/*.d.ts",
"**/seed.js",
"**/seedCloud.ts",
+13
View File
@@ -214,6 +214,19 @@ pnpm exec trigger dev --log-level debug
5. Commit the generated migration files as well as the changes to `schema.prisma`.
6. If you're using VSCode you may need to restart the TypeScript server in the webapp to get updated type inference. Open a TypeScript file, then open the Command Palette (View > Command Palette) and run `TypeScript: Restart TS server`.
## Git hooks (lefthook)
We use [lefthook](https://lefthook.dev) for local git hooks, configured in `lefthook.yml` (the source of truth for what runs and when). Today that's a pre-push hook mirroring the CI `code-quality` checks; the set may grow, so check `lefthook.yml` rather than this guide.
Hooks install automatically on `pnpm install`. A failing hook prints exactly what to run to fix it.
**Opting out**
- GitButler skips hooks on `but push` unless you enable **Run hooks** in the project settings (off by default).
- Plain git: `LEFTHOOK=0 git push` / `--no-verify` to skip once; `pnpm exec lefthook uninstall` to remove.
This never affects correctness — CI enforces the same checks on every PR; the hooks just give you faster feedback.
## Making a pull request
**If you get errors, be sure to fix them before committing.**
+23 -2
View File
@@ -10,8 +10,29 @@ pre-commit:
# implementation and only runs hooks when "Run hooks" is enabled in its
# settings - with that off, this protects plain `git push` only.
pre-push:
parallel: true
jobs:
- name: format
run: pnpm exec oxfmt --check .
run: |
pnpm exec oxfmt --check . || {
echo ""
echo "✖ Formatting issues found. Fix them with:"
echo ""
echo " pnpm run format"
echo ""
echo " then stage the changes and re-push."
echo ""
exit 1
}
- name: lint
run: pnpm exec oxlint .
run: |
pnpm exec oxlint . || {
echo ""
echo "✖ Lint errors found. Auto-fix what's fixable with:"
echo ""
echo " pnpm run lint:fix"
echo ""
echo " then review, stage, and re-push (some rules need a manual fix)."
echo ""
exit 1
}
+2
View File
@@ -63,6 +63,7 @@
"@vitest/coverage-v8": "4.1.7",
"autoprefixer": "^10.4.12",
"knip": "6.25.0",
"lefthook": "^2.1.10",
"oxfmt": "^0.54.0",
"oxlint": "^1.69.0",
"pkg-pr-new": "0.0.75",
@@ -157,6 +158,7 @@
"better-sqlite3",
"cpu-features",
"esbuild",
"lefthook",
"prisma",
"protobufjs",
"sharp",
+100
View File
@@ -136,6 +136,9 @@ importers:
knip:
specifier: 6.25.0
version: 6.25.0
lefthook:
specifier: ^2.1.10
version: 2.1.10
oxfmt:
specifier: ^0.54.0
version: 0.54.0
@@ -11918,6 +11921,60 @@ packages:
leac@0.6.0:
resolution: {integrity: sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==}
lefthook-darwin-arm64@2.1.10:
resolution: {integrity: sha512-nw+X8wRNDoUUV6WSteyKBbcLySq+fsmZt5WV/s50ZJpysmsDKJOUMln6SllNfP+60dzUahAO7REco/2633BsLg==}
cpu: [arm64]
os: [darwin]
lefthook-darwin-x64@2.1.10:
resolution: {integrity: sha512-KQ/bHmvpkFdHMn4pZnUdTf+GuSC+aBBgBTxZT4GW+6cSf+qbErKZBhK7cH6BmILsvx43+VzEArvHYY7YOfRFOQ==}
cpu: [x64]
os: [darwin]
lefthook-freebsd-arm64@2.1.10:
resolution: {integrity: sha512-8su6DwydP7+pv7kG0zCtjphqsw4ouOnfexRUErapy5GTxYBoUOhYz3RSHTSWNRsK6W4jva7FPUh2Lp5/PSn30w==}
cpu: [arm64]
os: [freebsd]
lefthook-freebsd-x64@2.1.10:
resolution: {integrity: sha512-GeAJEFxko3Lk+AsnS3NleAFrpyMLFUKOlgJvPKuU0xHwVEI/z+ZoCcmuO0BX+4CS0NLbZhC/YQAvBASqDvvVdQ==}
cpu: [x64]
os: [freebsd]
lefthook-linux-arm64@2.1.10:
resolution: {integrity: sha512-1sHTCmpTWjVMs+yKPBLRNT1kuuIr1yjietlk7rCB6wFPVOS6Ph3o2zPFH2AvW1UymHlqwyHXzBr9EtDpQ7j1mQ==}
cpu: [arm64]
os: [linux]
lefthook-linux-x64@2.1.10:
resolution: {integrity: sha512-z/VlRB3bh6mBvW3r1rwnJ5vP8z+Krx5gJzkZ4veDXh+6FlRTx8wtd3g3fllOv/yZMxkgmL3fQoFXv05Esa7vBQ==}
cpu: [x64]
os: [linux]
lefthook-openbsd-arm64@2.1.10:
resolution: {integrity: sha512-430zL8sSIKw5P0YXGG6PB+eAhHa06n0PXuaERaAQE4Ss3odfqwnl5Mq9hQmkEnOS1EGiQEKkd0UHv/i4PtMNIQ==}
cpu: [arm64]
os: [openbsd]
lefthook-openbsd-x64@2.1.10:
resolution: {integrity: sha512-bgkO8PphGZVDhQgCJ524aYYPI5491pVmCiLPGjBIo1AvOSlIyw4N1Y+1C3QfqwEmechzw+Aq16SNc8pqv6UuXg==}
cpu: [x64]
os: [openbsd]
lefthook-windows-arm64@2.1.10:
resolution: {integrity: sha512-5Q6etF0Fla2DDA4ilDySrdNgiR5+W7cJZwnZ69Je3kvWCaWm4wnkuc8FEdjp3kiL2x3ZXipdI00f5vpO8aWmog==}
cpu: [arm64]
os: [win32]
lefthook-windows-x64@2.1.10:
resolution: {integrity: sha512-c/XH8YZtylG4XaxzqFfXluvq2LXq2W/p54Bnzn3+Z7E5X2Fk3JlFJAibulMbIt2+w8T7UI/r97ok5GqE4kGaeA==}
cpu: [x64]
os: [win32]
lefthook@2.1.10:
resolution: {integrity: sha512-K7mM4WoqMwqfXYK11EHy+lSH1uW8XHni3Yn/bSqyerPkUPygGdf3xn18JoV5HyA06xuQL3ofGAOjG01QX9oJ4w==}
hasBin: true
light-my-request@6.6.0:
resolution: {integrity: sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A==}
@@ -27139,6 +27196,49 @@ snapshots:
leac@0.6.0: {}
lefthook-darwin-arm64@2.1.10:
optional: true
lefthook-darwin-x64@2.1.10:
optional: true
lefthook-freebsd-arm64@2.1.10:
optional: true
lefthook-freebsd-x64@2.1.10:
optional: true
lefthook-linux-arm64@2.1.10:
optional: true
lefthook-linux-x64@2.1.10:
optional: true
lefthook-openbsd-arm64@2.1.10:
optional: true
lefthook-openbsd-x64@2.1.10:
optional: true
lefthook-windows-arm64@2.1.10:
optional: true
lefthook-windows-x64@2.1.10:
optional: true
lefthook@2.1.10:
optionalDependencies:
lefthook-darwin-arm64: 2.1.10
lefthook-darwin-x64: 2.1.10
lefthook-freebsd-arm64: 2.1.10
lefthook-freebsd-x64: 2.1.10
lefthook-linux-arm64: 2.1.10
lefthook-linux-x64: 2.1.10
lefthook-openbsd-arm64: 2.1.10
lefthook-openbsd-x64: 2.1.10
lefthook-windows-arm64: 2.1.10
lefthook-windows-x64: 2.1.10
light-my-request@6.6.0:
dependencies:
cookie: 1.0.2