Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c0bba0775c | ||
|
|
b8d235df89 | ||
|
|
76fe8993a7 | ||
|
|
f984576d4e | ||
|
|
79b4d8c005 | ||
|
|
60e416b0fe | ||
|
|
e90d2549e3 | ||
|
|
8915eb8faa | ||
|
|
75f2185b32 |
No files matched your search
+32
-15
@@ -65,8 +65,8 @@ jobs:
|
||||
- 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. Mirrors the publish job's
|
||||
# NPM_TOKEN assert — cheap, and it names the invariant.
|
||||
# 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"
|
||||
@@ -142,19 +142,17 @@ jobs:
|
||||
container:
|
||||
image: gitea.e1nsnull.de/tmu/act-ci:26.8.2
|
||||
# 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:
|
||||
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:
|
||||
# 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/setup-node@v4
|
||||
with:
|
||||
@@ -183,9 +181,28 @@ jobs:
|
||||
env:
|
||||
TAG_REF: ${{ gitea.ref }}
|
||||
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:
|
||||
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:
|
||||
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
|
||||
+6
-1
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.1.5] - 2026-09-15
|
||||
|
||||
- improve CI configuration
|
||||
|
||||
## [0.1.4] - 2026-09-14
|
||||
|
||||
- fix CI to node from custom image
|
||||
@@ -28,7 +32,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- basic setup
|
||||
|
||||
[Unreleased]: https://gitea.e1nsnull.de/tmu/tiny-pattern-ts/compare/0.1.4...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
|
||||
|
||||
+4
-2
@@ -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":
|
||||
|
||||
| Tier | When | What it runs | Time |
|
||||
| -------------------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------- | ----- |
|
||||
| -------------------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
|
||||
| `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-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 |
|
||||
| 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 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?
|
||||
|
||||
@@ -115,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.
|
||||
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.
|
||||
|
||||
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.
|
||||
@@ -24,6 +24,7 @@ Bugs:
|
||||
Enhancements:
|
||||
|
||||
Documentation:
|
||||
☐ Clean up CONTRIBUTING.md and README.md, create docs
|
||||
☐ Add usage examples to README.md
|
||||
☐ Create `examples/` directory with runnable snippets
|
||||
☐ Add comparison section vs. other TS pattern-matching libs
|
||||
@@ -54,3 +55,10 @@ Maintenance:
|
||||
✔ 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
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "tiny-pattern-ts",
|
||||
"version": "0.1.4",
|
||||
"version": "0.1.5",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "tiny-pattern-ts",
|
||||
"version": "0.1.4",
|
||||
"version": "0.1.5",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@arethetypeswrong/cli": "^0.18.5",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "tiny-pattern-ts",
|
||||
"version": "0.1.4",
|
||||
"version": "0.1.5",
|
||||
"description": "Pattern matching for TypeScript/ESM environments (F#-style, not regex)",
|
||||
"keywords": [
|
||||
"adt",
|
||||
|
||||
Reference in new issue
Block a user