Skip to content

chore: promote next to main - #227

Merged
taraxvoid merged 18 commits into
mainfrom
next
Oct 24, 2026
Merged

taraxvoid merged 18 commits into
mainfrom
next

Conversation

@taraxvoid

Copy link
Copy Markdown
Owner

Commits promoted from next:

Auto-merges with a merge commit once checks pass, so each Conventional Commit reaches release-please. Do not squash it: main would get the changes from next without its commits, and every back-merge after it conflicts.

github-actions Bot and others added 18 commits October 12, 2026 05:28
chore: back-merge v0.13.0 into next
## What and why

actionlint is deprecated (mise now warns on it) in favour of
[jactionlint](https://github.com/jdx/jactionlint), an actively
maintained fork with upstream fixes merged.

- `ci.yml`, `site-ci.yml` and the justfile pin jactionlint 2.1.0 and
verify the release attestation wherever it's downloaded (site-ci
previously piped actionlint's download script from curl).
- **Consumers:** site-ci runs `--profile correctness`, which is
actionlint's rule set, unless the caller's `.github/jactionlint.yaml` /
`actionlint.yaml` sets `profile:`. That way this release can't fail
caller CI on the default profile's new rules, and a repo can opt in when
it's ready.
- voidflow sets `profile: correctness` in `.github/jactionlint.yaml` for
now. The default profile reports 9 findings, tracked in a follow-up.
- `just lint-workflows` checks `jactionlint --version` instead of
`command -v`, because a mise shim with no version set is on PATH but
fails.

Verified locally: `just lint-workflows` (download path included), `just
lint-actions`, `just security`.

Closes #173

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Closes #155.

Makes voidflow the default kit for any @taraxvoid bun repo, not only
Astro sites.

## Changes

- **`lefthook/base.yml`** (breaking): the hook set moves from
`lefthook/site.yml` to `lefthook/base.yml`. Before the `test:unit` and
`test:push` steps it runs `unset $(git rev-parse --local-env-vars)`, so
tests that spawn git in a temp repo no longer act on the hooked repo.
Tests run the real hook snippets against a stub to check this.
- **`lefthook/site.yml` stub**: Renovate bumps only `ref:`, and lefthook
skips a missing remote config without any warning. A plain rename would
therefore turn every consumer's hooks off silently. `site.yml` is now a
stub whose `pre-commit` and `pre-push` fail with the one-line fix.
- **mise**: a `mise.toml` for contributor tools, plus a `prepare` script
that tolerates a missing `lefthook` binary. The README setup becomes
`mise install && bun install`, and the consumer docs get a starter
`mise.toml`. The package description and keywords now cover tools.
- **`tool-ci.yml`**: a reusable validation workflow for bun tools.
- Steps: gitleaks, the shared install script, `mise-action` when the
repo has a `mise.toml`, then
`lint`/`check`/`build`/`test`/`check:licenses` for whichever scripts
`package.json` defines. actionlint and zizmor run when workflows change.
  - The job reports `validate / Validate`.
- Parity tests keep the steps it shares identical to `site-ci.yml` and
`actions/bun-install`.
- **Rulesets**: a `tool()` helper (main only, no Netlify, CODEOWNERS,
linear history, requires `validate / Validate`). `SITE_CHECK` is renamed
`VALIDATE_CHECK`.

## Migration

Consumers change `configs: [lefthook/site.yml]` to `lefthook/base.yml`
when they bump `ref`. Until they do, commits and pushes fail with that
instruction.

## Notes

- On free personal plan the rulesets API returns 403 for private repos,
which aborts the whole `apply-rulesets` run.
- `bun scripts/apply-rulesets.ts --check` reports the fleet in sync. An
earlier run listed 5 differences, but none was drift. They were retired
`next (staging)`/`live (prod)` rulesets on queeromaha, soundry and
synthomaha, waiting for `--prune`. Those rulesets have now been pruned,
and the stale `next`/`live` branches on soundry and synthomaha (0
commits ahead of main, no open PRs) have been deleted. That cleanup was
done out of band; this branch does not change it.

## Verification

- `bun test`: 148 pass, 0 fail.
- `just validate`: actionlint, check-jsonschema, shellcheck, gitleaks
and zizmor all clean.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
…iome (#183)

Closes #182

- `biome/base.json`: the house style five sites already share (4-space,
LF, width 80, single quotes, semicolons as needed, trailing commas,
`recommended` preset, organize imports, CSS lint off, HTML formatter
settings, git ignore file, `.astro` unused-import override). No ignore
lists; those stay per site.
- Exported as `@taraxvoid/voidflow/biome` and added to `files`, so a
site writes `"extends": ["@taraxvoid/voidflow/biome"]`.
- Biome 1.x warning (never fails) in the `lefthook/site.yml` pre-commit
hook and a `Check Biome version` step in `site-ci.yml` before `Lint
Code`.
- README section on using it.

## Testing

`test/biome-base.test.ts` builds a throwaway site that extends the
package by name and runs Biome 2.5.14 (new exact devDependency) on it:
- the base resolves through the package export
- house style is enforced (semicolons, double quotes fail) and the
recommended preset is on
- the `.astro` override matches files in the extending site (with a
control showing recommended flags the same file without the base)
- a site setting overrides the base

It also runs the hook and CI snippets against fake installs of Biome
1.9.4, 2.5.14 and none.

`bun test`: 125 pass, 1 fail. The failure is `lefthook/site.yml > is a
valid lefthook config`, which fails locally because `lefthook` on PATH
is a mise shim with no version set (`Bun.which` finds the shim). `mise
exec lefthook@2.2.1 -- lefthook validate` on the changed config prints
"All good". `just lint-workflows lint-shell lint-actions` pass.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
#157 (e775c8b) committed mise state from a run with HOME at the repo
root: `.cache/mise/`, `.local/share/mise/` (including lefthook binaries)
and `.local/state/mise/`, plus a stray file `f` containing `y`.

This removes them and adds `/.cache/` and `/.local/` to `.gitignore` so
they don't come back. `mise.toml` stays.

Refs #157

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
🤖 I have created a release *beep* *boop*
---


##
[0.14.0-next](v0.13.0...v0.14.0-next)
(2026-10-16)


### Features

* **biome:** shared base config sites extend as
@taraxvoid/voidflow/biome
([#183](#183))
([a5f0977](a5f0977))
* tool ergonomics (base hooks, tool-ci, mise, tool rulesets)
([#157](#157))
([e775c8b](e775c8b))


### Bug Fixes

* **site-ci:** replace deprecated actionlint with jactionlint
([#174](#174))
([6192a43](6192a43))

---
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>
`site-ci.yml` and `tool-ci.yml` now write gitleaks and zizmor results as
SARIF and keep them as the `voidflow-sarif` artifact. New opt-in
`upload-sarif.yml` sends them to code scanning, so voidlight's
`findings.zizmor` / `findings.gitleaks` stop being `null`.

- gitleaks: same step, plus `--report-format sarif` (redacted). Still
gates.
- zizmor: extra `--format sarif` run over every workflow after the
gates, `!cancelled()`, never fails the job (zizmor disables exit codes
for SARIF). The existing zizmor gate in tool-ci is unchanged.
- Upload is a separate reusable workflow because it needs
`security-events: write`; asking for it inside site-ci/tool-ci would
fail every caller that doesn't grant it. Callers add a `sarif` job
(README has the snippet).
- One category per tool, so each upload only closes its own fixed
alerts.
- Tests keep the SARIF steps identical between site-ci and tool-ci and
pin `security-events` to upload-sarif.yml only.

Doesn't add the zizmor *gate* to site-ci (#178), but sites using
`upload-sarif.yml` get zizmor findings counted.

Private repos need GitHub Code Security for the upload; public sites are
free.

Suggested bump: **minor** (feat) → 0.14.0.

---
_Generated by [Claude
Code](https://claude.ai/code/session_01KVnoX5acfvfmD6ge48HjqB)_

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Spec for `python-ci.yml`, `skills-ci.yml`, a deferred `iac-ci.yml`, the
shared contract every `<usecase>-ci.yml` follows, and fleet sync
(Renovate group rule, PR-time drift warning, `just fleet-sync`). Docs
only, no bump.

---
_Generated by [Claude
Code](https://claude.ai/code/session_01KVnoX5acfvfmD6ge48HjqB)_

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: ravenflight-releases[bot] <330165707+ravenflight-releases[bot]@users.noreply.github.com>
🤖 I have created a release *beep* *boop*
---


##
[0.14.0-next.1](v0.14.0-next...v0.14.0-next.1)
(2026-10-22)


### Features

* **ci:** SARIF for gitleaks and zizmor, opt-in upload-sarif.yml
([#187](#187))
([3ff2a33](3ff2a33))

---
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>
Brings main's 0.14.0 release and the Depot CI migration (#203) into next.
Version bookkeeping follows scripts/back-merge.ts: package.json, jsr.json
and both manifests move to 0.14.0, CHANGELOG.md takes main's side. Other
conflicts keep next's side (SARIF in tool-ci.yml, README, tests) and add
main's ravenflight.io ruleset entry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Resolves the conflicts the back-merge job refused (#219):

- README.md: take main's consumer rewrite and keep next's SARIF section as
  a top-level "Code scanning (SARIF)" section after Tool CI.
- test/site-ci.test.ts: main's docs-only gate test required every step after
  `decide` to carry the gate, but next's SARIF steps run after failures and
  must stay last. Exempt the three trailing SARIF steps so docs-only PRs
  still keep their gitleaks/zizmor SARIF.
- .release-please/next-manifest.json: 0.14.0 to 0.15.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
chore: back-merge v0.15.0 from main into next
…as code (#180)

Scoped Cloudflare deploy tokens as code, using the per-Worker scoping
Cloudflare added in September 2026. Same pattern as `rulesets/`:
describe the desired state, then plan and apply idempotent changes to
reach it. Old hand-made tokens can be retired as part of the cutover.

## What's here

- **`cloudflare/tokens.ts`:** the config shape and the plan logic. Each
token is owned by an account, scoped to one Worker (the Workers Editor
role on it), gets Workers Routes Write on its route zones only, and
expires after 90 days.
- The Worker and zones come from the caller's own wrangler config, from
its default branch. A route added there shows up as drift. `worker` and
`zones` can still be set explicitly, and `zones: []` grants no zones
(for preview tokens).
- **The fleet lives in each org's infra repo** (`taraxvoid/infra`,
`ravenflight/infra`), passed with `--config`. `cf-tokens-*` requires it.
The shared loader is `scripts/lib/config.ts`, which `apply-rulesets`
also uses.
- **`scripts/cf-tokens.ts`:** plan, apply, rotate and prune.
- Each new value goes straight into the `CLOUDFLARE_API_TOKEN` secret
and is never printed. The secret is per GitHub environment by default,
or repo-wide with `secret: 'repo'`.
- A rotation creates the new token, sets the secret, then deletes the
old one. If the secret write fails, the new token is deleted again. If
an earlier run left duplicate tokens, the next run rotates them all away
rather than guessing which one GitHub holds.
- When every env uses environments, a leftover repo-wide
`CLOUDFLARE_API_TOKEN` is reported, and deleted with `--prune`.
  - The plan prints each token's last use.
- **`--try`** (`just cf-tokens-try`): runs a command, such as a local
`wrangler deploy`, with a one-hour throwaway token that has exactly an
env's policies. This proves the grants before CI relies on them.
- **Fallback:** an env can record `fallback`, which adds account-wide
Workers Scripts Write. Every plan prints it, and `cloudflare-deploy`'s
new `token-fallback` input warns on every deploy that uses it.
- **`CF_TOKEN_ADMIN`** comes from fnox (`fnox.toml` declares it, macOS
Keychain provider). `just doctor` reports whether it resolves.
- **Rulesets:** `--config` support, repos whose rulesets are written out
in full (`RawConfig`), and missing fields in a `--config` repo default
from `tool()`, with unknown fields reported.

## Shakedown (done)

- [x] transbot: plan, apply, rotate, prune. `cf-tokens-try` deployed its
custom domain with only the zone grant, so no fallback was needed.
- [x] taraxvoid.net: KV bound by id, two zones, old token in a repo-wide
secret. The deploy worked, the old token is retired, and the repo-wide
secret was pruned.
- [x] Fleet moved to `taraxvoid/infra`, and `just cf-tokens-plan` there
is in sync.
- [ ] A CI deploy with the real token. Blocked for now by GitHub Actions
billing on the private repos. The plan's last-used column will confirm
it.

## Follow-ups

- #222: move the built-in rulesets fleet to the infra repos. It lands
after #209.
- Template-derived sites (voidsite, taraxvoid.com) create KV/D1/R2 at
deploy time, which a single-Worker token can't do. They need committed
resource ids plus a `grants` field. See the #179 comments.
- ravenflight.io via `ravenflight/infra`, once its account move and its
single-trunk switch are settled.

Refs #179

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
chore: back-merge v0.15.1 into next
🤖 I have created a release *beep* *boop*
---


##
[0.16.0-next](v0.15.0...v0.16.0-next)
(2026-10-24)


### Features

* **cf-tokens:** implement sync-able scoped Cloudflare deploy tokens as
code ([#180](#180))
([42c5373](42c5373))

---
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>
Co-authored-by: Tara \X/ Void <1711810+taraxvoid@users.noreply.github.com>
@taraxvoid
taraxvoid enabled auto-merge October 24, 2026 05:35
@taraxvoid
taraxvoid merged commit 63ea450 into main Oct 24, 2026
9 checks passed

This branch was successfully deployed

1 active deployment
npm — 553ef138 Deployed Oct 24, 2026 by taraxvoid via Publish to npm #126
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