From 677fc28ba5278d35658b7e386a439eb8f620ac76 Mon Sep 17 00:00:00 2001 From: "matthew a." <14793093+shottah@users.noreply.github.com> Date: Mon, 18 May 2026 14:47:28 -0400 Subject: [PATCH] chore: replace husky with lefthook Switch the git hook manager from husky to lefthook to fix the two-commit-required workflow described in #691. Husky's pre-commit ran `yarn fmt --staged`, which formatted files in the working tree but did not re-add them to the git index, so contributors had to make a second commit to include the formatting fixes. Lefthook's `stage_fixed: true` option re-stages files that hooks modify, so a single commit now lands the formatted output. Per the Biome git-hooks recipe, the pre-commit also upgrades from `format --write` to `check --write`, which runs lint + format in one pass over staged files. The pre-push hook is preserved verbatim (prereleasecheck.sh). Closes #691 --- .husky/pre-commit | 6 --- .husky/pre-push | 5 -- lefthook.yml | 13 +++++ package.json | 4 +- yarn.lock | 122 ++++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 127 insertions(+), 23 deletions(-) delete mode 100755 .husky/pre-commit delete mode 100755 .husky/pre-push create mode 100644 lefthook.yml diff --git a/.husky/pre-commit b/.husky/pre-commit deleted file mode 100755 index e33ccc7ea9..0000000000 --- a/.husky/pre-commit +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" - -yarn fmt --staged --no-errors-on-unmatched - -bash scripts/hooks/prereleasecheck.sh diff --git a/.husky/pre-push b/.husky/pre-push deleted file mode 100755 index 5eb282e368..0000000000 --- a/.husky/pre-push +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" - - -bash scripts/hooks/prereleasecheck.sh diff --git a/lefthook.yml b/lefthook.yml new file mode 100644 index 0000000000..806c8ec877 --- /dev/null +++ b/lefthook.yml @@ -0,0 +1,13 @@ +pre-commit: + commands: + biome-check: + glob: "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}" + run: yarn biome check --write --no-errors-on-unmatched --files-ignore-unknown=true --colors=off {staged_files} + stage_fixed: true + prerelease-check: + run: bash scripts/hooks/prereleasecheck.sh + +pre-push: + commands: + prerelease-check: + run: bash scripts/hooks/prereleasecheck.sh diff --git a/package.json b/package.json index 4981290282..c501170cd1 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "cs": "yarn changeset", "check-licenses": "yarn licenses list --prod | grep '\\(─ GPL\\|─ (GPL-[1-9]\\.[0-9]\\+ OR GPL-[1-9]\\.[0-9]\\+)\\)' && echo 'Found GPL license(s). Use 'yarn licenses list --prod' to look up the offending package' || echo 'No GPL licenses found'", "report-coverage": "yarn workspaces foreach -piv --all run test-coverage", - "postinstall": "husky install", + "postinstall": "lefthook install", "release": "yarn clean && yarn build && yarn workspace @celo/celocli run prepack && yarn cs publish", "version-then-update-files": "yarn changeset version && yarn install --no-immutable && yarn build && yarn docs", "celocli": "yarn workspace @celo/celocli run --silent celocli" @@ -43,8 +43,8 @@ "@changesets/changelog-github": "^0.5.1", "@types/node": "24.0.0", "colors": "1.4.0", - "husky": "^8.0.0", "jest": "^29.7.0", + "lefthook": "^2.1.6", "rimraf": "^4.4.1", "ts-jest": "^29.1.5", "ts-node": "^10.9.1", diff --git a/yarn.lock b/yarn.lock index 35b034e68e..0db17f2dc3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8192,8 +8192,8 @@ __metadata: "@changesets/cli": "npm:^2.29.5" "@types/node": "npm:24.0.0" colors: "npm:1.4.0" - husky: "npm:^8.0.0" jest: "npm:^29.7.0" + lefthook: "npm:^2.1.6" rimraf: "npm:^4.4.1" ts-jest: "npm:^29.1.5" ts-node: "npm:^10.9.1" @@ -11136,15 +11136,6 @@ __metadata: languageName: node linkType: hard -"husky@npm:^8.0.0": - version: 8.0.3 - resolution: "husky@npm:8.0.3" - bin: - husky: lib/bin.js - checksum: b754cf70fdc97c3b60fec5b80056b9c11436464953b1691bf2b5dcf0081fb6685d2c5f47abb8b2b1c49f504aabea5321fdd6496f8b755d9f6e7525a493406abb - languageName: node - linkType: hard - "hyperlinker@npm:^1.0.0": version: 1.0.0 resolution: "hyperlinker@npm:1.0.0" @@ -12652,6 +12643,117 @@ __metadata: languageName: node linkType: hard +"lefthook-darwin-arm64@npm:2.1.6": + version: 2.1.6 + resolution: "lefthook-darwin-arm64@npm:2.1.6" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"lefthook-darwin-x64@npm:2.1.6": + version: 2.1.6 + resolution: "lefthook-darwin-x64@npm:2.1.6" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"lefthook-freebsd-arm64@npm:2.1.6": + version: 2.1.6 + resolution: "lefthook-freebsd-arm64@npm:2.1.6" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"lefthook-freebsd-x64@npm:2.1.6": + version: 2.1.6 + resolution: "lefthook-freebsd-x64@npm:2.1.6" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"lefthook-linux-arm64@npm:2.1.6": + version: 2.1.6 + resolution: "lefthook-linux-arm64@npm:2.1.6" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"lefthook-linux-x64@npm:2.1.6": + version: 2.1.6 + resolution: "lefthook-linux-x64@npm:2.1.6" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"lefthook-openbsd-arm64@npm:2.1.6": + version: 2.1.6 + resolution: "lefthook-openbsd-arm64@npm:2.1.6" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + +"lefthook-openbsd-x64@npm:2.1.6": + version: 2.1.6 + resolution: "lefthook-openbsd-x64@npm:2.1.6" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"lefthook-windows-arm64@npm:2.1.6": + version: 2.1.6 + resolution: "lefthook-windows-arm64@npm:2.1.6" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"lefthook-windows-x64@npm:2.1.6": + version: 2.1.6 + resolution: "lefthook-windows-x64@npm:2.1.6" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"lefthook@npm:^2.1.6": + version: 2.1.6 + resolution: "lefthook@npm:2.1.6" + dependencies: + lefthook-darwin-arm64: "npm:2.1.6" + lefthook-darwin-x64: "npm:2.1.6" + lefthook-freebsd-arm64: "npm:2.1.6" + lefthook-freebsd-x64: "npm:2.1.6" + lefthook-linux-arm64: "npm:2.1.6" + lefthook-linux-x64: "npm:2.1.6" + lefthook-openbsd-arm64: "npm:2.1.6" + lefthook-openbsd-x64: "npm:2.1.6" + lefthook-windows-arm64: "npm:2.1.6" + lefthook-windows-x64: "npm:2.1.6" + dependenciesMeta: + lefthook-darwin-arm64: + optional: true + lefthook-darwin-x64: + optional: true + lefthook-freebsd-arm64: + optional: true + lefthook-freebsd-x64: + optional: true + lefthook-linux-arm64: + optional: true + lefthook-linux-x64: + optional: true + lefthook-openbsd-arm64: + optional: true + lefthook-openbsd-x64: + optional: true + lefthook-windows-arm64: + optional: true + lefthook-windows-x64: + optional: true + bin: + lefthook: bin/index.js + checksum: b2a0d1121b4212ff5f17dbae8baf375ff794a1597c5a661137164869d716510793c0a377f97aa9d84970d28867efd3f65485ff7cab4cfb799c439993e267b6d1 + languageName: node + linkType: hard + "level-concat-iterator@npm:^3.0.0": version: 3.1.0 resolution: "level-concat-iterator@npm:3.1.0"