27 Commits
Author SHA1 Message Date
tmu c0bba0775c 🚀 Release 0.1.5
CI / release-gate (push) Successful in 2s
CI / build (push) Successful in 24s
CI / maintain (push) Failing after 15s
CI / publish (push) Failing after 17s
2026-09-15 09:33:17 +00:00
tmu b8d235df89 🔀 Merge chore/improve-ci-publish into main 2026-09-15 09:32:04 +00:00
tmu 76fe8993a7 📝 Track the docs cleanup and docs-site task 2026-09-15 09:31:58 +00:00
tmu f984576d4e 📝 Record the automatic-token publish design in the backlog
Point 1 dropped the GITEA_TOKEN gate (the run's automatic github.token is
always present), and point 2 added the all-or-nothing check; keep the checked
task from claiming behavior the workflow no longer has.
2026-09-15 09:25:42 +00:00
tmu 79b4d8c005 ♻️ Use the automatic token and fail closed on a partial release
Drop the GITEA_TOKEN gate and pass no explicit token: gitea-release-action
defaults to the run's automatic github.token, so the release page needs only
contents: write. Keep the npm publish gated on NPM_TOKEN, but add a final
always() step that fails the job unless both the release page and npm publish
reported success, so a skipped npm half is an explicit red job instead of a
silently green one.
2026-09-15 09:25:24 +00:00
tmu 60e416b0fe 📝 Check off the CI publish task
The publish job was already tag-only; the coarse NPM_TOKEN assert is replaced by
per-step env gates, so an unset secret now skips only its own step.
2026-09-15 09:06:48 +00:00
tmu e90d2549e3 📝 Document the publish-step token gates
Record the two optional secrets and why the job lifts them into env: the
secrets context is unavailable in a step if, so env is the only place the gate
can read them.
2026-09-15 09:06:39 +00:00
tmu 8915eb8faa 👷 Gate the publish steps on their tokens
The publish job aborted at the top-of-job NPM_TOKEN assert, so every tag run
since 0.1.1 failed before checkout and nothing was ever published. Lift both
optional secrets into job-level env (the secrets context is not allowed in a
step if) and gate each publish step: the Gitea release on GITEA_TOKEN, npm
publish on NPM_TOKEN. An absent secret now skips only its step, so a tag without
the maintainer's secrets stays green after the packaging checks.
2026-09-15 09:06:35 +00:00
tmu 75f2185b32 📝 Track the CI publish hardening task
Also restores the runner force-pull task that the new entry had replaced; it is
still open (CONTRIBUTING § CI runner image documents the stale-image failure).
2026-09-15 09:05:41 +00:00
tmu 9c472c88c2 🚀 Release 0.1.4
CI / release-gate (push) Successful in 2s
CI / build (push) Successful in 22s
CI / maintain (push) Successful in 14s
CI / publish (push) Failing after 3s
2026-09-14 16:20:46 +00:00
tmu 16962e947e 🔀 Merge chore/dependency-updates into main 2026-09-14 16:19:04 +00:00
tmu be0ca717d0 ⬆️ Upgrade oxfmt to 0.68.0 and oxlint to 1.83.0
Latest releases of the two oxc tools; both minor bumps within 0.x/1.x
semver ranges. check-outdated now reports zero outdated dependencies
and npm run verify passes with no rule or format fallout.
2026-09-14 16:18:02 +00:00
tmu 5a3ee3b8cc 🔀 Merge chore/remove-toolcache-diagnostics into main
CI / release-gate (push) Successful in 2s
CI / build (push) Successful in 18s
CI / publish (push) Skipped
CI / maintain (push) Failing after 14s
2026-09-14 16:07:52 +00:00
tmu 77fb604d7e 📝 Check off the CI Node-baking task
All steps confirmed green in CI ('Found in cache @ /opt/hostedtoolcache/node/
26.8.2/x64', no download). The runner-side force-pull item moves to its own
task, since a changed image under an unchanged tag is still silently ignored.
2026-09-14 16:04:03 +00:00
tmu 1b2b50304e ♻️ Assert the baked tool cache instead of logging it
The diagnostics did their job (missing <version>/<arch>.complete marker, now
written by the image). Replace the noise with a fail-fast assert that names
the same invariant, mirroring the publish job's NPM_TOKEN check: a stale tag
on the runner would otherwise silently reintroduce the per-job download, with
nothing in the repo to catch it.
2026-09-14 16:04:01 +00:00
tmu 048a8870e6 🐛 Write the tool-cache completion marker into the image
CI / release-gate (push) Successful in 3s
CI / build (push) Successful in 39s
CI / publish (push) Skipped
CI / maintain (push) Failing after 15s
setup-node still downloaded although the image carried a perfect
/opt/hostedtoolcache/node/26.8.2/x64/ tree. actions/tool-cache accepts a
cached tool only when the sibling marker <version>/<arch>.complete exists
(tc.find() tests it explicitly); a bare directory is ignored, so the probe
fell through to the download. The marker is what tc.cacheDir() writes after
installing a tool, so the baked entry must create it too.

Job-container diagnostics also confirmed the path was never in question:
RUNNER_TOOL_CACHE=/opt/hostedtoolcache, no mount over it, node -v from the
baked path prints v26.8.2.

CONTRIBUTING records both invariants — the marker, and the fact that a
Dockerfile change keeps the same tag, which forcePull=false can hide.
2026-09-14 15:59:23 +00:00
tmu f0b28c81c0 🔊 Log tool-cache state in the CI build job
CI / release-gate (push) Successful in 2s
CI / build (push) Successful in 40s
CI / publish (push) Skipped
CI / maintain (push) Failing after 42s
The custom image provably carries /opt/hostedtoolcache/node/26.8.2/x64/bin/node
(ls inside the image confirms the layout, modes and the 150 MB binary), yet
setup-node still downloads. So the miss is runtime-only: either the runner is
not running that image or something shadows the path inside the job container.
This step prints mounts, the tool-cache listing, a direct node -v from the
baked path and the RUNNER_* env, then setup-node runs unchanged.

Temporary: remove once the cause is known.
2026-09-14 15:55:52 +00:00
tmu 1dfb979ebb 🚀 Release 0.1.3
CI / release-gate (push) Successful in 2s
CI / build (push) Successful in 43s
CI / maintain (push) Failing after 33s
CI / publish (push) Failing after 3s
2026-09-14 15:45:11 +00:00
tmu f04ad3d5bc 🔀 Merge chore/fix-ci into main 2026-09-14 15:43:57 +00:00
tmu 93cbfcf6b1 🐛 Expand the node base image through a named stage
CI / release-gate (pull_request) Successful in 2s
CI / build (pull_request) Successful in 37s
CI / publish (pull_request) Skipped
CI / maintain (pull_request) Failing after 34s
COPY --from= resolves its value as a stage name at parse time, before build
args exist, so COPY --from=node:${NODE_VERSION} collapsed to the invalid
'node:' and docker failed with 'failed to parse stage name'. ARGs in global
scope are expanded in FROM, so route through a named nodebase stage; the
per-stage ARG redeclaration keeps the tool-cache paths expanding.
2026-09-14 13:28:29 +00:00
tmu 3e33b51d1b 📝 Document CI runner-image bump ritual
build:runner-image broke the script prefix convention: build is a bare
single-tool command, and no tier fits a docker-daemon + registry-cred action,
so the script leaves package.json and is invoked directly. CONTRIBUTING gains
a 'CI runner image' section recording where the image pushes
(gitea.e1nsnull.de/tmu/act-ci:<version>), the .node-version coupling, and the
three-step Node-bump ritual.
2026-09-14 12:51:34 +00:00
tmu abbdf4410e 📝 Track CI Node-baking work in backlog
Record chore/fix-ci's two done steps and the remaining ops step (build/push
the image; first CI run is the acceptance test). Glyph/tag coupling honoured:
every ✔ line carries @done, open parent stays ☐.
2026-09-14 12:40:22 +00:00
tmu 245dfaf198 💚 Bake Node into the CI job image
setup-node never consults `node` on PATH; its only fast path is a probe of
/opt/hostedtoolcache, which the ephemeral act_runner job containers always
miss, so every job paid a ~50 MB Node download. docker/Dockerfile extends the
runner's default catthehacker/act image with the Node distribution overlaid at
the exact tool-cache layout, so setup-node finds 26.8.2 and skips the fetch
while node-version-file, cache: npm and registry-url keep working unchanged.

Image layers dedupe against the base the host already pulled and prune via
normal docker hygiene — the cleanup story a host bind of /opt/hostedtoolcache
lacks. To make the bake deterministic, .node-version is pinned to the exact
26.8.2 the image carries; scripts/runner-image.sh guards that coupling and
builds/pushes the tag the three node jobs now reference via container.image.

Ops follow-up (outside the repo): build once with
`npm run build:runner-image -- --push` on a machine with registry creds. If
the package is private, the runner needs container registry credentials in
its config.
2026-09-14 12:37:58 +00:00
tmu b9fe21175f 💚 Reuse npm cache in publish job
The publish job ran npm ci against a cold cache on every release while
build/maintain already share a warm node-cache key off the same lockfile.
Tag runs can read caches saved on main, so wiring cache: npm here is free.
2026-09-14 12:13:38 +00:00
tmu 5292455dbc 🚀 Release 0.1.2
CI / release-gate (push) Successful in 2s
CI / build (push) Successful in 36s
CI / maintain (push) Successful in 27s
CI / publish (push) Failing after 3s
2026-09-14 12:03:32 +00:00
tmu d1ef039688 🔀 Merge chore/dependency-updates into main 2026-09-14 12:02:51 +00:00
tmu c65f86e5d5 ⬆️ Upgrade dependencies 2026-09-14 12:02:27 +00:00
10 changed files with 380 additions and 190 deletions

No files matched your search

+58 -17
View File
@@ -49,15 +49,27 @@ jobs:
needs: release-gate needs: release-gate
if: needs.release-gate.outputs.skip != 'true' if: needs.release-gate.outputs.skip != 'true'
runs-on: ubuntu-latest runs-on: ubuntu-latest
# Bind-mount the shared pages tree so the coverage step below can write # `image` extends the runner's default job image (catthehacker/act)
# into it. The runner whitelists this path via `container.valid_volumes` # with Node 26 pre-planted in the tool cache layout, so setup-node's
# (docker-space `setup/gitea.sh`); `image` is omitted on purpose so the # version probe hits and never downloads (see docker/Dockerfile). The
# runner keeps using its default job image. # tag MUST equal the exact version pinned in `.node-version`; the bump
# ritual is documented in CONTRIBUTING.md § CI runner image. The volume
# bind-mounts the shared pages tree so the
# coverage step below can write into it; the runner whitelists this
# path via `container.valid_volumes` (docker-space `setup/gitea.sh`).
container: container:
image: gitea.e1nsnull.de/tmu/act-ci:26.8.2
volumes: volumes:
- /data/gitea-pages:/data/gitea-pages - /data/gitea-pages:/data/gitea-pages
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
# Fail fast when the job container is not the baked image: a stale
# tag on the runner (`forcePull=false` in its pull log) silently
# reintroduces the per-job download. Cheap, and it names the
# invariant.
- name: Assert the baked tool cache is present
run: |
test -f "/opt/hostedtoolcache/node/$(tr -d '[:space:]' < .node-version)/x64.complete"
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version-file: .node-version node-version-file: .node-version
@@ -108,6 +120,10 @@ jobs:
if: needs.release-gate.outputs.skip != 'true' if: needs.release-gate.outputs.skip != 'true'
runs-on: ubuntu-latest runs-on: ubuntu-latest
continue-on-error: true continue-on-error: true
# Same baked image as `build` — without it this job re-downloads Node
# per run (see docker/Dockerfile).
container:
image: gitea.e1nsnull.de/tmu/act-ci:26.8.2
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
@@ -121,24 +137,30 @@ jobs:
if: startsWith(gitea.ref, 'refs/tags/') if: startsWith(gitea.ref, 'refs/tags/')
needs: build needs: build
runs-on: ubuntu-latest runs-on: ubuntu-latest
# Same baked image as `build` — setup-node still owns the registry-url
# `.npmrc` rewrite here; only the Node download is skipped.
container:
image: gitea.e1nsnull.de/tmu/act-ci:26.8.2
# The release page is created with the run's automatic Gitea token # The release page is created with the run's automatic Gitea token
# (`github.token`), not `NPM_TOKEN`, so it needs `contents: write`. # (`github.token`), so it needs `contents: write`.
permissions: permissions:
contents: write contents: write
# The npm token is optional: `secrets` is not an allowed context in a
# step `if` (see GitHub's context-availability table), so it is lifted
# into job-level `env`, where an unset secret arrives as the empty
# string and skips the publish rather than attempting an unauthenticated
# one. Set NPM_TOKEN in the Gitea repo: Settings → Actions → Secrets.
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
steps: steps:
# Double-gate: publish only runs on a tag *and* aborts here if NPM_TOKEN
# is unset, so a tag push never silently no-ops (or half-publishes). Set
# NPM_TOKEN in the Gitea repo: Settings → Actions → Secrets.
- name: Assert NPM_TOKEN is configured
run: |
if [ -z "${{ secrets.NPM_TOKEN }}" ]; then
echo "::error::NPM_TOKEN secret is not set — refusing to publish."
exit 1
fi
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version-file: .node-version node-version-file: .node-version
# Same lockfile/key as `build`, and tag runs can read caches
# saved on `main` — without this, every release pays a cold
# `npm ci` despite the warm shared npm cache.
cache: "npm"
registry-url: "https://registry.npmjs.org/" registry-url: "https://registry.npmjs.org/"
- run: npm ci - run: npm ci
# Consume the dist/ that `build` produced and gated, instead of # Consume the dist/ that `build` produced and gated, instead of
@@ -159,9 +181,28 @@ jobs:
env: env:
TAG_REF: ${{ gitea.ref }} TAG_REF: ${{ gitea.ref }}
run: ./scripts/release-notes.sh "${TAG_REF#refs/tags/}" > release-notes.md run: ./scripts/release-notes.sh "${TAG_REF#refs/tags/}" > release-notes.md
- uses: https://gitea.com/actions/gitea-release-action@v1 - name: Create the Gitea release
id: gitea_release
uses: https://gitea.com/actions/gitea-release-action@v1
with: with:
body_path: release-notes.md body_path: release-notes.md
- run: npm publish --access public - name: Publish to npm
id: npm_publish
if: env.NPM_TOKEN != ''
run: npm publish --access public
env: env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} NODE_AUTH_TOKEN: ${{ env.NPM_TOKEN }}
# All-or-nothing: the tag is only released once *both* the release
# page and the npm package are up. A skipped npm publish (NPM_TOKEN
# unset) has no `success` outcome, so `always()` reaches this check
# even after a failure and turns the skipped half into an explicit
# red job instead of a silently green one.
- name: Require both releases
if: always()
run: |
GITEA="${{ steps.gitea_release.outcome }}"
NPM="${{ steps.npm_publish.outcome }}"
if [ "${GITEA}" != success ] || [ "${NPM}" != success ]; then
echo "::error::incomplete release — gitea=${GITEA:-skipped} npm=${NPM:-skipped}"
exit 1
fi
+1 -1
View File
@@ -1 +1 @@
26 26.8.2
+22 -1
View File
@@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
## [0.1.5] - 2026-09-15
- improve CI configuration
## [0.1.4] - 2026-09-14
- fix CI to node from custom image
- upgrade dependencies
## [0.1.3] - 2026-09-14
- change to custom image for CI
## [0.1.2] - 2026-09-14
- upgrade dependencies
## [0.1.1] - 2026-09-14 ## [0.1.1] - 2026-09-14
- upgrade dependencies - upgrade dependencies
@@ -15,6 +32,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- basic setup - basic setup
[Unreleased]: https://gitea.e1nsnull.de/tmu/tiny-pattern-ts/compare/0.1.1...main [Unreleased]: https://gitea.e1nsnull.de/tmu/tiny-pattern-ts/compare/0.1.5...main
[0.1.5]: https://gitea.e1nsnull.de/tmu/tiny-pattern-ts/compare/0.1.4...0.1.5
[0.1.4]: https://gitea.e1nsnull.de/tmu/tiny-pattern-ts/compare/0.1.3...0.1.4
[0.1.3]: https://gitea.e1nsnull.de/tmu/tiny-pattern-ts/compare/0.1.2...0.1.3
[0.1.2]: https://gitea.e1nsnull.de/tmu/tiny-pattern-ts/compare/0.1.1...0.1.2
[0.1.1]: https://gitea.e1nsnull.de/tmu/tiny-pattern-ts/compare/0.1.0...0.1.1 [0.1.1]: https://gitea.e1nsnull.de/tmu/tiny-pattern-ts/compare/0.1.0...0.1.1
[0.1.0]: https://gitea.e1nsnull.de/tmu/tiny-pattern-ts/compare/20308c5a6d8cccfb09b02ac2ebebd8055e91cd11...0.1.0 [0.1.0]: https://gitea.e1nsnull.de/tmu/tiny-pattern-ts/compare/20308c5a6d8cccfb09b02ac2ebebd8055e91cd11...0.1.0
+21 -2
View File
@@ -46,7 +46,7 @@ Separately, some top-level scripts are **bare** (no prefix): the entry points th
The tools are organized into a feedback ladder. Each tier catches different things at different costs; the rule of thumb is "earlier tiers fire more often, faster tiers catch less, slower tiers are more thorough": The tools are organized into a feedback ladder. Each tier catches different things at different costs; the rule of thumb is "earlier tiers fire more often, faster tiers catch less, slower tiers are more thorough":
| Tier | When | What it runs | Time | | Tier | When | What it runs | Time |
| -------------------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------- | ----- | | -------------------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
| `npm run watch` | manual | `watch:test` — re-runs tests on file save | ~0.1s | | `npm run watch` | manual | `watch:test` — re-runs tests on file save | ~0.1s |
| Pre-commit (auto) | on stage | tsc + oxlint + oxfmt + cspell (staged files only) | ~1.3s | | Pre-commit (auto) | on stage | tsc + oxlint + oxfmt + cspell (staged files only) | ~1.3s |
| Pre-push (auto) | on push | `npm test` (full tsc + unit tests) | ~3.5s | | Pre-push (auto) | on push | `npm test` (full tsc + unit tests) | ~3.5s |
@@ -56,7 +56,7 @@ The tools are organized into a feedback ladder. Each tier catches different thin
| `npm run maintain` | manual / CI (advisory) | `maintain:knip` + `maintain:outdated` (whole-project + network scans) | ~10s | | `npm run maintain` | manual / CI (advisory) | `maintain:knip` + `maintain:outdated` (whole-project + network scans) | ~10s |
| CI build (auto) | on push to `main` / tag | `build` job (build + correctness + packaging) — see [.gitea/workflows/ci.yml](./.gitea/workflows/ci.yml) | ~30s+ | | CI build (auto) | on push to `main` / tag | `build` job (build + correctness + packaging) — see [.gitea/workflows/ci.yml](./.gitea/workflows/ci.yml) | ~30s+ |
| CI maintain (auto, non-blocking) | on push to `main` | `npm run maintain` — reports, never fails the build | ~10s | | CI maintain (auto, non-blocking) | on push to `main` | `npm run maintain` — reports, never fails the build | ~10s |
| CI publish (auto) | on tag | Gitea release page (body from CHANGELOG) + `publish:publint` + `publish:attw`, then `npm publish` | ~15s | | CI publish (auto) | on tag | packaging checks + `publish:publint` / `publish:attw`, then the Gitea release page and `npm publish` (skipped, and the job failed, without `NPM_TOKEN`) | ~15s |
### Why these splits? ### Why these splits?
@@ -90,6 +90,23 @@ This is why every test in the suite pairs an `expectTypeOf(...)` with an `assert
- CI runs `npm run check` + `npm run test:ci` on every push to `main` — this is the authoritative gate. The one exception: a push headed by a release commit (`:rocket: Release x.y.z`) skips the full `build`/`maintain` jobs, because `create:release` pushes the tag for that exact commit right after and the tag run is the authoritative one (see `release-gate` in [.gitea/workflows/ci.yml](./.gitea/workflows/ci.yml)). - CI runs `npm run check` + `npm run test:ci` on every push to `main` — this is the authoritative gate. The one exception: a push headed by a release commit (`:rocket: Release x.y.z`) skips the full `build`/`maintain` jobs, because `create:release` pushes the tag for that exact commit right after and the tag run is the authoritative one (see `release-gate` in [.gitea/workflows/ci.yml](./.gitea/workflows/ci.yml)).
- **Releases are NOT triggered by pushes.** Only the maintainer triggers a release (see [Publishing workflow](#publishing-workflow)). - **Releases are NOT triggered by pushes.** Only the maintainer triggers a release (see [Publishing workflow](#publishing-workflow)).
## CI runner image
The `build` / `maintain` / `publish` jobs run in `gitea.e1nsnull.de/tmu/act-ci:<version>` ([docker/Dockerfile](./docker/Dockerfile)) — the runner's default act image with the Node distribution overlaid at the exact `/opt/hostedtoolcache` layout `actions/setup-node` probes before downloading, so no job pays the ~50 MB fetch. The image tag MUST equal the exact version pinned in `.node-version`; `release-gate` uses no Node and stays on the default image. The script is deliberately NOT an `npm run` script: building requires a docker daemon and registry credentials, so it belongs to no feedback tier — per [Script prefix convention](#script-prefix-convention), no existing prefix fits and that is the signal.
Bumping Node is one coordinated change, committed as a unit:
1. Edit `.node-version` to the new exact `x.y.z` — floats like `26` resolve to the latest patch at runtime and silently bust the baked entry; `scripts/runner-image.sh` refuses them.
2. `docker login gitea.e1nsnull.de` (user + package/access token), then `./scripts/runner-image.sh --push` — it reads the version from `.node-version` and builds/pushes `<IMAGE_REPO>:<version>`.
3. Repoint the three `container.image` tags in [.gitea/workflows/ci.yml](./.gitea/workflows/ci.yml) to the same version.
Skipping step 2 fails CI at image pull; skipping step 3 silently reverts to the per-job download.
Two invariants the image must satisfy for the probe to hit, both easy to break:
- **The `x64.complete` marker.** `actions/tool-cache` accepts a cached tool only when `<version>/<arch>.complete` exists next to the directory (`tc.find()` checks it); a plausible-looking `node/<version>/x64/` alone is ignored and the download happens anyway. See the comment in [docker/Dockerfile](./docker/Dockerfile).
- **Tag freshness.** The tag encodes only the Node version, so a Dockerfile change (like the marker above) produces _new content under an unchanged tag_. `act_runner` skips the pull when a tag of that name already exists locally (`forcePull=false` in the job log), so the runner must either force-pull (`force_pull` under `container:` in its `config.yaml`, if the installed version has it) or have the tag removed on the runner host (`docker rmi gitea.e1nsnull.de/tmu/act-ci:<version>`) after any image change. Symptom of getting this wrong: CI keeps running the previous image while the registry shows the new digest.
## Publishing workflow ## Publishing workflow
Publishing is CI-only by policy. Local `npm publish` is not supported. The maintainer triggers releases from `main`: Publishing is CI-only by policy. Local `npm publish` is not supported. The maintainer triggers releases from `main`:
@@ -98,3 +115,5 @@ Publishing is CI-only by policy. Local `npm publish` is not supported. The maint
2. The maintainer runs `npm run create:release`. VS Code opens `CHANGELOG.md` to finalize the `[Unreleased]` notes; because pubv refuses a dirty tree, any edit is committed first (then folded into the release commit), and pubv's interactive prompt suggests a version from those notes — the maintainer confirms or edits it. 2. The maintainer runs `npm run create:release`. VS Code opens `CHANGELOG.md` to finalize the `[Unreleased]` notes; because pubv refuses a dirty tree, any edit is committed first (then folded into the release commit), and pubv's interactive prompt suggests a version from those notes — the maintainer confirms or edits it.
3. `scripts/release.sh` creates a single release commit (graduated changelog + package.json bump, amended into one commit), tags it, and pushes everything to Gitea. 3. `scripts/release.sh` creates a single release commit (graduated changelog + package.json bump, amended into one commit), tags it, and pushes everything to Gitea.
4. CI fires on both pushes: the `publish` job runs on the tag (`build` + publish-tier checks + release page + `npm publish`), while the branch run's `release-gate` job recognizes the release commit and skips `build`/`maintain` — the tag verifies the identical SHA, so no work is duplicated. The job graph lives in [.gitea/workflows/ci.yml](./.gitea/workflows/ci.yml) — keep that file, not this list, as the source of truth. The publish-tier checks must pass before the artifact is published. The `publish` job also creates the Gitea release page from the matching Keep-a-Changelog section (`scripts/release-notes.sh`); it runs _before_ `npm publish` so a broken page fails CI without consuming a version, and `npm publish` stays the last step. 4. CI fires on both pushes: the `publish` job runs on the tag (`build` + publish-tier checks + release page + `npm publish`), while the branch run's `release-gate` job recognizes the release commit and skips `build`/`maintain` — the tag verifies the identical SHA, so no work is duplicated. The job graph lives in [.gitea/workflows/ci.yml](./.gitea/workflows/ci.yml) — keep that file, not this list, as the source of truth. The publish-tier checks must pass before the artifact is published. The `publish` job also creates the Gitea release page from the matching Keep-a-Changelog section (`scripts/release-notes.sh`); it runs _before_ `npm publish` so a broken page fails CI without consuming a version, and `npm publish` stays the last step.
The Gitea release page uses the run's automatic token (`github.token`), so it only needs `contents: write`. `npm publish` is gated on `NPM_TOKEN`, lifted into job-level `env` because `secrets` is not an allowed context in a step `if`: an unset secret skips the publish instead of attempting an unauthenticated one. A tag is all-or-nothing, though — a final `always()` step fails the job unless both the release page and `npm publish` reported `success`, so a skipped or failed npm half turns the job red rather than silently green. Set `NPM_TOKEN` (npm publish rights) under Settings → Actions → Secrets.
+17
View File
@@ -24,6 +24,7 @@ Bugs:
Enhancements: Enhancements:
Documentation: Documentation:
☐ Clean up CONTRIBUTING.md and README.md, create docs
☐ Add usage examples to README.md ☐ Add usage examples to README.md
☐ Create `examples/` directory with runnable snippets ☐ Create `examples/` directory with runnable snippets
☐ Add comparison section vs. other TS pattern-matching libs ☐ Add comparison section vs. other TS pattern-matching libs
@@ -45,3 +46,19 @@ Maintenance:
☐ Add a minimal dir-listing webserver to the gitea docker setup for serving landing page (reuse existing reverse proxy) ☐ Add a minimal dir-listing webserver to the gitea docker setup for serving landing page (reuse existing reverse proxy)
☐ CI writes landing page to a shared volume keyed by project + tag (e.g. `/landing/tiny-pattern-ts/<tag>/`) ☐ CI writes landing page to a shared volume keyed by project + tag (e.g. `/landing/tiny-pattern-ts/<tag>/`)
☐ Browse to `…/tiny-pattern-ts/index.html` in the browser ☐ Browse to `…/tiny-pattern-ts/index.html` in the browser
✔ Stop Gitea CI re-downloading Node on every job @done
✔ Share the warm npm cache with the publish job @done
✔ Bake Node into the CI job image (docker/Dockerfile, container.image in ci.yml) @done
✔ Build/push gitea.e1nsnull.de/tmu/act-ci:26.8.2 and confirm setup-node skips the download @done
✔ Write the `<version>/x64.complete` marker — actions/tool-cache ignores a bare directory, so the probe missed and the download continued @done
✔ Log tool-cache state from the job container to find it (temporary, removed once understood) @done
✔ Guard the invariant in CI (`Assert the baked tool cache is present`) @done
☐ Enable force-pull for the runner so a changed act-ci image is never missed @low
→ the tag encodes only the Node version, so a Dockerfile change yields new content under an unchanged tag; with `forcePull=false` the runner keeps the old image (see CONTRIBUTING § CI runner image)
✔ Improve CI publish @done
✔ Check whether publish job is only run on tags, if not, guard it @done
✔ Gate only single steps @done
✔ Do not publish to npm, if NPM_TOKEN is not set (e.g. PRs from forks) @done
✔ Do not publish to Gitea — uses the run's automatic `github.token`, so no secret gate is needed @done
✔ Otherwise run the steps @done
✔ Fail the job unless both the Gitea release and npm publish succeeded @done
+8
View File
@@ -27,6 +27,14 @@
"knope", "knope",
"runwisp", "runwisp",
"glab", "glab",
"hostedtoolcache",
"nodebase",
"frontends",
"catthehacker",
"nsnull",
"dedup",
"dedupe",
"repoint",
"postversion", "postversion",
"prebuild", "prebuild",
"Zilla", "Zilla",
+51
View File
@@ -0,0 +1,51 @@
# CI job image for the Gitea act_runner: the runner's default job image with
# Node pre-planted where actions/setup-node looks first.
#
# Why this layout: setup-node ignores `node` on PATH; its only fast path is a
# probe of /opt/hostedtoolcache/node/<version>/<arch>. Without an entry there
# it downloads the ~50 MB distribution on EVERY job (the runner's job
# containers are ephemeral, so its tool cache never survives a job). The
# official node images keep exactly the layout setup-node expects under
# /usr/local, so this layer is a pure file overlay — no scripts, no env.
#
# Why not a host bind of /opt/hostedtoolcache: binds never self-prune. Docker
# images are content-addressed: the base layers dedupe against the act image
# the host already has, and `docker image prune` / re-pulls are the cleanup
# story.
#
# NODE_VERSION must match `.node-version` exactly. setup-node resolves a float
# like `26` to the latest known patch at runtime, so a bump silently busts the
# baked entry; `.node-version` is pinned to x.y.z and scripts/runner-image.sh
# guards the coupling. Rebuild + repoint `container.image` in
# .gitea/workflows/ci.yml on every bump.
#
# The extra `nodebase` stage is load-bearing: `COPY --from=` resolves its value
# as a *stage name* at parse time, before build args exist, so
# `COPY --from=node:${NODE_VERSION}` collapses to the invalid `node:` on
# frontends that do not expand args there. ARGs declared before the first FROM
# *are* expanded in FROM, so routing through a named stage works everywhere.
# Global scope: only visible to FROM lines, but that is exactly where we need it.
ARG NODE_VERSION=26.8.2
FROM node:${NODE_VERSION} AS nodebase
FROM catthehacker/ubuntu:act-latest
# ARGs do not cross stage boundaries; redeclare (with the same default, so a
# bare `docker build -f docker/Dockerfile .` still works) for the paths below.
# Keep this default in sync with the global one above.
ARG NODE_VERSION=26.8.2
# node image: bin/ + lib/ under /usr/local → tool cache: bin/ + lib/ under <ver>/x64.
COPY --from=nodebase /usr/local /opt/hostedtoolcache/node/${NODE_VERSION}/x64
# actions/tool-cache only accepts a cached tool when the sibling marker file
# "<version>/<arch>.complete" exists — tc.find() checks it and falls back to
# downloading otherwise, however complete the directory is. The marker is what
# tc.cacheDir() writes after *it* installs a tool, so a pre-baked entry has to
# reproduce it explicitly.
RUN touch "/opt/hostedtoolcache/node/${NODE_VERSION}/x64.complete"
# Fail the build (not CI) if the overlay or the version arg were wrong.
# Shell form on purpose: exec form (`RUN [...]`) does not expand ARG values.
RUN "/opt/hostedtoolcache/node/${NODE_VERSION}/x64/bin/node" --version
+166 -166
View File
@@ -1,12 +1,12 @@
{ {
"name": "tiny-pattern-ts", "name": "tiny-pattern-ts",
"version": "0.1.1", "version": "0.1.5",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "tiny-pattern-ts", "name": "tiny-pattern-ts",
"version": "0.1.1", "version": "0.1.5",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@arethetypeswrong/cli": "^0.18.5", "@arethetypeswrong/cli": "^0.18.5",
@@ -20,8 +20,8 @@
"expect-type": "1.4.0", "expect-type": "1.4.0",
"knip": "^6.34.0", "knip": "^6.34.0",
"lefthook": "^2.1.12", "lefthook": "^2.1.12",
"oxfmt": "^0.66.0", "oxfmt": "^0.68.0",
"oxlint": "^1.81.0", "oxlint": "^1.83.0",
"oxlint-tsgolint": "^7.0.2001", "oxlint-tsgolint": "^7.0.2001",
"publint": "^0.3.24", "publint": "^0.3.24",
"typescript": "^7.0.2" "typescript": "^7.0.2"
@@ -1507,9 +1507,9 @@
] ]
}, },
"node_modules/@oxfmt/binding-android-arm-eabi": { "node_modules/@oxfmt/binding-android-arm-eabi": {
"version": "0.66.0", "version": "0.68.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm-eabi/-/binding-android-arm-eabi-0.66.0.tgz", "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm-eabi/-/binding-android-arm-eabi-0.68.0.tgz",
"integrity": "sha512-2Me9eoptv6ERdEuI2P8AOlYdHHraXebJaM6SC0kc2Dfb+mLrep2db+fedBPKaYn673h/vBgvP4tkOdAbaudX6w==", "integrity": "sha512-dhfYPbzv/h9JgHjNkl2R6sOjUfxDyLGOZVb3g8/ScaTNwwJcYgmHh8kcYFDUhinuy1QAoANCWUvw1jlk+z6gAg==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -1524,9 +1524,9 @@
} }
}, },
"node_modules/@oxfmt/binding-android-arm64": { "node_modules/@oxfmt/binding-android-arm64": {
"version": "0.66.0", "version": "0.68.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm64/-/binding-android-arm64-0.66.0.tgz", "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm64/-/binding-android-arm64-0.68.0.tgz",
"integrity": "sha512-u7O+bSSF0HGsDKkQQxBqvLGVepu93RA+JKu+ONqvfh4sCnCEbj31wZj4iG5gk3XfRwrmYj0/8catkO2LcblQKQ==", "integrity": "sha512-v3Njdi6qY0O/5eGfg01ww2w6gTn2mUvZ72Bnx1/UN53A9wruh3Nk6otc3WkgJLkXD4Qgz1SOcVQieH1oD03V9Q==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -1541,9 +1541,9 @@
} }
}, },
"node_modules/@oxfmt/binding-darwin-arm64": { "node_modules/@oxfmt/binding-darwin-arm64": {
"version": "0.66.0", "version": "0.68.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-arm64/-/binding-darwin-arm64-0.66.0.tgz", "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-arm64/-/binding-darwin-arm64-0.68.0.tgz",
"integrity": "sha512-/ikyMIVjX/sdo7KtjxoEsSUosfPzveVhT9RWMx9yGqFDKFJ89JAEKuEeLBmurDjrkb4w8tOnAdSO3SBaplY3bw==", "integrity": "sha512-ei4MCMzHFREmZwPJ7KuWUB4kBuHdsgDrnXGJVcEAopU7fj7S42I8BChdFILWdHvhFqR08FLJtOfbZIr2CDw0cA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -1558,9 +1558,9 @@
} }
}, },
"node_modules/@oxfmt/binding-darwin-x64": { "node_modules/@oxfmt/binding-darwin-x64": {
"version": "0.66.0", "version": "0.68.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-x64/-/binding-darwin-x64-0.66.0.tgz", "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-x64/-/binding-darwin-x64-0.68.0.tgz",
"integrity": "sha512-q5xUsKeFqawa9NXa6ZGXWimFV19m8MogKPdTaSVDAAk2EQKBmBZRDeluwcl1p8ty/OFc9s9888OKEh3xfPVH0g==", "integrity": "sha512-UrKgzZxYhwB9DSvTX+vdgl9M32wLUNKJcAKIoiyx/Kzn/zveqi7W6kYVcRroFMhS3Kwz0KhTk3WBeSuQn4YCTg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -1575,9 +1575,9 @@
} }
}, },
"node_modules/@oxfmt/binding-freebsd-x64": { "node_modules/@oxfmt/binding-freebsd-x64": {
"version": "0.66.0", "version": "0.68.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-freebsd-x64/-/binding-freebsd-x64-0.66.0.tgz", "resolved": "https://registry.npmjs.org/@oxfmt/binding-freebsd-x64/-/binding-freebsd-x64-0.68.0.tgz",
"integrity": "sha512-CR+x4VzMY0pRXLK/xFQ/RzsSFkP5t2Z2mef0QY6OP/rTRcMUoMLCOM62/3Fp/t0K+UDoBKxvMyeb6D0zPMjleA==", "integrity": "sha512-6jrEKgpJbilM1QaRv7hEtKXr4p4AK4jvvyOtajwyhu0kOz3e0O7OLnSTk6tBotRqCcUC4ehZRJ1Zx+Y99wieLw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -1592,9 +1592,9 @@
} }
}, },
"node_modules/@oxfmt/binding-linux-arm-gnueabihf": { "node_modules/@oxfmt/binding-linux-arm-gnueabihf": {
"version": "0.66.0", "version": "0.68.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.66.0.tgz", "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.68.0.tgz",
"integrity": "sha512-ZEYmO/LbH9tTQCADILHGZE4GeOXOAj2VzedHkASNwjmwlwtutJCLpCJbIs37wRGTFgWRoEcD72jpMX+IBJUGjQ==", "integrity": "sha512-YOIVnKOBaLeGullskS179N12hjSAdFYnzLjOaKiLhAKNWgnShq9w4xRdtmUm6BlnP65l2/EA9Aw/KlftNxDM7Q==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -1609,9 +1609,9 @@
} }
}, },
"node_modules/@oxfmt/binding-linux-arm-musleabihf": { "node_modules/@oxfmt/binding-linux-arm-musleabihf": {
"version": "0.66.0", "version": "0.68.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.66.0.tgz", "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.68.0.tgz",
"integrity": "sha512-hNtR9/oU0CeTkq7JnRkmBQwqe17v2ZaAMLC4VcN7IIOWeRyWDk0knSPWS9iiLmtbZ2RRBBtsG01jQgkZmKCJeQ==", "integrity": "sha512-xW5XoEHVNqydPBv2KXvk9lmEzyAlOQHVEazKoXUuAacqekjya+OdiaFjjEBl0oJD02raG8g3TRl9OVCh9PDIHA==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -1626,9 +1626,9 @@
} }
}, },
"node_modules/@oxfmt/binding-linux-arm64-gnu": { "node_modules/@oxfmt/binding-linux-arm64-gnu": {
"version": "0.66.0", "version": "0.68.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.66.0.tgz", "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.68.0.tgz",
"integrity": "sha512-uwOVQ8i6I1LT/+eDzfsgrrcZp8Fn6NPVUPn8fF5gdFGekFf0PddF+LEuwsD0/pbNUcKZhDj2rQ5UpITh9gF4iQ==", "integrity": "sha512-QCvYwVVQieu6oyJglAgV9vH/YMDxZyR4cwVSYtoq9oOXd5N+D3TDUBjNwxFrLn5AdcJZOcvn/7IB17vJGp+2Og==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -1646,9 +1646,9 @@
} }
}, },
"node_modules/@oxfmt/binding-linux-arm64-musl": { "node_modules/@oxfmt/binding-linux-arm64-musl": {
"version": "0.66.0", "version": "0.68.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.66.0.tgz", "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.68.0.tgz",
"integrity": "sha512-tTkF2Dmx4nGAjmBlZb+UtTGqR/EK4ZrW9qBfzte07a9XWqzoGGKzpFFlyNDhQe+Uwql94+ReCTeNbhOXscw1Dg==", "integrity": "sha512-4TVz5iFQ8ndrHnhX50UXiz9BIWAtUSOHJ6Nus4qWFfJBXq/Ed/krXbF/ehJu42BXM5tIvBs99jNIM22s9agY5A==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -1666,9 +1666,9 @@
} }
}, },
"node_modules/@oxfmt/binding-linux-ppc64-gnu": { "node_modules/@oxfmt/binding-linux-ppc64-gnu": {
"version": "0.66.0", "version": "0.68.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.66.0.tgz", "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.68.0.tgz",
"integrity": "sha512-F3cKHUav4yXOHn6GFnwpBhSYsJOYKKf9eqO/9jlEuqPxNw9zb98E9ZFct79gcg8pibUGkbveEu9WDlmXJpDzKw==", "integrity": "sha512-qLe3ao0RP84bnPxBvRI+GnlK/jybo538NWu0Xrm+zYeTmJtpzqLhnnd5BH21NafqKnplbGZjtN1cnrOlWF73lw==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@@ -1686,9 +1686,9 @@
} }
}, },
"node_modules/@oxfmt/binding-linux-riscv64-gnu": { "node_modules/@oxfmt/binding-linux-riscv64-gnu": {
"version": "0.66.0", "version": "0.68.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.66.0.tgz", "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.68.0.tgz",
"integrity": "sha512-K5fDaNZfDyQMYA/3qL21bqyN0X9T15LLwwbFPt2aHc94+ZG7bh0vZEsy2y7NlRnjjHFSwN+Hzg6ldJtbOriH4Q==", "integrity": "sha512-Yvyl7a6gbb0vM6r925KW2dO+/CmXySO5TVbcX7o/uZJ+d108HFOG0TxIyHApmn5USuj5mhDPxzhiVwOlGP7uSA==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@@ -1706,9 +1706,9 @@
} }
}, },
"node_modules/@oxfmt/binding-linux-riscv64-musl": { "node_modules/@oxfmt/binding-linux-riscv64-musl": {
"version": "0.66.0", "version": "0.68.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.66.0.tgz", "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.68.0.tgz",
"integrity": "sha512-44Yc+I+qOmTElRcEhm5hUKIUJEQIOugymz4ua4tB0Wox7tGAfIbjzmXz/HDAtw1Ij6gmBwZlzh4hc9679RhWeA==", "integrity": "sha512-mJlFuFVCxzrYM5sFStN433D/s/mb6Wq4aCQAM02vs/OudHywnaSAd2rb1vlYUJtqdYIciJtiasuxvfbYkv5fLg==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@@ -1726,9 +1726,9 @@
} }
}, },
"node_modules/@oxfmt/binding-linux-s390x-gnu": { "node_modules/@oxfmt/binding-linux-s390x-gnu": {
"version": "0.66.0", "version": "0.68.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.66.0.tgz", "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.68.0.tgz",
"integrity": "sha512-1e29Eg9hEj2kRBB19M0seIehPbbXHCk35GvImjDvb79rjjYjXCRmtbUNHJcgoktZAMIzXrTbxDBKmTc1V4bg3A==", "integrity": "sha512-RlfSg++qs1hbKltRR6lYvV9EoI3MdlfSQD9w1hdHVYjHqjIn1tkH4FWOpMSmjKGN20zr+nI+W9o4ARogCDudGQ==",
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
@@ -1746,9 +1746,9 @@
} }
}, },
"node_modules/@oxfmt/binding-linux-x64-gnu": { "node_modules/@oxfmt/binding-linux-x64-gnu": {
"version": "0.66.0", "version": "0.68.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.66.0.tgz", "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.68.0.tgz",
"integrity": "sha512-vODY1UQo10gngn0+D4xHKU84F1Twm1LqrzV4SqPXvmQKSd87paehvZ6jqA5wKs6XQrlWul9clYMDVHcoW9CPMA==", "integrity": "sha512-nyzRB9U+dlYUKu3pMo3afHzZBUv/oTHZMG36ZfJViNVfOIzp70Q4GS8FFRGgYJ/p0zcyDCgpBvYISOdJOMh+jQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -1766,9 +1766,9 @@
} }
}, },
"node_modules/@oxfmt/binding-linux-x64-musl": { "node_modules/@oxfmt/binding-linux-x64-musl": {
"version": "0.66.0", "version": "0.68.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-musl/-/binding-linux-x64-musl-0.66.0.tgz", "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-musl/-/binding-linux-x64-musl-0.68.0.tgz",
"integrity": "sha512-YDzXx2JsT4+HL4MdkVrYjO55NS5lUKNm8rLC4ZPou8+seu0v0jhecSh+ufoO6+xEa8gccEezMlI2WHJi4ApUgw==", "integrity": "sha512-iCx3sbZRIvGrL1RafphEiUKBaW1lc0/tAjKOIB/Wjw2+STRBEdu5+fH1Gc1faEWEmc2k5Ks4iUUV54Zd5C9a1A==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -1786,9 +1786,9 @@
} }
}, },
"node_modules/@oxfmt/binding-openharmony-arm64": { "node_modules/@oxfmt/binding-openharmony-arm64": {
"version": "0.66.0", "version": "0.68.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-openharmony-arm64/-/binding-openharmony-arm64-0.66.0.tgz", "resolved": "https://registry.npmjs.org/@oxfmt/binding-openharmony-arm64/-/binding-openharmony-arm64-0.68.0.tgz",
"integrity": "sha512-mJjUYd8lj0+j4JkYyEM+5qKBf1Rnrpgjn/SVYKJhicVDqLz566ooa7Fs8zflPqt+dnZDV7X054rVIQX6ZcQNlQ==", "integrity": "sha512-x2X5AZez7OgyLLFpwIgItoXBUqudDM7yiaTsxv8R8vKQ6e81l0jVw0NFeUCXzcl1sAJq8h+tC8N4mY8EiMeL4w==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -1803,9 +1803,9 @@
} }
}, },
"node_modules/@oxfmt/binding-win32-arm64-msvc": { "node_modules/@oxfmt/binding-win32-arm64-msvc": {
"version": "0.66.0", "version": "0.68.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.66.0.tgz", "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.68.0.tgz",
"integrity": "sha512-soV+0vESv7e5ntCHWC61x4gg8OSak6IHHnWsZmHrJFlvMj2AK+kmldErCNkVkrvc1Ts2/++rJXn+IuAb2WMXhw==", "integrity": "sha512-AHVPjXkenLPQUh6kB8zSC8pX2ct9r4T1Edk9r/RNJyov6wPsS5uAfYtipwG4chn6+3bPFG5rI/3DxEeH8vib1w==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -1820,9 +1820,9 @@
} }
}, },
"node_modules/@oxfmt/binding-win32-ia32-msvc": { "node_modules/@oxfmt/binding-win32-ia32-msvc": {
"version": "0.66.0", "version": "0.68.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.66.0.tgz", "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.68.0.tgz",
"integrity": "sha512-YCPi23uRIEYuIKTZohAkKbPFpujQ5QBuUM5iDv+UqbCmTPAkaFsxjsSuB8xlBpRT0G7eP/4HMF+cPDSqHtOD9A==", "integrity": "sha512-n09SjEk5VH7z8Hl4WVP7hho+cCwGViENkQFiM45vbW85dJd7kEhWaHRUobaPzEmrWyu6uumd4EuNfNyDKLtzDA==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@@ -1837,9 +1837,9 @@
} }
}, },
"node_modules/@oxfmt/binding-win32-x64-msvc": { "node_modules/@oxfmt/binding-win32-x64-msvc": {
"version": "0.66.0", "version": "0.68.0",
"resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.66.0.tgz", "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.68.0.tgz",
"integrity": "sha512-bwTQcv/JVRPkOqQtMF0X7vpvpncDQiBcXHxZ9S2hR12Hlo8bvBdUR5x5XnxzDZ3kM0qoZw1rv7KaD66Ly+pFWA==", "integrity": "sha512-gPe+dJLXaPuWPWqlpklDAJp0k+K9KhQPYiQLHfb+i2rmFuUGfJ/5Qlj6tr1mO6of5g0DiLjG/XCFHIaPhotqqA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -1938,9 +1938,9 @@
] ]
}, },
"node_modules/@oxlint/binding-android-arm-eabi": { "node_modules/@oxlint/binding-android-arm-eabi": {
"version": "1.82.0", "version": "1.83.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.82.0.tgz", "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.83.0.tgz",
"integrity": "sha512-a3LB+C5Dsj5b/qtmG/mv5WrzuiXEpg1KF5nXWcEvaoN5TYAqkIvxPOwTPp3Jy/FoGpRo8zsTFhMElMXfeoOEzA==", "integrity": "sha512-0yGY24EwsLk5YDe6F+VkmZyRHSwJDALa3nIrPpq7FXmp2lV2d0TzvBCGeZk+wgiULRGr5blhyr4QMp5KCXJUqA==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -1955,9 +1955,9 @@
} }
}, },
"node_modules/@oxlint/binding-android-arm64": { "node_modules/@oxlint/binding-android-arm64": {
"version": "1.82.0", "version": "1.83.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm64/-/binding-android-arm64-1.82.0.tgz", "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm64/-/binding-android-arm64-1.83.0.tgz",
"integrity": "sha512-OBlhRgNqFblGpGenno/aqOfJLOkQ2B8Ig3iDAalfn0H8hJGZKXPeexCRTDm6uwv6YUjSA9Xnwt1y/Bgj5ZH8uw==", "integrity": "sha512-hHfJ0vc17A4iUjH5p9BsTUPYbYRNxGpvD2lbu1aBRk54bzNIx9o5TtYF39QPZcV95DagZd+4DEAw2RH3G2ZsMg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -1972,9 +1972,9 @@
} }
}, },
"node_modules/@oxlint/binding-darwin-arm64": { "node_modules/@oxlint/binding-darwin-arm64": {
"version": "1.82.0", "version": "1.83.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-arm64/-/binding-darwin-arm64-1.82.0.tgz", "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-arm64/-/binding-darwin-arm64-1.83.0.tgz",
"integrity": "sha512-dsopxqtY5ZdyT9uLHyGt1SyiLop6hi7hWI3PKpePodkRQOkLaCm+OE4fR9CAz9qdfjiFO8531tX/QDyP/psjFg==", "integrity": "sha512-hsOjYjszLb/3zym/TkzUMPAoQlTJcuzSyEPOAyA+skXJIX9M0o+4JfOtqopX/Vf4hSLrJ98j0nvFo23gzk8auQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -1989,9 +1989,9 @@
} }
}, },
"node_modules/@oxlint/binding-darwin-x64": { "node_modules/@oxlint/binding-darwin-x64": {
"version": "1.82.0", "version": "1.83.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-x64/-/binding-darwin-x64-1.82.0.tgz", "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-x64/-/binding-darwin-x64-1.83.0.tgz",
"integrity": "sha512-94Lu0SgTClKColU66g1VDuigV3HkcbkJBnTtZjGYfE8UPugaWDgKrm2icjC6HJVUYler2OXaHP/X0TBy8+CowQ==", "integrity": "sha512-mjh5oH2EA+wl5yRJYT9K9G61O2zFlpuv+yf2JwZOi0+dq2FnTUtm1h8i+5Ik0fXPWIu/k84I1psZR9aQsLAnyA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -2006,9 +2006,9 @@
} }
}, },
"node_modules/@oxlint/binding-freebsd-x64": { "node_modules/@oxlint/binding-freebsd-x64": {
"version": "1.82.0", "version": "1.83.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-freebsd-x64/-/binding-freebsd-x64-1.82.0.tgz", "resolved": "https://registry.npmjs.org/@oxlint/binding-freebsd-x64/-/binding-freebsd-x64-1.83.0.tgz",
"integrity": "sha512-hne/V06ewhh1i0w8+l7GDNROAGCGPmyFuOwiP7YTRu0JycyStJ4785dmF8xU5p0uUwt2emvIF9vc7Xjis+cJ0g==", "integrity": "sha512-fNHr64/YaO8YssuoDVC8+F4Uk5enR86q5uxfHkQrjAPs1dbAILOrD2uaud+J7MO8Fx774g44ERLD0IGIvZE48w==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -2023,9 +2023,9 @@
} }
}, },
"node_modules/@oxlint/binding-linux-arm-gnueabihf": { "node_modules/@oxlint/binding-linux-arm-gnueabihf": {
"version": "1.82.0", "version": "1.83.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.82.0.tgz", "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.83.0.tgz",
"integrity": "sha512-aWY2xtbZf1LneW9Qsv/n2Sp8gOu74JrlQzEtj4coHX2SHFrCfhmAumaU+sI/A5nr+yoTRTSmI/pL2s6ADlNSkw==", "integrity": "sha512-Qpwy3zzAwMj+8/lyYItHmkSMwbkprFNWTK7jPYDOxSyxEhaSLOWYUTCMkjF334J8/WD0nznCCsoBbIH6hpsuIw==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -2040,9 +2040,9 @@
} }
}, },
"node_modules/@oxlint/binding-linux-arm-musleabihf": { "node_modules/@oxlint/binding-linux-arm-musleabihf": {
"version": "1.82.0", "version": "1.83.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-1.82.0.tgz", "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-1.83.0.tgz",
"integrity": "sha512-Fe+TtXCXMh/5f7kWlZ2VAwsMumZWtraFlKVk1NJlL52/beGwfDE7ov+/8gVirHzWokzGu7X65hSPq0ucPDskWQ==", "integrity": "sha512-s+BirYLFq7JL2k9sP0XI3ZXJ9dYvJ8sX3jLCLoag7tt+zrSHpZxP0jqznfL+Gdgwu7ay0dYgGYJXrQvq3iWloA==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -2057,9 +2057,9 @@
} }
}, },
"node_modules/@oxlint/binding-linux-arm64-gnu": { "node_modules/@oxlint/binding-linux-arm64-gnu": {
"version": "1.82.0", "version": "1.83.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.82.0.tgz", "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.83.0.tgz",
"integrity": "sha512-6azCZ6OJudlvipNttXCCQcyeFfcJ/NvUZdSN1z8elo73kCHtyQC7WTiUcSjWYvJ1jaq9KDUyMAoAS/vNzhBomA==", "integrity": "sha512-7lihXt3vKr+GIyapNbHrnFHm/biiW30le6Zv/DExbAFPF6YwCQXVFlONPFehxs0CpGO4CBfYPM9rdDT+XMoIlg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -2077,9 +2077,9 @@
} }
}, },
"node_modules/@oxlint/binding-linux-arm64-musl": { "node_modules/@oxlint/binding-linux-arm64-musl": {
"version": "1.82.0", "version": "1.83.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.82.0.tgz", "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.83.0.tgz",
"integrity": "sha512-PLEaSD8IAIIlwW4dwOd9YaxuxeOpwiXL4J24rcnE4iNtyM5j9Q9/3+gti08oXpx0u2ygNjRDx9xjWWpQonuJEw==", "integrity": "sha512-q63JalLYVkZiZvls1z3PPUnpmQluOMXp0khqQMznCeAPLGydfNY8JhvuA4WlK57JfrvikU8wB5lPVveqpIXvew==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -2097,9 +2097,9 @@
} }
}, },
"node_modules/@oxlint/binding-linux-ppc64-gnu": { "node_modules/@oxlint/binding-linux-ppc64-gnu": {
"version": "1.82.0", "version": "1.83.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.82.0.tgz", "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.83.0.tgz",
"integrity": "sha512-D94em/BwknNTn4vqxjHh5wb2oL566eFhArabqKIr0cNZMHOJuiraFp1A8tXpH05bbE5tqwEfLXTI0MWEGtn3Dw==", "integrity": "sha512-krQmDF+dRbxvdqVPV88ZuOoPPu8X5BuqDA8Hd+qcS4YMRQCb+nexA57DazgGsc/rGdKBe3QmV0mnv0bdpW/p5g==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@@ -2117,9 +2117,9 @@
} }
}, },
"node_modules/@oxlint/binding-linux-riscv64-gnu": { "node_modules/@oxlint/binding-linux-riscv64-gnu": {
"version": "1.82.0", "version": "1.83.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-1.82.0.tgz", "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-1.83.0.tgz",
"integrity": "sha512-MOprxBaoYU2D4VgxXCl3ghydThWtx7Um1lL51kGYNeQ5Al7WzsH7/tqGdNtbLrIWnjq3bsm13+nz/gRIxjrOXw==", "integrity": "sha512-MmOl8Y6txEAXZU1RG8Rr264jQ6D7VPmqFsU/45x/FeWsGe32hklTqGrLE6UxHzp5Rjt0wP+20tY8YXKgSFB3mw==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@@ -2137,9 +2137,9 @@
} }
}, },
"node_modules/@oxlint/binding-linux-riscv64-musl": { "node_modules/@oxlint/binding-linux-riscv64-musl": {
"version": "1.82.0", "version": "1.83.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-1.82.0.tgz", "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-1.83.0.tgz",
"integrity": "sha512-5h55QsfJ/luDXZzC20k6SNOY1Az+dCP9WvntKtcUWh2JhckAdwApY2ZusaBTwLENnReXU+A2fJtSrYvZJNKNPg==", "integrity": "sha512-u1rMymh0W3JZkq370kzQsYPULGWqhE09pZRqnZvUSoYaI9pVO5yVX+iYIslmWuEgwuzH9YAaOsScJiobWCHoOw==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@@ -2157,9 +2157,9 @@
} }
}, },
"node_modules/@oxlint/binding-linux-s390x-gnu": { "node_modules/@oxlint/binding-linux-s390x-gnu": {
"version": "1.82.0", "version": "1.83.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.82.0.tgz", "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.83.0.tgz",
"integrity": "sha512-IE8NJNLlHr0CaXyGJPGVn0eTkUyoj1I2UfA8x7I4PSOYKsQ/6btVC7Pywrj5onk0cMH25r6Z38SoN3AvE5Zuog==", "integrity": "sha512-y0zK3HNwGysu7rqtE+BQG/d0bx5gh/KwlOtghN8oWeK1KcWzeaLqtZrbm8owqdma1lFyrce/hTO5ismuNu+INQ==",
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
@@ -2177,9 +2177,9 @@
} }
}, },
"node_modules/@oxlint/binding-linux-x64-gnu": { "node_modules/@oxlint/binding-linux-x64-gnu": {
"version": "1.82.0", "version": "1.83.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.82.0.tgz", "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.83.0.tgz",
"integrity": "sha512-XUUUxaBo9XKl+J1B9EmP1cTGQPddzeURvoGkfwh/94PGnbW+hBprDljneoI2M1jzC1bzrIV3ihc7iM9UXl8+tg==", "integrity": "sha512-rS5gM0NgD7ngmuJmbIehsidtrOwKkLFwCQbKEeb9KuyQrrWNq5Zkn0uV6AYdXOMJ0grrWEiLwBuvMxt8w5vsNw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -2197,9 +2197,9 @@
} }
}, },
"node_modules/@oxlint/binding-linux-x64-musl": { "node_modules/@oxlint/binding-linux-x64-musl": {
"version": "1.82.0", "version": "1.83.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-musl/-/binding-linux-x64-musl-1.82.0.tgz", "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-musl/-/binding-linux-x64-musl-1.83.0.tgz",
"integrity": "sha512-SWLSFulX9TDuH6yvbPYp4+VNn6jkkIvvI+KiujDM5rWBRHEfkesCC/pCneIIUr6ovkxZ5fRtpi2v5Cz5FrMJZg==", "integrity": "sha512-W2IH4EtpcPaWcvNGCA95YoDg4vxqE/ZiPCi3arrxEEpsK7+JQN9WYwrlYFx9pcdP6KPXqRqkv3zdQPHcx7b6YQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -2217,9 +2217,9 @@
} }
}, },
"node_modules/@oxlint/binding-openharmony-arm64": { "node_modules/@oxlint/binding-openharmony-arm64": {
"version": "1.82.0", "version": "1.83.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-openharmony-arm64/-/binding-openharmony-arm64-1.82.0.tgz", "resolved": "https://registry.npmjs.org/@oxlint/binding-openharmony-arm64/-/binding-openharmony-arm64-1.83.0.tgz",
"integrity": "sha512-BQy35f6ZUdNr9a6c7B7orxQTcLjByGT2z3WAgmRovpRwmPYAaJ+NTplmMzhdjdJ4qSchfMNZy/Ukg+qRg6zseQ==", "integrity": "sha512-6LyKkUyoajssTPLlZmDbZIbu4IZ5B4bGuRUnBgCGpEvHP3FQMaYITncHA/unPUo7q+Z+pIu2HhdkQ+8d1SG7iA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -2234,9 +2234,9 @@
} }
}, },
"node_modules/@oxlint/binding-win32-arm64-msvc": { "node_modules/@oxlint/binding-win32-arm64-msvc": {
"version": "1.82.0", "version": "1.83.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.82.0.tgz", "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.83.0.tgz",
"integrity": "sha512-V4QhSTg5gctZue8RJjsGi7NpQPThr/p1/HfmiMC5kfe1KFEup9SQRVub4A6kijQjdHfxj7bLL1KO3QO7/5bwMQ==", "integrity": "sha512-Uz/fObEtF0jmNJQJ8CGRBKfefYstS0/wjD3s6IGzP8nUwsJykHQJBiN3npHwKiGRGn/vvBEgNr4B3cCzmmatvg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -2251,9 +2251,9 @@
} }
}, },
"node_modules/@oxlint/binding-win32-ia32-msvc": { "node_modules/@oxlint/binding-win32-ia32-msvc": {
"version": "1.82.0", "version": "1.83.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.82.0.tgz", "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.83.0.tgz",
"integrity": "sha512-TUSCLaKB2yktpFAJ/r3HAUYsaV/3DT7JS4iNKyoh3a9YNwD0UG7Ezh4D8m23654vQcU6P/RQrCAjRPKe4peP/A==", "integrity": "sha512-u7XcvPW6Bk58tY5iWs2ESb0vJjoE/kuSpHxopbwp/p3ZtWVQXZ6wor5w3ssVTHOqd/v8b+QdhSFWQ4grEUNWpA==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@@ -2268,9 +2268,9 @@
} }
}, },
"node_modules/@oxlint/binding-win32-x64-msvc": { "node_modules/@oxlint/binding-win32-x64-msvc": {
"version": "1.82.0", "version": "1.83.0",
"resolved": "https://registry.npmjs.org/@oxlint/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.82.0.tgz", "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.83.0.tgz",
"integrity": "sha512-VTVoRIWJTb+wvUX8EYoPArfFH02whuR10goFXE/LHRRX33ajRrFgqbcONXZMiF4C5rnattfkm87HqYn8jb8hmQ==", "integrity": "sha512-LZRubd7ph13QmAg4fFecTYVZkiYbROR2Htaxh/ufWRkDhPOm2wrwaEYR89e0YpPFD3dqBrPoxS7myBw5hmYA7Q==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -4171,13 +4171,13 @@
} }
}, },
"node_modules/oxfmt": { "node_modules/oxfmt": {
"version": "0.66.0", "version": "0.68.0",
"resolved": "https://registry.npmjs.org/oxfmt/-/oxfmt-0.66.0.tgz", "resolved": "https://registry.npmjs.org/oxfmt/-/oxfmt-0.68.0.tgz",
"integrity": "sha512-FfvqR8RFtV6JJpRrpkfqyVCQ7HDvZ/VriWFx7veftCgL1B5ZO9qNr+1rvPieycMQnNfVG0PWyJQiy7p0hq1I5w==", "integrity": "sha512-Z0XMofcXCGUXbcpBHnWyUiX93BGiw1B+lcHNbQDWEtOhX06ewoFfu4zXkyiLhRrNnMq0twqXRHUcJetf+GsiQQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"tinypool": "2.1.0" "tinypool": "2.1.2"
}, },
"bin": { "bin": {
"oxfmt": "bin/oxfmt" "oxfmt": "bin/oxfmt"
@@ -4189,25 +4189,25 @@
"url": "https://github.com/sponsors/oxc-project" "url": "https://github.com/sponsors/oxc-project"
}, },
"optionalDependencies": { "optionalDependencies": {
"@oxfmt/binding-android-arm-eabi": "0.66.0", "@oxfmt/binding-android-arm-eabi": "0.68.0",
"@oxfmt/binding-android-arm64": "0.66.0", "@oxfmt/binding-android-arm64": "0.68.0",
"@oxfmt/binding-darwin-arm64": "0.66.0", "@oxfmt/binding-darwin-arm64": "0.68.0",
"@oxfmt/binding-darwin-x64": "0.66.0", "@oxfmt/binding-darwin-x64": "0.68.0",
"@oxfmt/binding-freebsd-x64": "0.66.0", "@oxfmt/binding-freebsd-x64": "0.68.0",
"@oxfmt/binding-linux-arm-gnueabihf": "0.66.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.68.0",
"@oxfmt/binding-linux-arm-musleabihf": "0.66.0", "@oxfmt/binding-linux-arm-musleabihf": "0.68.0",
"@oxfmt/binding-linux-arm64-gnu": "0.66.0", "@oxfmt/binding-linux-arm64-gnu": "0.68.0",
"@oxfmt/binding-linux-arm64-musl": "0.66.0", "@oxfmt/binding-linux-arm64-musl": "0.68.0",
"@oxfmt/binding-linux-ppc64-gnu": "0.66.0", "@oxfmt/binding-linux-ppc64-gnu": "0.68.0",
"@oxfmt/binding-linux-riscv64-gnu": "0.66.0", "@oxfmt/binding-linux-riscv64-gnu": "0.68.0",
"@oxfmt/binding-linux-riscv64-musl": "0.66.0", "@oxfmt/binding-linux-riscv64-musl": "0.68.0",
"@oxfmt/binding-linux-s390x-gnu": "0.66.0", "@oxfmt/binding-linux-s390x-gnu": "0.68.0",
"@oxfmt/binding-linux-x64-gnu": "0.66.0", "@oxfmt/binding-linux-x64-gnu": "0.68.0",
"@oxfmt/binding-linux-x64-musl": "0.66.0", "@oxfmt/binding-linux-x64-musl": "0.68.0",
"@oxfmt/binding-openharmony-arm64": "0.66.0", "@oxfmt/binding-openharmony-arm64": "0.68.0",
"@oxfmt/binding-win32-arm64-msvc": "0.66.0", "@oxfmt/binding-win32-arm64-msvc": "0.68.0",
"@oxfmt/binding-win32-ia32-msvc": "0.66.0", "@oxfmt/binding-win32-ia32-msvc": "0.68.0",
"@oxfmt/binding-win32-x64-msvc": "0.66.0" "@oxfmt/binding-win32-x64-msvc": "0.68.0"
}, },
"peerDependencies": { "peerDependencies": {
"svelte": "^5.0.0", "svelte": "^5.0.0",
@@ -4223,9 +4223,9 @@
} }
}, },
"node_modules/oxlint": { "node_modules/oxlint": {
"version": "1.82.0", "version": "1.83.0",
"resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.82.0.tgz", "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.83.0.tgz",
"integrity": "sha512-+iFM1BGw1ntYJt3QngbJmjbrGxPaKMUADOXOijpWGnYcBPq8YZnQftSS1C+pVcDYy9YxqDVJKQqQkTazTQMboQ==", "integrity": "sha512-cyDzSzaw3uzP0TeCeq3lLRPPoaUxkbB4ZOXj+kn+5r+BX9V+4bNVGk9lxer+WrgcpebH4JxLlJ3KQjveVztOLQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"bin": { "bin": {
@@ -4238,25 +4238,25 @@
"url": "https://github.com/sponsors/oxc-project" "url": "https://github.com/sponsors/oxc-project"
}, },
"optionalDependencies": { "optionalDependencies": {
"@oxlint/binding-android-arm-eabi": "1.82.0", "@oxlint/binding-android-arm-eabi": "1.83.0",
"@oxlint/binding-android-arm64": "1.82.0", "@oxlint/binding-android-arm64": "1.83.0",
"@oxlint/binding-darwin-arm64": "1.82.0", "@oxlint/binding-darwin-arm64": "1.83.0",
"@oxlint/binding-darwin-x64": "1.82.0", "@oxlint/binding-darwin-x64": "1.83.0",
"@oxlint/binding-freebsd-x64": "1.82.0", "@oxlint/binding-freebsd-x64": "1.83.0",
"@oxlint/binding-linux-arm-gnueabihf": "1.82.0", "@oxlint/binding-linux-arm-gnueabihf": "1.83.0",
"@oxlint/binding-linux-arm-musleabihf": "1.82.0", "@oxlint/binding-linux-arm-musleabihf": "1.83.0",
"@oxlint/binding-linux-arm64-gnu": "1.82.0", "@oxlint/binding-linux-arm64-gnu": "1.83.0",
"@oxlint/binding-linux-arm64-musl": "1.82.0", "@oxlint/binding-linux-arm64-musl": "1.83.0",
"@oxlint/binding-linux-ppc64-gnu": "1.82.0", "@oxlint/binding-linux-ppc64-gnu": "1.83.0",
"@oxlint/binding-linux-riscv64-gnu": "1.82.0", "@oxlint/binding-linux-riscv64-gnu": "1.83.0",
"@oxlint/binding-linux-riscv64-musl": "1.82.0", "@oxlint/binding-linux-riscv64-musl": "1.83.0",
"@oxlint/binding-linux-s390x-gnu": "1.82.0", "@oxlint/binding-linux-s390x-gnu": "1.83.0",
"@oxlint/binding-linux-x64-gnu": "1.82.0", "@oxlint/binding-linux-x64-gnu": "1.83.0",
"@oxlint/binding-linux-x64-musl": "1.82.0", "@oxlint/binding-linux-x64-musl": "1.83.0",
"@oxlint/binding-openharmony-arm64": "1.82.0", "@oxlint/binding-openharmony-arm64": "1.83.0",
"@oxlint/binding-win32-arm64-msvc": "1.82.0", "@oxlint/binding-win32-arm64-msvc": "1.83.0",
"@oxlint/binding-win32-ia32-msvc": "1.82.0", "@oxlint/binding-win32-ia32-msvc": "1.83.0",
"@oxlint/binding-win32-x64-msvc": "1.82.0" "@oxlint/binding-win32-x64-msvc": "1.83.0"
}, },
"peerDependencies": { "peerDependencies": {
"oxlint-tsgolint": ">=7.0.2001", "oxlint-tsgolint": ">=7.0.2001",
@@ -4696,9 +4696,9 @@
} }
}, },
"node_modules/tinypool": { "node_modules/tinypool": {
"version": "2.1.0", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/tinypool/-/tinypool-2.1.0.tgz", "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-2.1.2.tgz",
"integrity": "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==", "integrity": "sha512-9YodfrxS9g9IbFr/KOjE5bAeJ0p61n3bW6mqvy0jtoeKd1kTW1Cxm0oulm6KX2lyM9Gl6WIe8nEbY7LWv5ZJww==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
+3 -3
View File
@@ -1,6 +1,6 @@
{ {
"name": "tiny-pattern-ts", "name": "tiny-pattern-ts",
"version": "0.1.1", "version": "0.1.5",
"description": "Pattern matching for TypeScript/ESM environments (F#-style, not regex)", "description": "Pattern matching for TypeScript/ESM environments (F#-style, not regex)",
"keywords": [ "keywords": [
"adt", "adt",
@@ -77,8 +77,8 @@
"expect-type": "1.4.0", "expect-type": "1.4.0",
"knip": "^6.34.0", "knip": "^6.34.0",
"lefthook": "^2.1.12", "lefthook": "^2.1.12",
"oxfmt": "^0.66.0", "oxfmt": "^0.68.0",
"oxlint": "^1.81.0", "oxlint": "^1.83.0",
"oxlint-tsgolint": "^7.0.2001", "oxlint-tsgolint": "^7.0.2001",
"publint": "^0.3.24", "publint": "^0.3.24",
"typescript": "^7.0.2" "typescript": "^7.0.2"
+33
View File
@@ -0,0 +1,33 @@
#!/usr/bin/env bash
set -euo pipefail
# Build (and optionally push) the CI job image from docker/Dockerfile.
# Run wherever docker + registry credentials live (the runner host, or any
# machine that can reach the registry). The registry/repo below MUST match
# the `container.image` references in .gitea/workflows/ci.yml — the runner
# pulls the image by name.
#
# Usage: scripts/runner-image.sh [--push]
IMAGE_REPO="gitea.e1nsnull.de/tmu/act-ci"
NODE_VERSION="$(tr -d '[:space:]' < .node-version)"
if [[ ! "${NODE_VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "error: .node-version must be pinned to an exact x.y.z, got '${NODE_VERSION}'." >&2
echo " setup-node resolves floats like '26' to the latest patch at runtime," >&2
echo " which silently busts the tool-cache entry baked into the image." >&2
exit 1
fi
IMAGE="${IMAGE_REPO}:${NODE_VERSION}"
# --pull: refresh the act base layer so the derivative does not float on an
# aging default image forever (layer dedup keeps this cheap).
docker build --pull --build-arg "NODE_VERSION=${NODE_VERSION}" -t "${IMAGE}" -f docker/Dockerfile .
if [[ "${1:-}" == "--push" ]]; then
docker push "${IMAGE}"
fi
echo "built ${IMAGE}"
echo "reminder: bump container.image in .gitea/workflows/ci.yml to this tag"