@taraxvoid/voidflow 0.13.0 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +116 -24
- package/biome/base.json +63 -0
- package/package.json +11 -4
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# voidflow
|
|
2
2
|
|
|
3
|
-
Shared CI and deploy pipeline for a small fleet of Astro sites on Cloudflare Workers. One set of reusable GitHub Actions workflows and composite actions keeps lint, type checks, license policy, Playwright and axe-core accessibility tests, Unlighthouse budgets, and deploys identical across every site.
|
|
3
|
+
Shared CI and deploy pipeline for a small fleet of Astro sites on Cloudflare Workers, and the bun tools around them. One set of reusable GitHub Actions workflows and composite actions keeps lint, type checks, license policy, Playwright and axe-core accessibility tests, Unlighthouse budgets, and deploys identical across every site.
|
|
4
4
|
|
|
5
5
|
- **SHA-pinned.** Every third-party action in this repo is pinned to a full commit SHA with a version comment.
|
|
6
|
-
- **Audited.** Workflows are checked with [zizmor](https://github.com/zizmorcore/zizmor), [
|
|
6
|
+
- **Audited.** Workflows are checked with [zizmor](https://github.com/zizmorcore/zizmor), [jactionlint](https://github.com/jdx/jactionlint), check-jsonschema and shellcheck on every change (see [Self-validation](#self-validation)).
|
|
7
7
|
- **In production.** It runs the pipelines for the sites listed under [Used by](#used-by), including the marketing site for [RavenFlight Industries, LLC](https://rvnflt.com/github).
|
|
8
8
|
|
|
9
9
|
It is semi-opinionated: the defaults match how my own sites are built (bun, Astro, Playwright).
|
|
@@ -11,7 +11,7 @@ It is semi-opinionated: the defaults match how my own sites are built (bun, Astr
|
|
|
11
11
|
## Used by
|
|
12
12
|
|
|
13
13
|
- [taraxvoid.net](https://taraxvoid.net), my portfolio
|
|
14
|
-
- [Queer Omaha](https://queeromaha.net), [Synth Omaha](https://synthomaha.net) and [Soundry](https://soundryomaha.
|
|
14
|
+
- [Queer Omaha](https://queeromaha.net), [Synth Omaha](https://synthomaha.net) and [Soundry](https://soundryomaha.org), free community sites for Omaha's queer and music scenes
|
|
15
15
|
- [ravenflight.io](https://ravenflight.io), RavenFlight's marketing site
|
|
16
16
|
|
|
17
17
|
### Show you use it
|
|
@@ -95,8 +95,8 @@ jobs:
|
|
|
95
95
|
build-env: ${{ format('{{"PUBLIC_SITE_URL":"https://example.com","GIT_SHA":"{0}"}}', github.sha) }}
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
-
With `pnpm`, the pnpm version comes from `packageManager` and Node from
|
|
99
|
-
|
|
98
|
+
With `pnpm`, the pnpm version comes from `packageManager` and Node from
|
|
99
|
+
`engines` in `package.json`. The lockfile (`bun.lock` or `pnpm-lock.yaml`)
|
|
100
100
|
follows the package manager. `build-env` is a JSON object, visible in logs, so
|
|
101
101
|
no secrets.
|
|
102
102
|
|
|
@@ -146,6 +146,39 @@ Runs lint, typecheck, check for GPL licenses, e2e with Playwright.
|
|
|
146
146
|
`live`), and `test:e2e:lighthouse` (`live`). A script the site does not define
|
|
147
147
|
is skipped with a notice, so none of them is required.
|
|
148
148
|
|
|
149
|
+
### Tool validation
|
|
150
|
+
|
|
151
|
+
`tool-ci.yml` is the validation job for bun tools and libraries (CLIs, TUIs,
|
|
152
|
+
packages): gitleaks over the full history, install (with the same Socket
|
|
153
|
+
scanner handling as `site-ci.yml`), tools from the repo's `mise.toml` when it
|
|
154
|
+
has one, then whichever of `lint`, `check`, `build` and `test` `package.json`
|
|
155
|
+
defines, and `check:licenses` when dependencies or `scripts/` changed. When
|
|
156
|
+
workflows change it also runs jactionlint (same profile handling as
|
|
157
|
+
`site-ci.yml`) and
|
|
158
|
+
[zizmor](https://github.com/zizmorcore/zizmor). The bun version comes from
|
|
159
|
+
`.bun-version` when present.
|
|
160
|
+
|
|
161
|
+
```yaml
|
|
162
|
+
name: CI
|
|
163
|
+
on:
|
|
164
|
+
pull_request:
|
|
165
|
+
types: [opened, synchronize, reopened, ready_for_review]
|
|
166
|
+
push:
|
|
167
|
+
branches: [main]
|
|
168
|
+
workflow_dispatch:
|
|
169
|
+
|
|
170
|
+
permissions:
|
|
171
|
+
contents: read
|
|
172
|
+
pull-requests: read
|
|
173
|
+
|
|
174
|
+
jobs:
|
|
175
|
+
validate:
|
|
176
|
+
uses: taraxvoid/voidflow/.github/workflows/tool-ci.yml@<release SHA> # vX.Y.Z
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
The job reports as `validate / Validate`, the check the `tool()` entry in
|
|
180
|
+
[`rulesets/index.ts`](#branch-rulesets-as-code) requires.
|
|
181
|
+
|
|
149
182
|
### Unlighthouse (performance / SEO budgets)
|
|
150
183
|
|
|
151
184
|
`site-ci.yml` runs `bun run test:e2e:lighthouse` on PRs into `live`. Sites
|
|
@@ -191,6 +224,11 @@ the global `~/.bunfig.toml` rather than the site's, so a global
|
|
|
191
224
|
locally (including in the pre-commit hook) for 3 days after every release.
|
|
192
225
|
The devDependency's bins are installed under the site's own `bunfig.toml`.
|
|
193
226
|
|
|
227
|
+
Both bins (`check-licenses`, `unlighthouse-runner`) are TypeScript run by Bun
|
|
228
|
+
(`#!/usr/bin/env bun`), so `bun` must be on `PATH` even when the site uses
|
|
229
|
+
npm or pnpm. The `@taraxvoid/voidflow/playwright` export is plain ESM and runs
|
|
230
|
+
on Node 22+ without Bun.
|
|
231
|
+
|
|
194
232
|
### Playwright preview config
|
|
195
233
|
|
|
196
234
|
Shared `playwright.config` for Astro sites that run e2e against
|
|
@@ -219,6 +257,31 @@ Options: `ciPort` (required in CI), `runner` (default `bun`, e.g. `pnpm`),
|
|
|
219
257
|
`timeout` (default 30000), `projects` (default Pixel 7 and Desktop Chrome),
|
|
220
258
|
`testDir` (default `./test/e2e`). Requires `@playwright/test` in the site.
|
|
221
259
|
|
|
260
|
+
## Shared Biome config
|
|
261
|
+
|
|
262
|
+
[`biome/base.json`](biome/base.json) is the house style for the fleet: 4-space
|
|
263
|
+
indent, LF, width 80, single quotes, semicolons only where needed, trailing
|
|
264
|
+
commas, the `recommended` rule preset, organized imports, CSS lint off, and
|
|
265
|
+
unused-import/variable rules off in `.astro` files (Biome can't see template
|
|
266
|
+
usage). With `@taraxvoid/voidflow` as a devDependency, the site's `biome.json`
|
|
267
|
+
extends it and adds only what is specific to the site:
|
|
268
|
+
|
|
269
|
+
```json
|
|
270
|
+
{
|
|
271
|
+
"$schema": "https://biomejs.dev/schemas/2.5.14/schema.json",
|
|
272
|
+
"extends": ["@taraxvoid/voidflow/biome"],
|
|
273
|
+
"files": {
|
|
274
|
+
"includes": ["**", "!**/bun.lock", "!public/admin/**"]
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Lists such as `files.includes` and `overrides` combine with the base's rather
|
|
280
|
+
than replace them; single values set in the site win. The base has no ignore
|
|
281
|
+
lists, so each site keeps its own. It needs Biome 2: the pre-commit hook and
|
|
282
|
+
`site-ci.yml` print a warning (they don't fail) when a site has Biome 1.x
|
|
283
|
+
installed.
|
|
284
|
+
|
|
222
285
|
## Dependency updates (Renovate)
|
|
223
286
|
|
|
224
287
|
[`default.json`](default.json) is the shared Renovate preset. Sites add a
|
|
@@ -243,30 +306,43 @@ on the repo.
|
|
|
243
306
|
|
|
244
307
|
## Git hooks (lefthook)
|
|
245
308
|
|
|
246
|
-
[`lefthook/
|
|
247
|
-
|
|
248
|
-
scripts (`<pm> run --if-present`, so a missing
|
|
249
|
-
when the repo has a `pnpm-lock.yaml`, bun
|
|
309
|
+
[`lefthook/base.yml`](lefthook/base.yml) is the shared hook set for any bun
|
|
310
|
+
(or pnpm) repo, sites and tools alike, consumed as a lefthook remote. It calls
|
|
311
|
+
the repo's own `package.json` scripts (`<pm> run --if-present`, so a missing
|
|
312
|
+
script is skipped; `<pm>` is pnpm when the repo has a `pnpm-lock.yaml`, bun
|
|
313
|
+
otherwise):
|
|
250
314
|
|
|
251
|
-
- `pre-commit`: dependency guard, `format` (formatted files are re-staged),
|
|
315
|
+
- `pre-commit`: dependency guard, Biome 1.x warning, `format` (formatted files are re-staged),
|
|
252
316
|
`lint:actions`, `check`, `test:unit`, and `check:licenses` / `audit` when the
|
|
253
317
|
lockfile changed.
|
|
254
318
|
- `commit-msg`: advisory Conventional Commits hint (never blocks).
|
|
255
319
|
- `pre-push`: bail if the remote branch is ahead, then `test:push`; skipped when
|
|
256
|
-
|
|
320
|
+
the push carries no commit the remote lacks (branch deletes, and tags or
|
|
321
|
+
branches at already-pushed commits).
|
|
322
|
+
|
|
323
|
+
Before `test:unit` and `test:push`, the hooks unset the variables git exports to
|
|
324
|
+
hooks (`GIT_DIR`, `GIT_INDEX_FILE`, ...; the list comes from
|
|
325
|
+
`git rev-parse --local-env-vars`). Without that, a test that runs
|
|
326
|
+
`git -C <tmpdir> commit` operates on, and commits into, the repo being hooked.
|
|
257
327
|
|
|
258
328
|
```yaml
|
|
259
|
-
# lefthook.yml in the
|
|
329
|
+
# lefthook.yml in the repo
|
|
260
330
|
remotes:
|
|
261
331
|
- git_url: https://github.com/taraxvoid/voidflow
|
|
262
332
|
ref: v0.10.0 # a tag or branch; lefthook passes it to `git clone --branch`
|
|
263
333
|
configs:
|
|
264
|
-
- lefthook/
|
|
334
|
+
- lefthook/base.yml
|
|
265
335
|
|
|
266
336
|
```
|
|
267
337
|
|
|
338
|
+
Upgrading from `lefthook/site.yml` (v0.13 and earlier): change the `configs`
|
|
339
|
+
entry to `lefthook/base.yml` when you bump `ref`. The hooks are otherwise the
|
|
340
|
+
same. `lefthook/site.yml` is now a stub whose `pre-commit` and `pre-push` fail
|
|
341
|
+
with that instruction, so a `ref` bump (for example from Renovate) that leaves
|
|
342
|
+
`configs` alone stops commits instead of turning the hooks off silently.
|
|
343
|
+
|
|
268
344
|
Lefthook merges `lefthook.yml`, then remotes, then `lefthook-local.yml`, so a
|
|
269
|
-
|
|
345
|
+
repo's own `lefthook.yml` can add commands (for example image compression) but
|
|
270
346
|
cannot override ones defined here. Differences go through `package.json`
|
|
271
347
|
scripts: define `test:unit:precommit` (for example excluding tests that need a
|
|
272
348
|
built `dist/`) and the pre-commit unit step runs it instead of `test:unit`.
|
|
@@ -283,13 +359,22 @@ locally. Common uses:
|
|
|
283
359
|
as a recursive run, add `--filter '!{.}'` so it doesn't recurse.
|
|
284
360
|
|
|
285
361
|
Hook-level options merge too. Don't set `parallel: true` under `pre-commit:` in
|
|
286
|
-
the
|
|
362
|
+
the repo's `lefthook.yml`: it applies to the merged hook, so every step,
|
|
287
363
|
including the shared ones, starts at once and their `priority` order is ignored
|
|
288
364
|
(tests that share a database or build output can then time out).
|
|
289
365
|
|
|
290
|
-
Install the
|
|
291
|
-
|
|
292
|
-
|
|
366
|
+
Install the binaries through mise. A starter `mise.toml` for a repo using
|
|
367
|
+
these hooks and voidflow CI:
|
|
368
|
+
|
|
369
|
+
```toml
|
|
370
|
+
[tools]
|
|
371
|
+
lefthook = "2.2.1"
|
|
372
|
+
gitleaks = "8.30.1"
|
|
373
|
+
jactionlint = "2.1.0"
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
Renovate bumps `mise.toml` natively. Set the `prepare` script so `bun install`
|
|
377
|
+
wires the hooks, but make it tolerate a missing binary:
|
|
293
378
|
|
|
294
379
|
```json
|
|
295
380
|
"prepare": "lefthook install || echo 'lefthook not installed (run mise install); git hooks skipped'"
|
|
@@ -305,7 +390,10 @@ release tag.
|
|
|
305
390
|
Branch protection for the fleet lives in [`rulesets/index.ts`](rulesets/index.ts):
|
|
306
391
|
one canonical `main` / `next` / `live` definition (plus `prerelease` and `maintenance`
|
|
307
392
|
tiers for repos with release channels) and a small per-repo table
|
|
308
|
-
(Netlify or not, check names, CODEOWNERS, extra bypass actors).
|
|
393
|
+
(Netlify or not, check names, CODEOWNERS, extra bypass actors). Sites use
|
|
394
|
+
`site()` and tools use `tool()` (main only, no Netlify, requires
|
|
395
|
+
`validate / Validate` from `tool-ci.yml`). Private repos are left out: on a
|
|
396
|
+
plan without rulesets for private repos, the API returns 403. Hand-edited
|
|
309
397
|
rulesets drift, and drift is how a `next` ruleset ends up requiring a check
|
|
310
398
|
name that no workflow reports any more.
|
|
311
399
|
|
|
@@ -323,7 +411,11 @@ manages `main`, `prerelease` (`next`) and `maintenance` (`release/*`) and sets
|
|
|
323
411
|
`linearHistory: false` so `next` can be promoted into `main` with a merge commit.
|
|
324
412
|
Uses the `gh` CLI for auth (needs admin on the repos). Rulesets that are not in
|
|
325
413
|
the config are reported and left alone; only `retire` entries are ever deleted,
|
|
326
|
-
and only with `--prune`.
|
|
414
|
+
and only with `--prune`. Private repos on a plan without rulesets (GitHub answers
|
|
415
|
+
403, e.g. a free personal account) are skipped and listed at the end rather than
|
|
416
|
+
failing the run, so `--check` stays green and they pick up their rulesets once the
|
|
417
|
+
repo goes public or the plan changes. It is repo tooling, not part of the published
|
|
418
|
+
package.
|
|
327
419
|
|
|
328
420
|
## Deployments
|
|
329
421
|
|
|
@@ -397,16 +489,16 @@ Treat `@main` and `@next` as unstable.
|
|
|
397
489
|
|
|
398
490
|
This repo validates its own workflows and composite actions (`.github/workflows/ci.yml`):
|
|
399
491
|
|
|
400
|
-
- **
|
|
492
|
+
- **jactionlint**: workflow schema/logic; also shellchecks `run:` steps in `.github/workflows/*.yml` automatically (`shellcheck` ships on `ubuntu-latest`)
|
|
401
493
|
- **check-jsonschema**: schema-checks `actions/**/action.yml` and the workflow files against [SchemaStore](https://www.schemastore.org/)'s `github-action.json` / `github-workflow.json`
|
|
402
|
-
- **shellcheck** (`scripts/shellcheck-actions.ts`): checks `run:` steps inside `actions/**/action.yml`, which
|
|
494
|
+
- **shellcheck** (`scripts/shellcheck-actions.ts`): checks `run:` steps inside `actions/**/action.yml`, which jactionlint doesn't reach
|
|
403
495
|
- **zizmor**: security audit (unpinned refs, script injection via `${{ }}` in `run:`, excess permissions, etc.)
|
|
404
496
|
|
|
405
497
|
### Local dev setup
|
|
406
498
|
|
|
407
499
|
```sh
|
|
408
|
-
|
|
409
|
-
lefthook install
|
|
500
|
+
mise install # tools pinned in mise.toml
|
|
501
|
+
bun install # its prepare script runs `lefthook install`
|
|
410
502
|
```
|
|
411
503
|
|
|
412
504
|
- `just validate`: run everything CI runs, locally
|
package/biome/base.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"vcs": {
|
|
3
|
+
"enabled": true,
|
|
4
|
+
"clientKind": "git",
|
|
5
|
+
"useIgnoreFile": true
|
|
6
|
+
},
|
|
7
|
+
"assist": {
|
|
8
|
+
"enabled": true,
|
|
9
|
+
"actions": {
|
|
10
|
+
"source": {
|
|
11
|
+
"organizeImports": "on"
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"formatter": {
|
|
16
|
+
"enabled": true,
|
|
17
|
+
"indentStyle": "space",
|
|
18
|
+
"indentWidth": 4,
|
|
19
|
+
"lineEnding": "lf",
|
|
20
|
+
"lineWidth": 80,
|
|
21
|
+
"useEditorconfig": true
|
|
22
|
+
},
|
|
23
|
+
"javascript": {
|
|
24
|
+
"formatter": {
|
|
25
|
+
"arrowParentheses": "always",
|
|
26
|
+
"jsxQuoteStyle": "double",
|
|
27
|
+
"quoteProperties": "asNeeded",
|
|
28
|
+
"quoteStyle": "single",
|
|
29
|
+
"semicolons": "asNeeded",
|
|
30
|
+
"trailingCommas": "all"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"html": {
|
|
34
|
+
"formatter": {
|
|
35
|
+
"indentScriptAndStyle": false,
|
|
36
|
+
"selfCloseVoidElements": "always"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"css": {
|
|
40
|
+
"linter": {
|
|
41
|
+
"enabled": false
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"linter": {
|
|
45
|
+
"enabled": true,
|
|
46
|
+
"rules": {
|
|
47
|
+
"preset": "recommended"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"overrides": [
|
|
51
|
+
{
|
|
52
|
+
"includes": ["**/*.astro"],
|
|
53
|
+
"linter": {
|
|
54
|
+
"rules": {
|
|
55
|
+
"correctness": {
|
|
56
|
+
"noUnusedImports": "off",
|
|
57
|
+
"noUnusedVariables": "off"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
}
|
package/package.json
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taraxvoid/voidflow",
|
|
3
|
-
"version": "0.13.
|
|
4
|
-
"description": "Shared workflows,
|
|
3
|
+
"version": "0.13.1",
|
|
4
|
+
"description": "Shared workflows, hooks and tooling for @taraxvoid repos",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"github-actions",
|
|
8
8
|
"ci",
|
|
9
9
|
"reusable-workflows",
|
|
10
|
+
"lefthook",
|
|
11
|
+
"renovate",
|
|
12
|
+
"bun",
|
|
10
13
|
"playwright",
|
|
11
14
|
"unlighthouse",
|
|
12
|
-
"astro",
|
|
13
15
|
"cloudflare"
|
|
14
16
|
],
|
|
15
17
|
"homepage": "https://github.com/taraxvoid/voidflow#readme",
|
|
@@ -33,17 +35,21 @@
|
|
|
33
35
|
"types": "./playwright/index.d.mts",
|
|
34
36
|
"default": "./playwright/index.mjs"
|
|
35
37
|
},
|
|
38
|
+
"./biome": "./biome/base.json",
|
|
36
39
|
"./package.json": "./package.json"
|
|
37
40
|
},
|
|
38
41
|
"files": [
|
|
42
|
+
"biome",
|
|
39
43
|
"playwright",
|
|
40
44
|
"scripts/unlighthouse",
|
|
41
45
|
"scripts/check-licenses.ts"
|
|
42
46
|
],
|
|
43
47
|
"engines": {
|
|
44
|
-
"bun": ">=1.4.0"
|
|
48
|
+
"bun": ">=1.4.0",
|
|
49
|
+
"node": ">=22"
|
|
45
50
|
},
|
|
46
51
|
"scripts": {
|
|
52
|
+
"prepare": "lefthook install || echo 'lefthook not installed (run mise install); git hooks skipped'",
|
|
47
53
|
"test": "bun test"
|
|
48
54
|
},
|
|
49
55
|
"peerDependencies": {
|
|
@@ -55,6 +61,7 @@
|
|
|
55
61
|
}
|
|
56
62
|
},
|
|
57
63
|
"devDependencies": {
|
|
64
|
+
"@biomejs/biome": "2.5.14",
|
|
58
65
|
"@playwright/test": "1.64.0",
|
|
59
66
|
"@socketsecurity/bun-security-scanner": "1.1.3"
|
|
60
67
|
},
|