@entro314labs/release-kit 2.3.0 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +32 -23
  2. package/package.json +1 -1
  3. package/release.mjs +34 -2
package/README.md CHANGED
@@ -94,7 +94,7 @@ release-kit minor
94
94
  No global state to drift, no install step, and the version is explicit in the command.
95
95
 
96
96
  ```sh
97
- npx @entro314labs/release-kit@2.1.0 minor --yes
97
+ npx @entro314labs/release-kit@2.3.0 minor --yes
98
98
  ```
99
99
 
100
100
  ### Vendored — no registry at release time
@@ -116,7 +116,7 @@ npx @entro314labs/release-kit --sync . # writes scripts/release.mjs
116
116
  machine you do not want to install anything on.
117
117
 
118
118
  ```sh
119
- curl -fsSL https://raw.githubusercontent.com/entro314-labs/release-kit/v2.1.0/release.mjs \
119
+ curl -fsSL https://raw.githubusercontent.com/entro314-labs/release-kit/v2.3.0/release.mjs \
120
120
  | node - minor --yes
121
121
  ```
122
122
 
@@ -172,16 +172,20 @@ Prerelease bumps need `--preid` unless the current version already carries one t
172
172
 
173
173
  ### Flags
174
174
 
175
- | Flag | Effect |
176
- | ------------------- | -------------------------------------------------------------------------- |
177
- | `--dry-run` | Print every step, execute nothing. Preflight still runs and still reports. |
178
- | `--yes`, `-y` | Skip the confirmation prompt. |
179
- | `--preid <id>` | Prerelease identifier: `alpha`, `beta`, `rc`, `next`, `nightly`, `canary`. |
180
- | `--dist-tag <name>` | Override the npm dist-tag. Always wins over the derived one. |
181
- | `--only <steps>` | Run only these steps, comma-separated. |
182
- | `--skip <steps>` | Run every step except these. |
183
- | `--sync <dir>...` | Copy this script into other projects and exit. Touches no git state. |
184
- | `--help`, `-h` | Full flag list. |
175
+ | Flag | Effect |
176
+ | ---------------------------- | -------------------------------------------------------------------------- |
177
+ | `--only <steps>` | Run only these steps, comma-separated. |
178
+ | `--skip <steps>` | Run every step except these. |
179
+ | `--commit` | Add the opt-in `commit` step: commit a dirty tree with a drafted message. |
180
+ | `--dry-run` | Print every step, execute nothing. Preflight still runs and still reports. |
181
+ | `--yes`, `-y` | Skip the confirmation prompt. |
182
+ | `--preid <id>` | Prerelease identifier: `alpha`, `beta`, `rc`, `next`, `nightly`, `canary`. |
183
+ | `--dist-tag <name>` | Override the npm dist-tag. Always wins over the derived one. |
184
+ | `--assistant <name>` | Drafting CLI: `auto`, `none`, `claude`, `codex`. |
185
+ | `--assistant-model <name>` | Model the assistant runs with. |
186
+ | `--assistant-effort <level>` | Reasoning effort the assistant runs with. |
187
+ | `--sync <dir>...` | Copy this script into other projects and exit. Touches no git state. |
188
+ | `--help`, `-h` | Full flag list. |
185
189
 
186
190
  ## 🧩 Steps
187
191
 
@@ -256,17 +260,18 @@ falling through to `latest` would put a prerelease on the stable line where ever
256
260
  Every check runs and every failure is reported before it aborts once with the whole list,
257
261
  rather than stopping at the first problem.
258
262
 
259
- - The target version is greater than the current one
260
- - Working tree is clean
261
- - On the configured branch
263
+ - The target version is greater than the current one — and for `auto`, which bump the
264
+ commits imply and why
265
+ - Working tree is clean, or listed for commit when the `commit` step runs
266
+ - On the configured branch, and not on a detached HEAD
262
267
  - The remote exists, is reachable, and the branch is not behind it
263
268
  - The tag is free — or already exists at `HEAD`, in which case it is reused
264
269
  - `gh` is installed and authenticated
265
- - Commit and tag signing can actually sign, when `commit.gpgsign` or `tag.gpgsign` is on
266
- - The publishing CLI is authenticated, and the version is not already on the registry
270
+ - Commit and tag signing can actually sign, and the key is one GitHub will accept
271
+ - The publishing CLI is authenticated, and the version is not already published
267
272
  - Configured release assets exist
268
- - A changelog section for the version exists _(a warning, not a failure — it falls back
269
- to generated notes)_
273
+ - A shallow clone is reported, since it truncates the history notes come from _(warning)_
274
+ - A changelog section for the version exists _(warning — it falls back to generated notes)_
270
275
 
271
276
  Under `--dry-run` the failures are reported and then the remaining steps are shown anyway,
272
277
  so you can see the whole plan without fixing the blockers first.
@@ -348,12 +353,16 @@ rather than being silently ignored.
348
353
 
349
354
  | Key | Default | Meaning |
350
355
  | --------------- | ------------------------ | ------------------------------------------------------------ |
356
+ | `steps` | all but `commit` | Which steps run; the order is fixed |
351
357
  | `tagPrefix` | `"v"` | Prepended to the version to form the tag |
352
358
  | `branch` | `"main"` | The only branch a release may run from; `null` allows any |
353
359
  | `remote` | `"origin"` | Git remote to push to |
354
- | `changelog` | `"CHANGELOG.md"` | Changelog path; `null` disables changelog handling |
355
- | `versionFiles` | `[]` | Extra JSON files whose top-level `"version"` is kept in sync |
356
- | `publish` | `"npm publish --tag %d"` | Publish command; `null` skips publishing |
360
+ | `changelog` | `"CHANGELOG.md"` | Changelog path; `null` for a project without one |
361
+ | `versionFile` | detected | Where the version lives; `null` versions by tag alone |
362
+ | `versionFiles` | `[]` | Further files kept in sync; a path or `{ path, pattern }` |
363
+ | `publish` | `"npm publish --tag %d"` | Publish command; `null` means none is configured |
364
+ | `versioning` | `"conventional"` | How `auto` infers; or `always-patch` / `-minor` / `-major` |
365
+ | `assistant` | `null` | Drafting CLI: a name, `"auto"`, or `{ tool, model, effort }` |
357
366
  | `commitMessage` | `"chore(release): %t"` | Release commit subject |
358
367
  | `releaseTitle` | `"%t"` | GitHub release title |
359
368
  | `assets` | `[]` | Files attached to the GitHub release |
@@ -373,7 +382,7 @@ Non-interactive by default: the confirmation prompt is skipped when stdin is not
373
382
  with:
374
383
  fetch-depth: 0 # release notes and the last-tag lookup need real history
375
384
  - id: release
376
- run: npx @entro314labs/release-kit@2.1.0 minor --yes
385
+ run: npx @entro314labs/release-kit@2.3.0 minor --yes
377
386
  env:
378
387
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
379
388
  - run: echo "shipped ${{ steps.release.outputs.tag }} ${{ steps.release.outputs.release-url }}"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@entro314labs/release-kit",
3
- "version": "2.3.0",
3
+ "version": "2.3.1",
4
4
  "description": "Single-file, zero-dependency release mechanism for JS/TS/Node projects: version bump, changelog roll, commit, annotated tag, push, publish, GitHub release",
5
5
  "keywords": [
6
6
  "changelog",
package/release.mjs CHANGED
@@ -229,6 +229,22 @@ function read(command, args) {
229
229
  }).trim()
230
230
  }
231
231
 
232
+ /**
233
+ * Whether GitHub knows the key git signs with.
234
+ *
235
+ * Compares key material rather than fingerprints, so no extra process is spawned per key.
236
+ *
237
+ * @returns {boolean | null} null when it cannot be determined — gh missing, token without
238
+ * the scope to list signing keys, or no network. An unanswerable check is not a failure.
239
+ */
240
+ function signingKeyRegistered(keyPath) {
241
+ const local = readFileSync(keyPath, 'utf8').trim().split(/\s+/)[1]
242
+ if (!local) return null
243
+ const listed = tryRead('gh', ['api', 'user/ssh_signing_keys', '--jq', '.[].key'])
244
+ if (listed === null) return null
245
+ return listed.split('\n').some((key) => key.trim().split(/\s+/)[1] === local)
246
+ }
247
+
232
248
  /** Read-only command → trimmed stdout, or null when it exits non-zero. */
233
249
  function tryRead(command, args) {
234
250
  try {
@@ -1289,9 +1305,9 @@ if (runs('commit') && !assistant) {
1289
1305
  .join(', ')
1290
1306
  ok(`assistant: ${assistantName}${detail ? ` (${detail})` : ''}`)
1291
1307
  if (assistantModel && !assistant.model)
1292
- warn(`${assistantName} takes no model flag — --model ignored`)
1308
+ warn(`${assistantName} takes no model flag — --assistant-model ignored`)
1293
1309
  if (assistantEffort && !assistant.effort)
1294
- warn(`${assistantName} takes no effort flag — --effort ignored`)
1310
+ warn(`${assistantName} takes no effort flag — --assistant-effort ignored`)
1295
1311
  }
1296
1312
 
1297
1313
  const branch = tryRead('git', ['rev-parse', '--abbrev-ref', 'HEAD'])
@@ -1351,6 +1367,22 @@ if (signsSomething && signingKeys.length) {
1351
1367
  )
1352
1368
  } else {
1353
1369
  ok(`signing commits and tags (${format})`)
1370
+ // git signs happily with a key GitHub has never seen, which is how a repository fills
1371
+ // up with commits that are locally valid and permanently "Unverified". Only GitHub can
1372
+ // answer this, and only when the token carries the scope to list signing keys — so an
1373
+ // unanswerable check stays silent rather than guessing.
1374
+ if (format === 'ssh' && keyPath && existsSync(keyPath) && runs('release')) {
1375
+ const registered = signingKeyRegistered(keyPath)
1376
+ if (registered === false) {
1377
+ warn(
1378
+ 'this signing key is not registered with GitHub, so the commits will show as ' +
1379
+ 'Unverified.\n Add it: gh ssh-key add ' +
1380
+ `${signingKey} --type signing`,
1381
+ )
1382
+ } else if (registered === true) {
1383
+ ok('signing key is registered with GitHub')
1384
+ }
1385
+ }
1354
1386
  }
1355
1387
  }
1356
1388