Skip to content

chore(lefthook): add CI-style path filtering to hooks#2211

Merged
wpfleger96 merged 1 commit into
mainfrom
duncan/lefthook-path-filter
Jul 21, 2026
Merged

chore(lefthook): add CI-style path filtering to hooks#2211
wpfleger96 merged 1 commit into
mainfrom
duncan/lefthook-path-filter

Conversation

@wpfleger96

@wpfleger96 wpfleger96 commented Jul 21, 2026

Copy link
Copy Markdown
Member

Every lefthook command ran unconditionally on every commit/push, regardless of which surface the change touched. This meant a rust-only push always ran flutter analyze, a mobile-only push always ran cargo test, etc.

Add glob: (and exclude: for desktop vs desktop-tauri) to each command so lefthook skips commands whose surface the push diff doesn't touch. The mechanism is lefthook's built-in push-range filtering (git diff --name-only HEAD @{push}) for pre-push and staged-file filtering for pre-commit — the same information CI's dorny/paths-filter changes job uses for PR diffs.

What changed

pre-commit:
  rust-fmt          → glob: ["crates/**", "examples/countdown-bot/**"]
  desktop-tauri-fmt → glob: ["desktop/src-tauri/**"]
  desktop-fix       → glob: ["desktop/**", "pnpm-lock.yaml"], exclude: ["desktop/src-tauri/**"]
  web-fix           → glob: ["web/**", "pnpm-lock.yaml"]
  mobile-fix        → glob: ["mobile/**"]

pre-push:
  branch-skew        → no glob (always runs)
  rust-tests         → glob: ["crates/**", "migrations/**", "schema/**", "Cargo.toml", ...]
  desktop-check      → glob: ["desktop/**", "pnpm-lock.yaml"], exclude: ["desktop/src-tauri/**"]
  desktop-test       → glob: ["desktop/**", "pnpm-lock.yaml"], exclude: ["desktop/src-tauri/**"]
  desktop-tauri-test → glob: ["desktop/src-tauri/**"] UNION [rust filter] (mirrors ci.yml:113)
  mobile-test        → glob: ["mobile/**"]

A header comment in lefthook.yml states that these globs mirror ci.yml's changes job filters and must be kept in sync.

Deliberate deviations from ci.yml

  1. Workflow-file path omitted — CI adds .github/workflows/ci.yml to its rust/mobile filters; a CI-config-only edit doesn't need a local test run.
  2. desktop-check/desktop-test don't union rust — CI's Desktop Core job triggers on rust OR desktop-rust, but those commands are pure TS (biome + node:test) with no Rust dependency. Triggering them on rust changes would be spurious locally.
  3. Deletion-only pushes don't trigger local hooks — lefthook 2.1.x drops deleted paths from push-file discovery (extractFiles existence check in repository.go). CI's dorny/paths-filter remains the gate for deletion-only surface changes. Deliberate: accepted, not worked around.

Semantics to note

lefthook pre-push diffs against the remote branch tip (HEAD @{push}), not the full PR history. This means a later unrelated push won't re-run an earlier surface's tests even if that surface has commits earlier in the branch. This is coherent — each surface was gated when it was pushed — but it differs from CI which diffs the whole PR against main.

Verification matrix (LEFTHOOK_VERBOSE=1)

Scenario Runs Skips
crates/buzz-core/src/lib.rs rust-tests, desktop-tauri-test desktop-check, desktop-test, mobile-test — all "no matching push files"
mobile/lib/main.dart mobile-test rust-tests, desktop-tauri-test, desktop-check, desktop-test — all "no matching push files"
desktop/src/App.ts desktop-check, desktop-test rust-tests, desktop-tauri-test, mobile-test — all "no matching push files"
README.md (any file) branch-skew everything else skipped

Skip message in each case: (skip) no matching push files

@wpfleger96
wpfleger96 requested a review from a team as a code owner July 21, 2026 06:24
Every lefthook command ran unconditionally on every commit/push,
regardless of which surface (rust/desktop/desktop-tauri/web/mobile)
the change actually touched — e.g. flutter analyze on a rust-only
push. Scope each command with glob (and exclude for desktop vs
desktop-tauri) so lefthook skips commands whose surface the diff
doesn't touch, using the same push-range/staged-file mechanism CI's
dorny/paths-filter changes job uses for PR diffs.

Globs mirror ci.yml's changes job filters; the header comment states
that parity explicitly. branch-skew keeps no glob and always runs.

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
@wpfleger96
wpfleger96 force-pushed the duncan/lefthook-path-filter branch from 12d9f3a to 3765669 Compare July 21, 2026 07:01
@wpfleger96
wpfleger96 merged commit 692c56d into main Jul 21, 2026
24 checks passed
@wpfleger96
wpfleger96 deleted the duncan/lefthook-path-filter branch July 21, 2026 07:15
tlongwell-block pushed a commit that referenced this pull request Jul 21, 2026
* origin/main:
  fix(desktop): keep project branches after reload (#2214)
  fix(git): make project branch workflows reliable (#2213)
  feat(desktop): manage project branches (#2212)
  fix(acp): honor relay rate limits and pace resubscribes on bad links (#2199)
  chore(lefthook): add CI-style path filtering to hooks (#2211)
  feat(cli): manage repository protection rules (#2193)
  feat(cli): filter archived instances from --template roster resolution (#2207)
  chore(release): release Buzz Desktop version 0.4.21 (#2209)
  fix(desktop): clarify data deletion action (#2208)
  feat: brand authentication complete page (#2192)
  fix(buzz-acp,buzz-agent): surface stall duration and fate (#2204)
  fix(desktop): resolve activity feed showing channel UUID instead of message content (#2201)
  feat(cli): add agents archive/unarchive/archived subcommands (#2173)
  chore(acp): strip stale finding-number references from comments (#2202)
  chore(release): release Buzz Mobile version 0.4.9 (#2200)
  Simplify first-community onboarding choices (UI only) (#2194)
  fix(mobile): sanitize Android image uploads (#2188)
  fix(cli): paginate channel directory queries (#2181)

Semantic resolutions in crates/buzz-acp/src/lib.rs:
- kept lazy_pool startup + pool_ready select guard from this branch,
  adopted main's comment cleanup (#2202)
- dropped this branch's duplicated steer_renewal_tests module: #2204 moved
  those tests to queue.rs on main

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant