@bounded-systems/mint 0.4.3 → 0.5.0
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/.github/npm-trusted-publisher.json +10 -0
- package/.github/workflows/release.yml +32 -56
- package/.github/workflows/standard.yml +15 -0
- package/CHANGELOG.md +82 -0
- package/README.md +55 -8
- package/jsr.json +1 -1
- package/mint.mjs +37 -19
- package/mint.test.mjs +34 -0
- package/package.json +5 -1
- package/.github/workflows/ci.yml +0 -20
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/package.json",
|
|
3
|
+
"_comment": "Declarative record of the npm trusted publisher configuration for @bounded-systems/mint. Apply manually at https://www.npmjs.com/package/@bounded-systems/mint/access until npm exposes a public API for this.",
|
|
4
|
+
"provider": "github-actions",
|
|
5
|
+
"organization": "bounded-systems",
|
|
6
|
+
"repository": "mint",
|
|
7
|
+
"workflow": "release.yml",
|
|
8
|
+
"environment": null,
|
|
9
|
+
"permissions": ["npm publish"]
|
|
10
|
+
}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
name: release
|
|
2
2
|
|
|
3
3
|
# On a vX.Y.Z tag (pushed by `mint release`):
|
|
4
|
-
# release
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
4
|
+
# release — test, pack, SLSA-attest the tarball, emit + keyless-sign the
|
|
5
|
+
# in-toto release Statement (tag → version plan → commit), publish
|
|
6
|
+
# the GitHub release (notes from the tag annotation mint wrote) with
|
|
7
|
+
# the statement + its Sigstore bundle attached.
|
|
8
|
+
# approve — gated by the `npm-publish` GitHub Environment (required reviewer).
|
|
9
|
+
# No-op job: a maintainer approves in the Actions UI, which unblocks
|
|
10
|
+
# all deploy jobs below. Add new deploy targets as separate jobs with
|
|
11
|
+
# needs: [release, approve].
|
|
12
|
+
# npm — publish to npm via OIDC trusted publishing (no token).
|
|
13
|
+
# jsr — publish to JSR via OIDC (no token).
|
|
12
14
|
#
|
|
13
15
|
# This workflow covers: npm (staged) + JSR + GitHub release.
|
|
14
16
|
# Out of scope here — triggered separately on the same tag:
|
|
@@ -40,7 +42,7 @@ jobs:
|
|
|
40
42
|
id: pack
|
|
41
43
|
run: echo "tgz=$(npm pack | tail -1)" >> "$GITHUB_OUTPUT"
|
|
42
44
|
- name: Attest build provenance (SLSA)
|
|
43
|
-
uses: actions/attest-build-provenance@
|
|
45
|
+
uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4.1.1
|
|
44
46
|
with:
|
|
45
47
|
subject-path: ${{ steps.pack.outputs.tgz }}
|
|
46
48
|
# Release provenance: the deterministic in-toto Statement binding this tag to
|
|
@@ -66,60 +68,34 @@ jobs:
|
|
|
66
68
|
mint-release.intoto.json \
|
|
67
69
|
mint-release.intoto.sigstore.json
|
|
68
70
|
|
|
69
|
-
|
|
71
|
+
approve:
|
|
70
72
|
needs: release
|
|
71
73
|
runs-on: ubuntu-latest
|
|
74
|
+
environment: npm-publish # required reviewer — approving here unblocks all deploys
|
|
75
|
+
steps:
|
|
76
|
+
- run: echo "Approved."
|
|
77
|
+
|
|
78
|
+
npm:
|
|
79
|
+
needs: [release, approve]
|
|
80
|
+
runs-on: ubuntu-latest
|
|
72
81
|
steps:
|
|
73
82
|
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
|
|
74
83
|
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
|
|
75
84
|
with:
|
|
76
|
-
node-version: "24"
|
|
85
|
+
node-version: "24"
|
|
77
86
|
registry-url: "https://registry.npmjs.org"
|
|
78
87
|
- run: npm ci --no-audit --no-fund
|
|
79
|
-
- name: Publish
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
npm stage publish --access public --provenance 2>&1 | tee /tmp/stage-out.txt || true
|
|
92
|
-
else
|
|
93
|
-
echo "first publish — seeding with npm publish (staged publishing requires existing package)"
|
|
94
|
-
npm publish --access public --provenance 2>&1 | tee /tmp/stage-out.txt || true
|
|
95
|
-
fi
|
|
96
|
-
STAGE_OUT=$(cat /tmp/stage-out.txt)
|
|
97
|
-
STAGE_ID=$(echo "$STAGE_OUT" | grep -oE '[A-Za-z0-9]{8}-[A-Za-z0-9]{4}-[A-Za-z0-9]{4}-[A-Za-z0-9]{4}-[A-Za-z0-9]{12}' | head -1 || true)
|
|
98
|
-
echo "stage_id=${STAGE_ID}" >> "$GITHUB_OUTPUT"
|
|
99
|
-
- name: Surface approval instructions
|
|
100
|
-
env:
|
|
101
|
-
STAGE_ID: ${{ steps.stage.outputs.stage_id }}
|
|
102
|
-
PKG: ${{ github.repository }}
|
|
103
|
-
run: |
|
|
104
|
-
{
|
|
105
|
-
echo "## npm package staged — human approval required"
|
|
106
|
-
echo ""
|
|
107
|
-
echo "The package is in the staging area, **not yet live on the registry**."
|
|
108
|
-
echo "A maintainer must approve it with 2FA before it becomes publicly available."
|
|
109
|
-
echo ""
|
|
110
|
-
if [ -n "$STAGE_ID" ]; then
|
|
111
|
-
echo "**Stage ID:** \`${STAGE_ID}\`"
|
|
112
|
-
echo ""
|
|
113
|
-
echo "**Approve via CLI (2FA required):**"
|
|
114
|
-
echo '```'
|
|
115
|
-
echo "npm stage approve ${STAGE_ID}"
|
|
116
|
-
echo '```'
|
|
117
|
-
else
|
|
118
|
-
echo "> Could not parse stage ID from npm output."
|
|
119
|
-
echo "> Run \`npm stage list @bounded-systems/mint\` to find it."
|
|
120
|
-
fi
|
|
121
|
-
echo ""
|
|
122
|
-
echo "**Or approve on npmjs.com:** open the [Staged Packages](https://www.npmjs.com/settings/~/packages/staged) tab."
|
|
123
|
-
} >> "$GITHUB_STEP_SUMMARY"
|
|
88
|
+
- name: Publish to npm (OIDC trusted publishing — no token)
|
|
89
|
+
run: npm publish --access public --provenance
|
|
90
|
+
|
|
91
|
+
jsr:
|
|
92
|
+
needs: [release, approve]
|
|
93
|
+
runs-on: ubuntu-latest
|
|
94
|
+
steps:
|
|
95
|
+
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
|
|
96
|
+
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
|
|
97
|
+
with:
|
|
98
|
+
node-version: "24"
|
|
99
|
+
- run: npm ci --no-audit --no-fund
|
|
124
100
|
- name: Publish to JSR (OIDC — no token)
|
|
125
101
|
run: npx jsr publish --allow-slow-types
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
name: standard
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches: [main]
|
|
5
|
+
pull_request:
|
|
6
|
+
permissions:
|
|
7
|
+
contents: read
|
|
8
|
+
jobs:
|
|
9
|
+
standard:
|
|
10
|
+
uses: bounded-systems/.github/.github/workflows/repo-standard.yml@d43c3280588ef05f4ead43426db1091d4cb8f520
|
|
11
|
+
with:
|
|
12
|
+
security: true
|
|
13
|
+
test: true
|
|
14
|
+
runtime: node
|
|
15
|
+
test-command: "npm ci --no-audit --no-fund && npm test"
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,87 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.0 — 2026-07-05
|
|
4
|
+
|
|
5
|
+
### Minor
|
|
6
|
+
|
|
7
|
+
- read + bump `deno.json` (not just `package.json`/`jsr.json`) — unblocks every Deno/JSR package in the org from adopting mint (fixes #13; unblocks gh-project-room#47)
|
|
8
|
+
|
|
9
|
+
### Patch
|
|
10
|
+
|
|
11
|
+
- docs: document the minimumDependencyAge 24h JSR/npm cooldown for consumers and its batch-rollout ripple (#11)
|
|
12
|
+
|
|
13
|
+
## 0.4.15 — 2026-06-29
|
|
14
|
+
|
|
15
|
+
### Patch
|
|
16
|
+
|
|
17
|
+
- add repository field to package.json — required by npm provenance verification to match the GitHub repo URL in the OIDC claims
|
|
18
|
+
|
|
19
|
+
## 0.4.14 — 2026-06-29
|
|
20
|
+
|
|
21
|
+
### Patch
|
|
22
|
+
|
|
23
|
+
- revert _authToken strip — the empty NODE_AUTH_TOKEN reference in .npmrc is what triggers npm's OIDC exchange; stripping it causes ENEEDAUTH; trusted publisher config (no environment, publish allowed) is the real fix
|
|
24
|
+
|
|
25
|
+
## 0.4.13 — 2026-06-29
|
|
26
|
+
|
|
27
|
+
### Patch
|
|
28
|
+
|
|
29
|
+
- fix npm OIDC auth — restore registry-url and strip the injected empty _authToken before publishing so npm can fall through to its OIDC trusted-publishing exchange
|
|
30
|
+
|
|
31
|
+
## 0.4.12 — 2026-06-29
|
|
32
|
+
|
|
33
|
+
### Patch
|
|
34
|
+
|
|
35
|
+
- remove registry-url from npm job setup-node — injected NODE_AUTH_TOKEN conflicts with OIDC trusted publishing auth exchange
|
|
36
|
+
|
|
37
|
+
## 0.4.11 — 2026-06-29
|
|
38
|
+
|
|
39
|
+
### Patch
|
|
40
|
+
|
|
41
|
+
- split publish into approve (gate) + npm + jsr as independent parallel jobs — one approval unblocks all deploys, each target has its own job log and can be retried independently
|
|
42
|
+
|
|
43
|
+
## 0.4.10 — 2026-06-29
|
|
44
|
+
|
|
45
|
+
### Patch
|
|
46
|
+
|
|
47
|
+
- unify npm + JSR behind a single publish job gated by the npm-publish GitHub Environment — one approval deploys to all registries
|
|
48
|
+
|
|
49
|
+
## 0.4.9 — 2026-06-29
|
|
50
|
+
|
|
51
|
+
### Patch
|
|
52
|
+
|
|
53
|
+
- replace npm staged publishing with direct npm publish gated behind the GitHub Environment approval — same human gate, no dependency on unfinished npm staging OIDC support
|
|
54
|
+
|
|
55
|
+
## 0.4.8 — 2026-06-29
|
|
56
|
+
|
|
57
|
+
### Patch
|
|
58
|
+
|
|
59
|
+
- fix npm stage publish OIDC scope — move npm stage publish into the npm-approve job (environment: npm-publish) so the OIDC token carries the environment claim required by the trusted publisher
|
|
60
|
+
|
|
61
|
+
## 0.4.7 — 2026-06-29
|
|
62
|
+
|
|
63
|
+
### Patch
|
|
64
|
+
|
|
65
|
+
- retry staged npm publish — trusted publisher now has stage action + environment scoped to npm-publish
|
|
66
|
+
|
|
67
|
+
## 0.4.6 — 2026-06-29
|
|
68
|
+
|
|
69
|
+
### Patch
|
|
70
|
+
|
|
71
|
+
- bump actions/attest-build-provenance to v4.1.1 (Node 24, clears deprecation warnings); add npm-publish GitHub Environment gate with required reviewer before surfacing the npm stage approve command
|
|
72
|
+
|
|
73
|
+
## 0.4.5 — 2026-06-29
|
|
74
|
+
|
|
75
|
+
### Patch
|
|
76
|
+
|
|
77
|
+
- fix registry existence check — use curl instead of `npm view` (NODE_AUTH_TOKEN in .npmrc was causing the lookup to fail, always falling through to first-publish path)
|
|
78
|
+
|
|
79
|
+
## 0.4.4 — 2026-06-29
|
|
80
|
+
|
|
81
|
+
### Patch
|
|
82
|
+
|
|
83
|
+
- first staged npm release — package now seeded, all future releases go through `npm stage publish` with human 2FA approval
|
|
84
|
+
|
|
3
85
|
## 0.4.3 — 2026-06-29
|
|
4
86
|
|
|
5
87
|
### Patch
|
package/README.md
CHANGED
|
@@ -106,16 +106,15 @@ mint ships from `release.yml` on each `v*` tag via **OIDC trusted publishing**
|
|
|
106
106
|
no `NPM_TOKEN`, no JSR token, ever. The package manifests are kept in lockstep by
|
|
107
107
|
`mint version` (it bumps `package.json`, `package-lock.json`, **and** `jsr.json`).
|
|
108
108
|
|
|
109
|
-
**npm uses
|
|
110
|
-
|
|
111
|
-
|
|
109
|
+
**npm uses a GitHub Environment gate** — the `npm-approve` job is blocked by the
|
|
110
|
+
`npm-publish` environment, which requires a designated reviewer to approve in the
|
|
111
|
+
GitHub Actions UI before `npm publish` runs. Approve at:
|
|
112
112
|
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
# or: npmjs.com → Staged Packages tab → Approve
|
|
113
|
+
```
|
|
114
|
+
https://github.com/bounded-systems/mint/actions
|
|
116
115
|
```
|
|
117
116
|
|
|
118
|
-
|
|
117
|
+
Once approved, the package publishes immediately via OIDC trusted publishing (no token).
|
|
119
118
|
|
|
120
119
|
**JSR publishes immediately** on the same tag (no staging concept on JSR).
|
|
121
120
|
|
|
@@ -138,6 +137,54 @@ JSR type-checker resolves mint's `node:` imports.
|
|
|
138
137
|
> authorizes the keyless OIDC publish; after it, every tagged release publishes
|
|
139
138
|
> with no token.
|
|
140
139
|
|
|
140
|
+
### Consumers: the 24h JSR/npm cooldown after a release
|
|
141
|
+
|
|
142
|
+
Every fresh JSR/npm publish immediately hits Deno's
|
|
143
|
+
[`minimumDependencyAge`](https://docs.deno.com/runtime/packages/supply_chain/)
|
|
144
|
+
in any consumer running Deno 2.9+: since 2.9 it defaults to **24 hours** — Deno
|
|
145
|
+
refuses to resolve a version published inside that window, full stop, no
|
|
146
|
+
config needed to trigger it. It's a real supply-chain guard (malicious
|
|
147
|
+
versions are usually caught/yanked within days), but it applies to first-party
|
|
148
|
+
`@bounded-systems/*` releases exactly the same as to a random third party.
|
|
149
|
+
|
|
150
|
+
Concretely: `baobab@0.2.0` published, and every downstream consumer's CI
|
|
151
|
+
(e.g. a `check-contrast.yml` caller) hard-failed for the next 24h trying to
|
|
152
|
+
resolve it — not a flake, a guaranteed wait baked into every release
|
|
153
|
+
([bounded-systems/mint#11](https://github.com/bounded-systems/mint/issues/11)).
|
|
154
|
+
For one package that's a wait; for a coordinated rollout of several
|
|
155
|
+
interdependent `@bounded-systems/*` packages in one sitting, it ripples —
|
|
156
|
+
every consumer of every package in the batch eats the same 24h, and chains of
|
|
157
|
+
dependencies compound it.
|
|
158
|
+
|
|
159
|
+
**The fix does NOT live in a consumer's `deno.json`.** An earlier version of
|
|
160
|
+
this doc claimed a `minimumDependencyAge.exclude` list there would work —
|
|
161
|
+
that was wrong, and only looked right because it was tested against Deno
|
|
162
|
+
2.8.3 (which doesn't enforce the 24h default at all; the default only started
|
|
163
|
+
in 2.9). Verified against the real `2.9.1` binary: `deno.json` is never even
|
|
164
|
+
read when `deno run`'s entrypoint is a bare `jsr:...` specifier — config-file
|
|
165
|
+
discovery only applies in normal "project mode." Planting invalid JSON in a
|
|
166
|
+
`deno.json` and confirming Deno never complained is what exposed this.
|
|
167
|
+
|
|
168
|
+
**What actually works:** the `--minimum-dependency-age` CLI flag on the
|
|
169
|
+
invocation itself. That means the fix has to live wherever the `deno run`
|
|
170
|
+
command is composed — for a reusable GitHub Actions workflow like
|
|
171
|
+
`check-contrast.yml`, that's an input on the workflow, not something a caller
|
|
172
|
+
can override from its own repo
|
|
173
|
+
([bounded-systems/baobab#7](https://github.com/bounded-systems/baobab/pull/7)
|
|
174
|
+
adds `minimum-dependency-age`, defaulting to `"0"`, since the only thing that
|
|
175
|
+
workflow ever resolves from the network is `@bounded-systems/baobab` itself —
|
|
176
|
+
a first-party package the caller already trust-bounds via its own version
|
|
177
|
+
range input, so the age gate adds no real protection there). Any other
|
|
178
|
+
reusable workflow or script that shells out to `deno run jsr:...`/`npm:...`
|
|
179
|
+
directly needs the same treatment: an explicit `--minimum-dependency-age`
|
|
180
|
+
(or `--minimum-dependency-age=0` if every dependency it touches is
|
|
181
|
+
first-party) on the command, not a config file a caller drops in.
|
|
182
|
+
|
|
183
|
+
This still doesn't scale past a handful of hand-fixed workflows — #11 is the
|
|
184
|
+
open ask for mint to own generating this consistently across every
|
|
185
|
+
`@bounded-systems/*` reusable workflow, rather than fixing each one by hand
|
|
186
|
+
as it's hit.
|
|
187
|
+
|
|
141
188
|
## Library
|
|
142
189
|
|
|
143
190
|
```js
|
|
@@ -167,7 +214,7 @@ releaseStatement({
|
|
|
167
214
|
- [x] `mint release` — signed tag + in-toto release provenance, keyless-signed in CI (cosign/Sigstore; anchored-chain-shaped)
|
|
168
215
|
- [ ] verbspec-typed CLI + MCP surface
|
|
169
216
|
- [x] Reusable `workflow_call` Action (`version.yml` + `release-provenance.yml`)
|
|
170
|
-
- [x] Publish to npm (
|
|
217
|
+
- [x] Publish to npm (GitHub Environment approval gate) + JSR
|
|
171
218
|
|
|
172
219
|
Tracking: [bounded-systems/string-audit#43](https://github.com/bounded-systems/string-audit/issues/43).
|
|
173
220
|
|
package/jsr.json
CHANGED
package/mint.mjs
CHANGED
|
@@ -34,10 +34,23 @@ async function readJson(path) {
|
|
|
34
34
|
return JSON.parse(await readFile(path, "utf8"));
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
// The version lives in whichever manifest a repo uses: deno.json (Deno),
|
|
38
|
+
// jsr.json (JSR-from-npm), or package.json (npm). A repo may carry several kept
|
|
39
|
+
// in lockstep. Detect the first present one that declares a version.
|
|
40
|
+
const MANIFESTS = ["deno.json", "jsr.json", "package.json"];
|
|
41
|
+
|
|
37
42
|
async function currentVersion() {
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
43
|
+
for (const path of MANIFESTS) {
|
|
44
|
+
try {
|
|
45
|
+
const m = await readJson(path);
|
|
46
|
+
if (m.version) return m.version;
|
|
47
|
+
} catch (e) {
|
|
48
|
+
if (e.code !== "ENOENT") throw e;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
throw new Error(
|
|
52
|
+
`no manifest with a version field (looked for: ${MANIFESTS.join(", ")})`,
|
|
53
|
+
);
|
|
41
54
|
}
|
|
42
55
|
|
|
43
56
|
async function cmdPlan() {
|
|
@@ -63,10 +76,25 @@ async function cmdVersion() {
|
|
|
63
76
|
return;
|
|
64
77
|
}
|
|
65
78
|
|
|
66
|
-
// Bump
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
79
|
+
// Bump every manifest present (deno.json / jsr.json / package.json) in
|
|
80
|
+
// lockstep, preserving 2-space JSON.
|
|
81
|
+
const bumped = [];
|
|
82
|
+
for (const path of MANIFESTS) {
|
|
83
|
+
try {
|
|
84
|
+
const m = await readJson(path);
|
|
85
|
+
m.version = p.nextVersion;
|
|
86
|
+
await writeFile(path, JSON.stringify(m, null, 2) + "\n");
|
|
87
|
+
bumped.push(path);
|
|
88
|
+
} catch (e) {
|
|
89
|
+
if (e.code !== "ENOENT") throw e;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (bumped.length === 0) {
|
|
93
|
+
throw new Error(
|
|
94
|
+
`no manifest to bump (looked for: ${MANIFESTS.join(", ")})`,
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
// Keep an npm lockfile in lockstep if present.
|
|
70
98
|
try {
|
|
71
99
|
const lock = await readJson("package-lock.json");
|
|
72
100
|
lock.version = p.nextVersion;
|
|
@@ -75,14 +103,6 @@ async function cmdVersion() {
|
|
|
75
103
|
} catch (e) {
|
|
76
104
|
if (e.code !== "ENOENT") throw e;
|
|
77
105
|
}
|
|
78
|
-
// Keep jsr.json in lockstep (JSR has its own manifest version).
|
|
79
|
-
try {
|
|
80
|
-
const jsr = await readJson("jsr.json");
|
|
81
|
-
jsr.version = p.nextVersion;
|
|
82
|
-
await writeFile("jsr.json", JSON.stringify(jsr, null, 2) + "\n");
|
|
83
|
-
} catch (e) {
|
|
84
|
-
if (e.code !== "ENOENT") throw e;
|
|
85
|
-
}
|
|
86
106
|
|
|
87
107
|
// Prepend the entry to CHANGELOG.md (create with a header if absent).
|
|
88
108
|
let changelog = "";
|
|
@@ -95,7 +115,7 @@ async function cmdVersion() {
|
|
|
95
115
|
// Consume the intents.
|
|
96
116
|
for (const i of intents) if (i.file) await unlink(i.file);
|
|
97
117
|
|
|
98
|
-
console.log(`mint: ${p.currentVersion} → ${p.nextVersion} (${p.bump}). Updated
|
|
118
|
+
console.log(`mint: ${p.currentVersion} → ${p.nextVersion} (${p.bump}). Updated ${bumped.join(" + ")} + CHANGELOG.md, consumed ${intents.length} intent(s).`);
|
|
99
119
|
console.log(`Next: commit, then \`mint release\` to cut the tag + emit release provenance.`);
|
|
100
120
|
}
|
|
101
121
|
|
|
@@ -122,9 +142,7 @@ function ciBuilder() {
|
|
|
122
142
|
// (reads package.json + CHANGELOG + git HEAD + CI env); delegates the pure shape
|
|
123
143
|
// to release.mjs. Throws with a CLI-friendly message on a missing changelog entry.
|
|
124
144
|
async function gatherStatement() {
|
|
125
|
-
const
|
|
126
|
-
const version = pkg.version;
|
|
127
|
-
if (!version) throw new Error("package.json has no version");
|
|
145
|
+
const version = await currentVersion();
|
|
128
146
|
const tag = `v${version}`;
|
|
129
147
|
|
|
130
148
|
let changelog = "";
|
package/mint.test.mjs
CHANGED
|
@@ -177,3 +177,37 @@ test("DSSE pre-authentication encoding wraps the canonical statement", () => {
|
|
|
177
177
|
assert.ok(pae.startsWith(`DSSEv1 ${DSSE_PAYLOAD_TYPE.length} ${DSSE_PAYLOAD_TYPE} ${Buffer.byteLength(payload)} `));
|
|
178
178
|
assert.ok(pae.endsWith(payload));
|
|
179
179
|
});
|
|
180
|
+
|
|
181
|
+
// ── CLI manifest handling: mint reads/bumps deno.json, not just package.json (#13)
|
|
182
|
+
import { execFileSync } from "node:child_process";
|
|
183
|
+
import { mkdtempSync, mkdirSync, writeFileSync, readFileSync, rmSync } from "node:fs";
|
|
184
|
+
import { tmpdir } from "node:os";
|
|
185
|
+
import { join } from "node:path";
|
|
186
|
+
import { fileURLToPath } from "node:url";
|
|
187
|
+
|
|
188
|
+
const MINT = fileURLToPath(new URL("./mint.mjs", import.meta.url));
|
|
189
|
+
|
|
190
|
+
function bumpIn(manifestName) {
|
|
191
|
+
const d = mkdtempSync(join(tmpdir(), "mint-cli-"));
|
|
192
|
+
try {
|
|
193
|
+
writeFileSync(
|
|
194
|
+
join(d, manifestName),
|
|
195
|
+
JSON.stringify({ name: "@x/y", version: "0.1.0", exports: "./m.ts" }, null, 2) + "\n",
|
|
196
|
+
);
|
|
197
|
+
mkdirSync(join(d, ".release"));
|
|
198
|
+
writeFileSync(join(d, ".release", "i.md"), "---\nbump: minor\n---\nx\n");
|
|
199
|
+
execFileSync("node", [MINT, "version"], { cwd: d, stdio: "pipe" });
|
|
200
|
+
return JSON.parse(readFileSync(join(d, manifestName), "utf8")).version;
|
|
201
|
+
} finally {
|
|
202
|
+
rmSync(d, { recursive: true, force: true });
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
test("mint version bumps a deno.json-only repo (#13)", () => {
|
|
207
|
+
assert.equal(bumpIn("deno.json"), "0.2.0");
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
test("mint version still bumps a jsr.json / package.json repo", () => {
|
|
211
|
+
assert.equal(bumpIn("jsr.json"), "0.2.0");
|
|
212
|
+
assert.equal(bumpIn("package.json"), "0.2.0");
|
|
213
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bounded-systems/mint",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Deterministic versioning capability — intent files in, signed release out. A seam over semver: own the flow, delegate the arithmetic.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -15,6 +15,10 @@
|
|
|
15
15
|
"test": "node --test",
|
|
16
16
|
"plan": "node mint.mjs plan"
|
|
17
17
|
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/bounded-systems/mint.git"
|
|
21
|
+
},
|
|
18
22
|
"license": "PolyForm-Noncommercial-1.0.0",
|
|
19
23
|
"dependencies": {
|
|
20
24
|
"semver": "^7.6.0",
|
package/.github/workflows/ci.yml
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
name: ci
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [main]
|
|
6
|
-
pull_request:
|
|
7
|
-
|
|
8
|
-
permissions:
|
|
9
|
-
contents: read
|
|
10
|
-
|
|
11
|
-
jobs:
|
|
12
|
-
test:
|
|
13
|
-
runs-on: ubuntu-latest
|
|
14
|
-
steps:
|
|
15
|
-
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
|
|
16
|
-
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
|
|
17
|
-
with:
|
|
18
|
-
node-version: "22"
|
|
19
|
-
- run: npm ci --no-audit --no-fund
|
|
20
|
-
- run: npm test
|