From 9b0e2b7942640d0d8494b0dbe2b61e65d2c21eac Mon Sep 17 00:00:00 2001 From: Tara X V01D <1711810+taraxvoid@users.noreply.github.com> Date: Fri, 2 Oct 2026 13:20:22 -0500 Subject: [PATCH 01/11] chore: start next at the released 0.10.0 0.10.0 shipped on the pre-channel workflow, so the back-merge job never ran and next-manifest.json still said 0.9.0. Without this the first prerelease would be computed from 0.9.0. Co-Authored-By: Claude Sonnet 5.5 --- .release-please/next-manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.release-please/next-manifest.json b/.release-please/next-manifest.json index 76d5538..7d9b009 100644 --- a/.release-please/next-manifest.json +++ b/.release-please/next-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.9.0" + ".": "0.10.0" } From 1c74e3afe1c1984c9478a794ff942e788951a7b9 Mon Sep 17 00:00:00 2001 From: "Tara \\X/ Void" <1711810+taraxvoid@users.noreply.github.com> Date: Fri, 2 Oct 2026 13:25:30 -0500 Subject: [PATCH 02/11] fix(docs): prerelease tags carry the -next suffix (#109) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit First feature PR through the next channel: a one-line README correction (prereleases tag vX.Y.Z-next[.N]). Merging it should make release-please open a prerelease PR on next. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Sonnet 5.5 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a903ba4..0b89f2f 100644 --- a/README.md +++ b/README.md @@ -287,7 +287,7 @@ Semver, released with [release-please](https://github.com/googleapis/release-ple | maintenance | `release/N.x` | `0.9.4` | `release-N.x` | release-please keeps a standing release PR open on each channel's branch, updated as commits land. -Merging it bumps `package.json` (and [`CHANGELOG.md`](CHANGELOG.md) on stable), tags `vX.Y.Z`, +Merging it bumps `package.json` (and [`CHANGELOG.md`](CHANGELOG.md) on stable), tags `vX.Y.Z` (`vX.Y.Z-next[.N]` on `next`), creates the GitHub release and publishes to npm and JSR under the channel's dist-tag. The PR is opened with the org's release-bot GitHub App token (`RELEASE_BOT_CLIENT_ID` / `RELEASE_BOT_APP_PRIVATE_KEY`) so CI runs on it. From ccf7341cf580e911933cc55561749dbc61384e05 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:26:56 -0500 Subject: [PATCH 03/11] chore(next): release 0.11.0-next (#108) :robot: I have created a release *beep* *boop* --- ## [0.11.0-next](https://github.com/taraxvoid/voidflow/compare/v0.10.0...v0.11.0-next) (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 * **docs:** prerelease tags carry the -next suffix ([#109](https://github.com/taraxvoid/voidflow/issues/109)) ([1c74e3a](https://github.com/taraxvoid/voidflow/commit/1c74e3afe1c1984c9478a794ff942e788951a7b9)) --- 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/next-manifest.json | 2 +- jsr.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.release-please/next-manifest.json b/.release-please/next-manifest.json index 7d9b009..439b3cc 100644 --- a/.release-please/next-manifest.json +++ b/.release-please/next-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.10.0" + ".": "0.11.0-next" } diff --git a/jsr.json b/jsr.json index 431e3ba..465881d 100644 --- a/jsr.json +++ b/jsr.json @@ -1,6 +1,6 @@ { "name": "@taraxvoid/voidflow", - "version": "0.10.0", + "version": "0.11.0-next", "license": "MIT", "exports": { "./playwright": "./playwright/index.mjs" diff --git a/package.json b/package.json index 204a55d..eb6430d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@taraxvoid/voidflow", - "version": "0.10.0", + "version": "0.11.0-next", "description": "Shared workflows, actions and tooling for @taraxvoid sites", "license": "MIT", "keywords": [ From 6a2979ce1313c8944a67b6c66522954781348514 Mon Sep 17 00:00:00 2001 From: "ravenflight-releases[bot]" <330165707+ravenflight-releases[bot]@users.noreply.github.com> Date: Tue, 6 Oct 2026 12:59:18 -0500 Subject: [PATCH 04/11] chore: back-merge v0.12.0 into next (#123) Brings the v0.12.0 version bump and changelog from main into next. Merge with a merge commit, not a squash, so the branches share history. --------- Co-authored-by: Tara X V01D <1711810+taraxvoid@users.noreply.github.com> Co-authored-by: Claude Sonnet 5.5 Co-authored-by: ravenflight-releases[bot] <330165707+ravenflight-releases[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .github/workflows/resolve-env.yml | 37 ++++++++++++---- .release-please/main-manifest.json | 2 +- .release-please/next-manifest.json | 2 +- CHANGELOG.md | 12 +++++ README.md | 21 ++++++--- jsr.json | 2 +- lefthook/site.yml | 39 ++++++++++------ package.json | 2 +- test/branch-env-map.test.ts | 71 ++++++++++++++++++++++++++++++ test/lefthook-site.test.ts | 16 ++++++- 10 files changed, 170 insertions(+), 34 deletions(-) create mode 100644 test/branch-env-map.test.ts diff --git a/.github/workflows/resolve-env.yml b/.github/workflows/resolve-env.yml index 7d20fc3..49af8e6 100644 --- a/.github/workflows/resolve-env.yml +++ b/.github/workflows/resolve-env.yml @@ -1,8 +1,9 @@ name: Resolve env # Resolves the deploy environment (dev/staging/prod) for the current branch -# via the branch-env-map action, exposing it as a job output so callers can -# reference it in a downstream job's `name:` (e.g. `Deploy [${{ needs.resolve-env.outputs.env }}]`). +# using the same mapping as the branch-env-map action, exposing it as a job +# output so callers can reference it in a downstream job's `name:` (e.g. +# `Deploy [${{ needs.resolve-env.outputs.env }}]`). # Job names may use the `needs` context, but not composite action outputs # directly, so this indirection is what makes that possible. @@ -34,10 +35,30 @@ jobs: outputs: env: ${{ steps.map.outputs.env }} steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false + # Same mapping as actions/branch-env-map (a test keeps them identical). + # Inlined because a reusable workflow can't reach `./actions/...` in its + # own repo: checkout gives it the caller's tree, not voidflow's. - id: map - uses: ./actions/branch-env-map - with: - single-environment: ${{ inputs.single-environment }} + shell: bash + env: + REF_NAME: ${{ github.ref_name }} + EVENT_NAME: ${{ github.event_name }} + SINGLE: ${{ inputs.single-environment }} + run: | + if [[ "$SINGLE" == "true" ]]; then + if [[ "$EVENT_NAME" == pull_request* ]]; then + echo "env=preview" >> "$GITHUB_OUTPUT" + elif [[ "$REF_NAME" == main ]]; then + echo "env=prod" >> "$GITHUB_OUTPUT" + else + echo "::error::Refusing to deploy unknown ref: $REF_NAME (expected main or a pull request)" >&2 + exit 1 + fi + exit 0 + fi + case "$REF_NAME" in + main) echo "env=dev" >> "$GITHUB_OUTPUT" ;; + next) echo "env=staging" >> "$GITHUB_OUTPUT" ;; + live) echo "env=prod" >> "$GITHUB_OUTPUT" ;; + *) echo "::error::Refusing to deploy unknown branch: $REF_NAME (expected main, next, or live)" >&2; exit 1 ;; + esac diff --git a/.release-please/main-manifest.json b/.release-please/main-manifest.json index ddfa3e3..8032c17 100644 --- a/.release-please/main-manifest.json +++ b/.release-please/main-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.11.1" + ".": "0.12.0" } diff --git a/.release-please/next-manifest.json b/.release-please/next-manifest.json index ddfa3e3..8032c17 100644 --- a/.release-please/next-manifest.json +++ b/.release-please/next-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.11.1" + ".": "0.12.0" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 76b724b..f48bbfc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,18 @@ 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.12.0](https://github.com/taraxvoid/voidflow/compare/v0.11.1...v0.12.0) (2026-10-06) + + +### Features + +* **lefthook:** pick bun or pnpm from the lockfile in the shared site hooks ([#119](https://github.com/taraxvoid/voidflow/issues/119)) ([fc33ffd](https://github.com/taraxvoid/voidflow/commit/fc33ffd2c3314ed8e4a3be6a2d006789b832d1fd)) + + +### Bug Fixes + +* **resolve-env:** inline the env mapping so the reusable workflow works cross-repo ([#118](https://github.com/taraxvoid/voidflow/issues/118)) ([cc14d77](https://github.com/taraxvoid/voidflow/commit/cc14d77befdb4532e8ba448d37b0f4087ca99e1d)) + ## [0.11.1](https://github.com/taraxvoid/voidflow/compare/v0.11.0...v0.11.1) (2026-10-02) diff --git a/README.md b/README.md index a18df2b..b947dde 100644 --- a/README.md +++ b/README.md @@ -107,10 +107,11 @@ static directory on a free port and runs [Unlighthouse](https://unlighthouse.dev/) against it, reusing Playwright's Chromium. It exits non-zero if a category budget in the site's config fails. -In the site's `package.json` (pin the tag): +Add `@taraxvoid/voidflow` as a devDependency and call the bin from the site's +`package.json`: ```json -"test:e2e:lighthouse": "bun run build && bunx --package @taraxvoid/voidflow@0.8.1 unlighthouse-runner --dir dist" +"test:e2e:lighthouse": "bun run build && unlighthouse-runner --dir dist" ``` Options: `--dir` (default `dist`, use `dist/client` for Cloudflare adapter @@ -126,12 +127,20 @@ change. Sites implement that script with the shared check, which runs `license-checker` in the site's repo root and fails on GPL, AGPL, SSPL and similar copyleft licenses (LGPL is allowed). -In the site's `package.json` (pin the tag): +With `@taraxvoid/voidflow` as a devDependency, call the bin from the site's +`package.json`: ```json -"check:licenses": "bunx --package @taraxvoid/voidflow@ check-licenses" +"check:licenses": "check-licenses" ``` +Don't use `bunx --package @taraxvoid/voidflow@ ...` for these. It +duplicates the version pin outside the lockfile and Renovate, and `bunx` reads +the global `~/.bunfig.toml` rather than the site's, so a global +`minimumReleaseAge` that doesn't exclude `@taraxvoid/voidflow` blocks it +locally (including in the pre-commit hook) for 3 days after every release. +The devDependency's bins are installed under the site's own `bunfig.toml`. + ### Playwright preview config Shared `playwright.config` for Astro sites that run e2e against @@ -182,12 +191,12 @@ remote's `ref` tag, and tool versions in a `justfile` (annotate the line above with `# renovate: datasource=... depName=...`). Requires the Renovate GitHub App on the repo. -||||||| 4041a59 ## Git hooks (lefthook) [`lefthook/site.yml`](lefthook/site.yml) is the shared hook set for the site stack, consumed as a lefthook remote. It calls the site's own `package.json` -scripts (`bun run --if-present`, so a missing script is skipped): +scripts (` run --if-present`, so a missing script is skipped; `` is pnpm +when the repo has a `pnpm-lock.yaml`, bun otherwise): - `pre-commit`: dependency guard, `format` (formatted files are re-staged), `lint:actions`, `check`, `test:unit`, and `check:licenses` / `audit` when the diff --git a/jsr.json b/jsr.json index 085437a..336260e 100644 --- a/jsr.json +++ b/jsr.json @@ -1,6 +1,6 @@ { "name": "@taraxvoid/voidflow", - "version": "0.11.1", + "version": "0.12.0", "license": "MIT", "exports": { "./playwright": "./playwright/index.mjs" diff --git a/lefthook/site.yml b/lefthook/site.yml index b1a9c94..47dc8e6 100644 --- a/lefthook/site.yml +++ b/lefthook/site.yml @@ -1,11 +1,12 @@ -# Shared git hooks for the Astro/bun site stack. Sites pull this in as a -# lefthook remote and call their own package.json scripts, so a script a site -# does not define is skipped (`bun run --if-present`). +# Shared git hooks for the Astro site stack (bun, or pnpm when the repo has a +# pnpm-lock.yaml). Sites pull this in as a lefthook remote and call their own +# package.json scripts, so a script a site does not define is skipped +# (` run --if-present`). # # # lefthook.yml in the site # remotes: # - git_url: https://github.com/taraxvoid/voidflow -# ref: # pin; bump deliberately +# ref: # a tag or branch (not a SHA); bump deliberately # configs: # - lefthook/site.yml # @@ -14,6 +15,10 @@ # one defined here. Differences go through package.json scripts instead, e.g. # `test:unit:precommit` replaces `test:unit` for the pre-commit unit step. +templates: + # Package manager: pnpm when the repo is a pnpm project, bun otherwise. + pm: "$(if [ -f pnpm-lock.yaml ]; then echo pnpm; else echo bun; fi)" + pre-commit: skip: [merge, rebase] commands: @@ -22,39 +27,45 @@ pre-commit: run: | if [ ! -d node_modules ]; then echo "pre-commit: 'node_modules' is missing, dependencies aren't installed." - echo " Run 'bun install' before committing, then commit again." + echo " Run '{pm} install' before committing, then commit again." exit 1 fi format: priority: 2 - run: bun run --if-present format + run: "{pm} run --if-present format" stage_fixed: true lint-actions: priority: 3 - run: bun run --if-present lint:actions + run: "{pm} run --if-present lint:actions" typecheck: priority: 3 - run: bun run --if-present check + run: "{pm} run --if-present check" unit: priority: 3 # 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 + {pm} run test:unit:precommit else - bun run --if-present test:unit + {pm} run --if-present test:unit fi licenses: priority: 3 glob: "{package.json,bun.lock,pnpm-lock.yaml}" - run: bun run --if-present check:licenses + run: "{pm} run --if-present check:licenses" audit: # Local only: hits a remote vulnerability database and can hang offline, # so it runs when dependencies changed and fails closed. priority: 3 glob: "{package.json,bun.lock,pnpm-lock.yaml}" - run: bun run --if-present audit + # Checked by hand: under bun, `--if-present` falls through to + # the system `audit` binary (macOS /usr/sbin/audit) when the site has no + # audit script, and that exits non-zero. + run: | + if grep -q '"audit"' package.json; then + {pm} run audit + fi commit-msg: commands: @@ -109,8 +120,8 @@ pre-push: if [ ! -d node_modules ]; then echo "pre-push: 'node_modules' is missing, dependencies aren't installed." - echo " Run 'bun install' before pushing, then push again." + echo " Run '{pm} install' before pushing, then push again." exit 1 fi - bun run --if-present test:push + {pm} run --if-present test:push diff --git a/package.json b/package.json index be4a64d..d9c4048 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@taraxvoid/voidflow", - "version": "0.11.1", + "version": "0.12.0", "description": "Shared workflows, actions and tooling for @taraxvoid sites", "license": "MIT", "keywords": [ diff --git a/test/branch-env-map.test.ts b/test/branch-env-map.test.ts new file mode 100644 index 0000000..6f0fa7a --- /dev/null +++ b/test/branch-env-map.test.ts @@ -0,0 +1,71 @@ +import { describe, expect, test } from 'bun:test' +import { mkdtempSync, readFileSync } from 'node:fs' +import { tmpdir } from 'node:os' +import { join } from 'node:path' + +const read = (p: string) => readFileSync(new URL(`../${p}`, import.meta.url), 'utf8') + +const actionScript: string = Bun.YAML.parse(read('actions/branch-env-map/action.yml')).runs.steps.find( + (s: any) => s.id === 'map', +).run +const workflowScript: string = Bun.YAML.parse(read('.github/workflows/resolve-env.yml')).jobs[ + 'resolve-env' +].steps.find((s: any) => s.id === 'map').run + +async function map(script: string, ref: string, event: string, single: boolean) { + const out = join(mkdtempSync(join(tmpdir(), 'voidflow-env-')), 'out') + await Bun.write(out, '') + const proc = Bun.spawn(['bash', '-c', script], { + env: { + PATH: process.env.PATH, + REF_NAME: ref, + EVENT_NAME: event, + SINGLE: String(single), + GITHUB_OUTPUT: out, + }, + stdout: 'pipe', + stderr: 'pipe', + }) + const code = await proc.exited + return { code, env: readFileSync(out, 'utf8').trim() } +} + +describe('resolve-env.yml carries the same mapping as branch-env-map', () => { + test('scripts are identical (no drift)', () => { + expect(workflowScript).toBe(actionScript) + }) + + test('resolve-env.yml has no `uses` steps (a local ./actions path or checkout cannot work cross-repo)', () => { + const steps = Bun.YAML.parse(read('.github/workflows/resolve-env.yml')).jobs['resolve-env'].steps + expect(steps.filter((s: any) => s.uses)).toEqual([]) + }) +}) + +describe.each([ + ['action', actionScript], + ['workflow', workflowScript], +])('%s script', (_name, script) => { + test.each([ + ['main', 'push', 'env=dev'], + ['next', 'push', 'env=staging'], + ['live', 'push', 'env=prod'], + ])('default mode: %s on %s', async (ref, event, expected) => { + expect(await map(script, ref, event, false)).toEqual({ code: 0, env: expected }) + }) + + test('default mode rejects unknown branches', async () => { + expect((await map(script, 'feature/x', 'push', false)).code).toBe(1) + }) + + test.each([ + ['main', 'push', 'env=prod'], + ['123/merge', 'pull_request', 'env=preview'], + ['feature/x', 'pull_request', 'env=preview'], + ])('single-environment: %s on %s', async (ref, event, expected) => { + expect(await map(script, ref, event, true)).toEqual({ code: 0, env: expected }) + }) + + test('single-environment rejects non-main pushes', async () => { + expect((await map(script, 'feature/x', 'push', true)).code).toBe(1) + }) +}) diff --git a/test/lefthook-site.test.ts b/test/lefthook-site.test.ts index 574c31d..f44c796 100644 --- a/test/lefthook-site.test.ts +++ b/test/lefthook-site.test.ts @@ -28,7 +28,19 @@ describe('lefthook/site.yml', () => { 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') + expect(text).toContain('{pm} run test:unit:precommit') + expect(text).toContain('{pm} run --if-present test:unit') + }) + + test('picks the package manager from the lockfile instead of hardcoding bun', async () => { + const text = await Bun.file(config).text() + expect(text).toContain('pnpm-lock.yaml ]; then echo pnpm; else echo bun') + expect(text).not.toMatch(/\bbun run\b/) + }) + + test('audit step only runs when the site defines an audit script', async () => { + const text = await Bun.file(config).text() + expect(text).toContain('grep -q \'"audit"\' package.json') + expect(text).not.toContain('--if-present audit') }) }) From 896ef20a33529a8944a3556b1bb2d3c0c3a5f219 Mon Sep 17 00:00:00 2001 From: "ravenflight-releases[bot]" <330165707+ravenflight-releases[bot]@users.noreply.github.com> Date: Wed, 7 Oct 2026 21:55:54 -0700 Subject: [PATCH 05/11] chore(next): release 0.13.0-next (#126) :robot: I have created a release *beep* *boop* --- ## [0.13.0-next](https://github.com/taraxvoid/voidflow/compare/v0.12.0...v0.13.0-next) (2026-10-06) ### Features * add conventional-commits release method ([#27](https://github.com/taraxvoid/voidflow/issues/27)) ([3cd5a86](https://github.com/taraxvoid/voidflow/commit/3cd5a86348e26dcb8bf2ccf6c22d2d01f0ff59be)) * 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)) * **branch-env-map:** single-environment mode (main to prod, PRs to preview) ([#91](https://github.com/taraxvoid/voidflow/issues/91)) ([bc50b96](https://github.com/taraxvoid/voidflow/commit/bc50b96e6760d4ae0cbe4d35f80c5142032ac2f8)) * **justfile:** add lint-only validation target ([b0fbc23](https://github.com/taraxvoid/voidflow/commit/b0fbc23983bbad3080b958667d2b68dcdcf244f8)) * manage branch rulesets as code ([#98](https://github.com/taraxvoid/voidflow/issues/98)) ([8f9c64b](https://github.com/taraxvoid/voidflow/commit/8f9c64b60b1fa2332d5811f0a2d8b629d9585c7d)) * **npm:** also publish unscoped voidflow mirror ([#69](https://github.com/taraxvoid/voidflow/issues/69)) ([8cebb32](https://github.com/taraxvoid/voidflow/commit/8cebb325381aba778c37af47e640eddea4a64a9c)) * **npm:** publish @taraxvoid/voidflow via trusted publishing ([#67](https://github.com/taraxvoid/voidflow/issues/67)) ([46b8ebd](https://github.com/taraxvoid/voidflow/commit/46b8ebdcce7347b4aa2c399dd0b7e72cb768391b)), closes [#65](https://github.com/taraxvoid/voidflow/issues/65) * **playwright:** add shared definePreviewConfig helper ([#64](https://github.com/taraxvoid/voidflow/issues/64)) ([#66](https://github.com/taraxvoid/voidflow/issues/66)) ([4901738](https://github.com/taraxvoid/voidflow/commit/49017386c9102eb3be41e32e2f206c1d0e391723)) * **release:** migrate to release-please ([#71](https://github.com/taraxvoid/voidflow/issues/71)) ([ecf3961](https://github.com/taraxvoid/voidflow/commit/ecf396155d397ad70767818cb2e3ff81b441e056)) * **resolve-env:** add reusable workflow to expose deploy env as a job output ([413cab4](https://github.com/taraxvoid/voidflow/commit/413cab4c7a9ee50c4edf12154af6f1c663a0c230)) * shared lefthook config for the site stack ([#103](https://github.com/taraxvoid/voidflow/issues/103)) ([98ea3cd](https://github.com/taraxvoid/voidflow/commit/98ea3cd279d7fdf87adf3bc50f309d27a39ddf74)) * shared Renovate preset ([#104](https://github.com/taraxvoid/voidflow/issues/104)) ([649d2b8](https://github.com/taraxvoid/voidflow/commit/649d2b8d0092a8d145bfc30f7b3c9161a77cf2c9)) * ship check-licenses as a package bin ([#97](https://github.com/taraxvoid/voidflow/issues/97)) ([4041a59](https://github.com/taraxvoid/voidflow/commit/4041a59dd9e73bd154f516c155c11ce94cbdd3cd)) * **site-ci.yml:** add GITLEAKS\_LICENSE secret since organizations require it ([5000ccc](https://github.com/taraxvoid/voidflow/commit/5000ccc42885c5890405cdcb2dee3d2b24d9767a)) * **site-ci.yml:** add optional GITLEAKS_LICENSE secret for gitleaks Organization plan ([4504d72](https://github.com/taraxvoid/voidflow/commit/4504d72057eaa7e6c250229723ed931af6403392)) * **site-ci.yml:** add support for Playwright installation without OS-level browser dependencies on self-hosted runners ([8fcac78](https://github.com/taraxvoid/voidflow/commit/8fcac78cecf192b6ebe338c04d7c6d292da6bb6b)) * **site-ci:** package-manager, e2e-extra-paths, build-env inputs; skip missing scripts ([#90](https://github.com/taraxvoid/voidflow/issues/90)) ([cd10551](https://github.com/taraxvoid/voidflow/commit/cd1055138e1072affb483f4161bb24efb274d341)) * **site-ci:** single-environment input for main-only sites ([#102](https://github.com/taraxvoid/voidflow/issues/102)) ([7be76fd](https://github.com/taraxvoid/voidflow/commit/7be76fd2a15cececaa6d734d5b01d9af6ac3a7f4)) * support JSR as npm alternative ([#78](https://github.com/taraxvoid/voidflow/issues/78)) ([75b68ce](https://github.com/taraxvoid/voidflow/commit/75b68ce6028cb8535fbfbfc079bf5376f822a0d6)) * **unlighthouse:** add shared Unlighthouse CI runner ([#63](https://github.com/taraxvoid/voidflow/issues/63)) ([b8a2798](https://github.com/taraxvoid/voidflow/commit/b8a27980c50dc20e9afb286382260ae05137d0e4)) ### Bug Fixes * also run validate on pushes ([#48](https://github.com/taraxvoid/voidflow/issues/48)) ([50ede94](https://github.com/taraxvoid/voidflow/commit/50ede945ed8426201c6751137ee0193aaac1e7e2)) * **ci.yml:** disable uv dependency cache since repo has no lockfile/requirements to key it on ([#37](https://github.com/taraxvoid/voidflow/issues/37)) ([82f81a4](https://github.com/taraxvoid/voidflow/commit/82f81a4d4a7084031d2d5f9d9265d7b0519bcbff)) * **ci:** make npm publish steps idempotent ([#87](https://github.com/taraxvoid/voidflow/issues/87)) ([5ad4f10](https://github.com/taraxvoid/voidflow/commit/5ad4f106764ea3eca3b7f61d43f36938593124a4)) * **ci:** resolve e2e base branch on push events ([#96](https://github.com/taraxvoid/voidflow/issues/96)) ([28e1465](https://github.com/taraxvoid/voidflow/commit/28e1465fe5fb67ffeb5c027e71c483647eb46aff)) * **cloudflare-deploy:** sanitize deployment-url output for multi-custom-domain deploys ([#49](https://github.com/taraxvoid/voidflow/issues/49)) ([d4a1eee](https://github.com/taraxvoid/voidflow/commit/d4a1eeed84b95b9d528892cc592535c72bd541ae)) * **cloudflare-deploy:** warn when --config bypasses the build's deploy redirect ([#85](https://github.com/taraxvoid/voidflow/issues/85)) ([9b09c1c](https://github.com/taraxvoid/voidflow/commit/9b09c1c1fe3a1b60755da7ebcac6eb6fac551a32)) * **docs:** prerelease tags carry the -next suffix ([#109](https://github.com/taraxvoid/voidflow/issues/109)) ([1c74e3a](https://github.com/taraxvoid/voidflow/commit/1c74e3afe1c1984c9478a794ff942e788951a7b9)) * improve Playwright cache invalidation ([#22](https://github.com/taraxvoid/voidflow/issues/22)) ([f8d863b](https://github.com/taraxvoid/voidflow/commit/f8d863b0bae156085054968309d44091f375f347)) * invalidate py cache ([b5106e4](https://github.com/taraxvoid/voidflow/commit/b5106e4880c9eb02942a41b2fc335bb10fc21300)) * just use github actions a la site-ci.yml instead of using just validate ([de40c3b](https://github.com/taraxvoid/voidflow/commit/de40c3bb955ff9973a7507c38f4a9781b3fbde46)) * just use github actions a la site-ci.yml instead of using just validate ([#68](https://github.com/taraxvoid/voidflow/issues/68)) ([2c90d50](https://github.com/taraxvoid/voidflow/commit/2c90d50679046a2f21c768f23d2c4f3e1e78c7e9)) * **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)) * move JSR publish above NPM to fix issue when npm dirties the tree ([6560f87](https://github.com/taraxvoid/voidflow/commit/6560f877b82eb9931155e757954de5ae5d165ff7)) * **release.yml:** pass GH_TOKEN through to just validate ([#28](https://github.com/taraxvoid/voidflow/issues/28)) ([fb573d7](https://github.com/taraxvoid/voidflow/commit/fb573d70771886a54bc3ea0290adeba3328956c8)) * **release.yml:** pin --tag-pattern for the auto-bump path ([#38](https://github.com/taraxvoid/voidflow/issues/38)) ([1ea0abb](https://github.com/taraxvoid/voidflow/commit/1ea0abb6b860bda5d3a28354e871621d4ce91c54)) * **release:** publish to npm with NPM_TOKEN until npm accepts immutable OIDC subjects ([#76](https://github.com/taraxvoid/voidflow/issues/76)) ([87a407b](https://github.com/taraxvoid/voidflow/commit/87a407b2d6b552e9b7e87d9c079a152478946634)) * **release:** split into PR-then-tag flow, main is PR-only ([#30](https://github.com/taraxvoid/voidflow/issues/30)) ([dea2940](https://github.com/taraxvoid/voidflow/commit/dea2940d58881a657135841b77cd2478f6e27086)) * **resolve-env:** use local action path to satisfy zizmor's unpinned-uses policy ([a3c210b](https://github.com/taraxvoid/voidflow/commit/a3c210ba9493f4f39f96d7b309c93136bb1b000c)) * scope minimumReleaseAgeExcludes under [install] ([#111](https://github.com/taraxvoid/voidflow/issues/111)) ([9869f82](https://github.com/taraxvoid/voidflow/commit/9869f82e6eb23352a1824a033ea24ab4f82e75df)) * **site-ci:** scan secrets with OSS gitleaks binary ([#95](https://github.com/taraxvoid/voidflow/issues/95)) ([1fb27ea](https://github.com/taraxvoid/voidflow/commit/1fb27eaccafe5ddc26859999730a53914e60d266)) * **tag-release.yml:** tolerate squash-merge's " (#NN)" suffix ([#33](https://github.com/taraxvoid/voidflow/issues/33)) ([665b9f3](https://github.com/taraxvoid/voidflow/commit/665b9f3437f75bbdc320fb1c950bf07a318e821c)) * **tag-release:** handle merge-commit release messages ([fb8e067](https://github.com/taraxvoid/voidflow/commit/fb8e0673ab2e2fed6bcef9b544883c43d4e95063)) * **tag-release:** handle merge-commit release messages ([ba6a6c9](https://github.com/taraxvoid/voidflow/commit/ba6a6c9b764bf18deb26999cf84380684a3358d8)) * **unlighthouse:** launch Chrome with --no-sandbox in CI ([#114](https://github.com/taraxvoid/voidflow/issues/114)) ([67daebb](https://github.com/taraxvoid/voidflow/commit/67daebbc0fe4b18163dabd392b38a85653871e3e)) --- 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/next-manifest.json | 2 +- jsr.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.release-please/next-manifest.json b/.release-please/next-manifest.json index 8032c17..212c2a7 100644 --- a/.release-please/next-manifest.json +++ b/.release-please/next-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.12.0" + ".": "0.13.0-next" } diff --git a/jsr.json b/jsr.json index 336260e..d6bf93a 100644 --- a/jsr.json +++ b/jsr.json @@ -1,6 +1,6 @@ { "name": "@taraxvoid/voidflow", - "version": "0.12.0", + "version": "0.13.0-next", "license": "MIT", "exports": { "./playwright": "./playwright/index.mjs" diff --git a/package.json b/package.json index d9c4048..d8c9744 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@taraxvoid/voidflow", - "version": "0.12.0", + "version": "0.13.0-next", "description": "Shared workflows, actions and tooling for @taraxvoid sites", "license": "MIT", "keywords": [ From 35fc6112afd2a6c90a1a462a7153c3d65165062d Mon Sep 17 00:00:00 2001 From: "ravenflight-releases[bot]" <330165707+ravenflight-releases[bot]@users.noreply.github.com> Date: Thu, 8 Oct 2026 23:02:11 -0700 Subject: [PATCH 06/11] chore: back-merge v0.12.1 into next (#128) Brings the v0.12.1 version bump and changelog from main into next. Merge with a merge commit, not a squash, so the branches share history. --------- Co-authored-by: Tara X V01D <1711810+taraxvoid@users.noreply.github.com> Co-authored-by: Claude Sonnet 5.5 Co-authored-by: ravenflight-releases[bot] <330165707+ravenflight-releases[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .release-please/main-manifest.json | 2 +- CHANGELOG.md | 7 +++++++ README.md | 13 +++++++++++-- default.json | 4 +--- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/.release-please/main-manifest.json b/.release-please/main-manifest.json index 8032c17..38acea6 100644 --- a/.release-please/main-manifest.json +++ b/.release-please/main-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.12.0" + ".": "0.12.1" } diff --git a/CHANGELOG.md b/CHANGELOG.md index f48bbfc..f6dc846 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ 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.12.1](https://github.com/taraxvoid/voidflow/compare/v0.12.0...v0.12.1) (2026-10-06) + + +### Bug Fixes + +* **renovate:** drop Renovate security PRs in favor of Dependabot security updates ([#124](https://github.com/taraxvoid/voidflow/issues/124)) ([63a1b6f](https://github.com/taraxvoid/voidflow/commit/63a1b6f3a7827a9292f27f27468da6bb8e802c37)) + ## [0.12.0](https://github.com/taraxvoid/voidflow/compare/v0.11.1...v0.12.0) (2026-10-06) diff --git a/README.md b/README.md index b947dde..c718799 100644 --- a/README.md +++ b/README.md @@ -222,8 +222,17 @@ 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. +set the `prepare` script so `bun install` wires the hooks, but make it tolerate a +missing binary: + +```json +"prepare": "lefthook install || echo 'lefthook not installed (run mise install); git hooks skipped'" +``` + +A bare `lefthook install` fails the whole install step (exit 127) on any runner +without the `lefthook` binary, which includes GitHub-hosted and self-hosted CI +images, and CI never runs git hooks anyway. `ref` cannot be a commit SHA; pin a +release tag. ## Branch rulesets as code diff --git a/default.json b/default.json index 003e4e0..a0dab61 100644 --- a/default.json +++ b/default.json @@ -15,9 +15,7 @@ "schedule": ["before 9am on the first day of the month"] }, "vulnerabilityAlerts": { - "minimumReleaseAge": null, - "schedule": ["at any time"], - "labels": ["security"] + "enabled": false }, "packageRules": [ { From faa203d46ad9b0c0f1107c51364ba163572cfa3d Mon Sep 17 00:00:00 2001 From: "Tara \\X/ Void" <1711810+taraxvoid@users.noreply.github.com> Date: Sun, 11 Oct 2026 21:30:17 -0700 Subject: [PATCH 07/11] feat(lefthook): honor check:precommit in the pre-commit typecheck step (#135) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lets a site narrow what the pre-commit typecheck runs, the same way `test:unit:precommit` already narrows the unit step. If a site defines a `check:precommit` script, the hook runs that; otherwise it runs `check` as before. CI keeps calling the full `check`. Purely additive: no site defines `check:precommit` today, so nothing changes until one opts in. First user: ravenflight/rvnflt (pnpm workspace). Its pre-commit typecheck currently runs every package on every commit. With this change it can run only the changed packages and their dependents via `pnpm --filter '...[HEAD]'`. ## Changes - `lefthook/site.yml`: the `typecheck` step prefers `check:precommit` when it's defined. - `README.md`: documents the override, plus the two usual recipes: - bun: `bun test --changed`. Checked locally on bun 1.4.2: it ran 1 of 9 test files with only `site.yml` and its test changed, and it counts staged changes too. - pnpm: `--filter '...[HEAD]'`, with two caveats: fall back to a full run when a root-level file changes, and exclude the root with `--filter '!{.}'`. - `test/lefthook-site.test.ts`: a test for the new branch. ## Test plan - [x] `bun test test/lefthook-site.test.ts`: 7 pass, including `lefthook validate` 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 --- README.md | 11 +++++++++++ lefthook/site.yml | 13 +++++++++++-- test/lefthook-site.test.ts | 7 +++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c718799..46599aa 100644 --- a/README.md +++ b/README.md @@ -220,6 +220,17 @@ 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`. +Likewise, define `check:precommit` and the typecheck step runs it instead of +`check`. CI keeps calling the full scripts, so these only narrow what runs +locally. Common uses: + +- bun: `"test:unit:precommit": "bun test --changed"` runs only the test files + whose imports reach an uncommitted change. +- pnpm workspace: `pnpm -r --filter '...[HEAD]' run