From 0be17d791d9345e4fcc413f46c86b49e348e24ce Mon Sep 17 00:00:00 2001 From: "Tara \\X/ Void" <1711810+taraxvoid@users.noreply.github.com> Date: Fri, 2 Oct 2026 13:39:47 -0500 Subject: [PATCH 1/3] fix(lefthook): pre-commit unit step honors test:unit:precommit (#110) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Found while rolling v0.10.0 into queeromaha: a site's own `lefthook.yml` cannot override a command defined by the remote. Lefthook merges `lefthook.yml`, then remotes, then `lefthook-local.yml`, so the remote's `unit` command won and ran tests that need a built `dist/` (`lefthook dump` showed the remote's `run`). The README I wrote said local config overrides by name; that was wrong. Fix: the shared `unit` step runs `test:unit:precommit` if the site's `package.json` defines it, otherwise `test:unit` as before. Sites that exclude dist-dependent tests pre-commit (queeromaha, soundry, synthomaha) define that script. README corrected: a site `lefthook.yml` can add commands (e.g. synthomaha's image compression), not override. Verified in throwaway repos consuming this branch as the remote: with the script defined the pre-commit runs it, without it falls back to `test:unit`. Added a unit test for the fallback text. Needs a patch release (0.10.1) before the sites can pin it. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Sonnet 5.5 --- README.md | 12 ++++++------ lefthook/site.yml | 15 ++++++++++++--- test/lefthook-site.test.ts | 6 ++++++ 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index a903ba4..9f63a60 100644 --- a/README.md +++ b/README.md @@ -204,14 +204,14 @@ remotes: configs: - lefthook/site.yml -# Site-specific differences override the remote by name, e.g. skip tests that -# need a built dist/ before commit: -pre-commit: - commands: - unit: - run: bun run test:unit -- --exclude 'test/build.test.ts' ``` +Lefthook merges `lefthook.yml`, then remotes, then `lefthook-local.yml`, so a +site's own `lefthook.yml` can add commands (for example image compression) but +cannot override ones defined here. Differences go through `package.json` +scripts: define `test:unit:precommit` (for example excluding tests that need a +built `dist/`) and the pre-commit unit step runs it instead of `test:unit`. + Install the binary through mise (`lefthook = ""` in `mise.toml`) and set `"prepare": "lefthook install"` so `bun install` wires the hooks. `ref` cannot be a commit SHA; pin a release tag. diff --git a/lefthook/site.yml b/lefthook/site.yml index 1c8acde..b1a9c94 100644 --- a/lefthook/site.yml +++ b/lefthook/site.yml @@ -9,8 +9,10 @@ # configs: # - lefthook/site.yml # -# Anything a site needs to do differently (extra steps, test:unit excludes) -# goes in its own lefthook.yml: local config overrides the remote by name. +# Lefthook merges lefthook.yml < remotes < lefthook-local.yml, so a site's own +# lefthook.yml can ADD commands (e.g. image compression) but cannot override +# one defined here. Differences go through package.json scripts instead, e.g. +# `test:unit:precommit` replaces `test:unit` for the pre-commit unit step. pre-commit: skip: [merge, rebase] @@ -35,7 +37,14 @@ pre-commit: run: bun run --if-present check unit: priority: 3 - run: bun run --if-present test:unit + # A site that can't run its whole suite pre-commit (e.g. tests that need + # a built dist/) defines `test:unit:precommit`; otherwise test:unit runs. + run: | + if grep -q '"test:unit:precommit"' package.json; then + bun run test:unit:precommit + else + bun run --if-present test:unit + fi licenses: priority: 3 glob: "{package.json,bun.lock,pnpm-lock.yaml}" diff --git a/test/lefthook-site.test.ts b/test/lefthook-site.test.ts index 8868c8c..574c31d 100644 --- a/test/lefthook-site.test.ts +++ b/test/lefthook-site.test.ts @@ -25,4 +25,10 @@ describe('lefthook/site.yml', () => { expect(text).toContain(`\n${hook}`) } }) + test('pre-commit unit step prefers test:unit:precommit when a site defines it', async () => { + const text = await Bun.file(config).text() + expect(text).toContain('grep -q \'"test:unit:precommit"\' package.json') + expect(text).toContain('bun run test:unit:precommit') + expect(text).toContain('bun run --if-present test:unit') + }) }) From 9869f82e6eb23352a1824a033ea24ab4f82e75df Mon Sep 17 00:00:00 2001 From: "Tara \\X/ Void" <1711810+taraxvoid@users.noreply.github.com> Date: Fri, 2 Oct 2026 13:39:56 -0500 Subject: [PATCH 2/3] fix: scope minimumReleaseAgeExcludes under [install] (#111) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `minimumReleaseAgeExcludes` sat below the `[install.security]` header in `bunfig.toml`, so TOML scoped it to that table instead of `[install]` and the exclusions never applied. Found because the same layout (from the bunfig baseline PRs) made `bun add @taraxvoid/voidflow@0.10.0` fail in queeromaha with `blocked by minimum-release-age`, and Netlify's install failed identically; moving the key under `[install]` made it resolve. Moves the key up (and keeps a blank line before `[install.security]`). Other repos from the baseline PRs likely share the layout. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Sonnet 5.5 --- bunfig.toml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/bunfig.toml b/bunfig.toml index 1486b07..4d9c545 100644 --- a/bunfig.toml +++ b/bunfig.toml @@ -1,9 +1,8 @@ [install] minimumReleaseAge = 259200 # 3 days -[install.security] -scanner = "@socketsecurity/bun-security-scanner" - # Packages that bypass the gate minimumReleaseAgeExcludes = ["@playwright/test", "playwright", "playwright-core"] +[install.security] +scanner = "@socketsecurity/bun-security-scanner" From c7296c79e40c6b6585d0c8b3e3d2237d4bf9e2c1 Mon Sep 17 00:00:00 2001 From: "ravenflight-releases[bot]" <330165707+ravenflight-releases[bot]@users.noreply.github.com> Date: Fri, 2 Oct 2026 13:43:27 -0500 Subject: [PATCH 3/3] chore(main): release 0.11.0 (#106) :robot: I have created a release *beep* *boop* --- ## [0.11.0](https://github.com/taraxvoid/voidflow/compare/v0.10.0...v0.11.0) (2026-10-02) ### Features * branch-based release channels (next prerelease, maintenance branches, floating v0) ([#105](https://github.com/taraxvoid/voidflow/issues/105)) ([978f1db](https://github.com/taraxvoid/voidflow/commit/978f1db11183a3c61b94faa4724f2585caefaccf)) ### Bug Fixes * **lefthook:** pre-commit unit step honors test:unit:precommit ([#110](https://github.com/taraxvoid/voidflow/issues/110)) ([0be17d7](https://github.com/taraxvoid/voidflow/commit/0be17d791d9345e4fcc413f46c86b49e348e24ce)) * scope minimumReleaseAgeExcludes under [install] ([#111](https://github.com/taraxvoid/voidflow/issues/111)) ([9869f82](https://github.com/taraxvoid/voidflow/commit/9869f82e6eb23352a1824a033ea24ab4f82e75df)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: ravenflight-releases[bot] <330165707+ravenflight-releases[bot]@users.noreply.github.com> --- .release-please/main-manifest.json | 2 +- CHANGELOG.md | 13 +++++++++++++ jsr.json | 2 +- package.json | 2 +- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/.release-please/main-manifest.json b/.release-please/main-manifest.json index 7d9b009..78e7f27 100644 --- a/.release-please/main-manifest.json +++ b/.release-please/main-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.10.0" + ".": "0.11.0" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f24b1c..f26c4fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,19 @@ All notable changes to this project are documented here, generated by [release-please](https://github.com/googleapis/release-please) from [Conventional Commits](https://www.conventionalcommits.org). +## [0.11.0](https://github.com/taraxvoid/voidflow/compare/v0.10.0...v0.11.0) (2026-10-02) + + +### Features + +* branch-based release channels (next prerelease, maintenance branches, floating v0) ([#105](https://github.com/taraxvoid/voidflow/issues/105)) ([978f1db](https://github.com/taraxvoid/voidflow/commit/978f1db11183a3c61b94faa4724f2585caefaccf)) + + +### Bug Fixes + +* **lefthook:** pre-commit unit step honors test:unit:precommit ([#110](https://github.com/taraxvoid/voidflow/issues/110)) ([0be17d7](https://github.com/taraxvoid/voidflow/commit/0be17d791d9345e4fcc413f46c86b49e348e24ce)) +* scope minimumReleaseAgeExcludes under [install] ([#111](https://github.com/taraxvoid/voidflow/issues/111)) ([9869f82](https://github.com/taraxvoid/voidflow/commit/9869f82e6eb23352a1824a033ea24ab4f82e75df)) + ## [0.10.0](https://github.com/taraxvoid/voidflow/compare/v0.9.0...v0.10.0) (2026-10-02) diff --git a/jsr.json b/jsr.json index 431e3ba..39bbbe5 100644 --- a/jsr.json +++ b/jsr.json @@ -1,6 +1,6 @@ { "name": "@taraxvoid/voidflow", - "version": "0.10.0", + "version": "0.11.0", "license": "MIT", "exports": { "./playwright": "./playwright/index.mjs" diff --git a/package.json b/package.json index 204a55d..1c157f1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@taraxvoid/voidflow", - "version": "0.10.0", + "version": "0.11.0", "description": "Shared workflows, actions and tooling for @taraxvoid sites", "license": "MIT", "keywords": [