@williamthorsen/release-kit 9.1.1 → 10.1.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/CHANGELOG.md +36 -0
- package/README.md +19 -7
- package/dist/esm/defineConfig.d.ts +1 -0
- package/dist/esm/index.d.ts +0 -2
- package/dist/esm/index.js +0 -1
- package/dist/esm/init/templates.js +2 -2
- package/dist/esm/loadConfig.js +11 -7
- package/dist/esm/sync-labels/templates.js +1 -1
- package/package.json +7 -4
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,42 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## 10.1.0 — 2026-08-03
|
|
6
|
+
|
|
7
|
+
### 🎉 Features
|
|
8
|
+
|
|
9
|
+
- Publish nmr's readyup kit with a test-tier conformance check (#580)
|
|
10
|
+
|
|
11
|
+
`@williamthorsen/nmr` is now bundled with ReadyUp kits that check a repo's alignment with `nmr` requirements and recommendations.
|
|
12
|
+
|
|
13
|
+
`rdy run --from npm:@williamthorsen/nmr` checks the repo against the kits without prior configuration. Once the package is added to the ReadyUp config, `rdy run --packages` will run the `nmr` kits along with those of any other registered package. Requires `readyup` v0.23 or greater.
|
|
14
|
+
|
|
15
|
+
### ♻️ Refactoring
|
|
16
|
+
|
|
17
|
+
- Load the config with Node's TypeScript support instead of jiti (#573)
|
|
18
|
+
|
|
19
|
+
`release-kit` now uses native Node with type-stripping to read its configs. `jiti` is no longer needed as a dependency. As a result, relative imports inside `.config/release-kit.config.ts` now require an explicit file extension.
|
|
20
|
+
|
|
21
|
+
## 10.0.0 — 2026-08-03
|
|
22
|
+
|
|
23
|
+
### 🎉 Features
|
|
24
|
+
|
|
25
|
+
- 🚨 **Breaking:** Retire integration label in favor of an isolation-tier test ladder (#552)
|
|
26
|
+
|
|
27
|
+
Test groups are now named for what a test reaches rather than for how much of the codebase it covers: `integration` and `app` are replaced by `unit`, `tool`, `localhost`, and `remote`.
|
|
28
|
+
|
|
29
|
+
`nmr test` now runs the `tool` group alongside `unit`, so the first run after upgrading may fail on tests that nothing was running before. Upgrading means renaming `*.int.test.ts` files onto the new groups and replacing `nmr test:integration` with `nmr test:tool`.
|
|
30
|
+
|
|
31
|
+
### ♻️ Refactoring
|
|
32
|
+
|
|
33
|
+
- 🚨 **Breaking:** Move defineConfig to a dedicated config subpath (#566)
|
|
34
|
+
|
|
35
|
+
`defineConfig` now comes from the `@williamthorsen/release-kit/config` subpath rather than from the package root. The subpath also carries the config types.
|
|
36
|
+
|
|
37
|
+
- Share nmr-core's cache primitives with nmr-compile (#570)
|
|
38
|
+
|
|
39
|
+
A package's writes to the build cache are now hidden from other packages until the write is complete. A failing build now reports its error in the same form as every other `nmr` command. `tsx` is no longer required to build a package.
|
|
40
|
+
|
|
5
41
|
## 9.1.0 — 2026-07-31
|
|
6
42
|
|
|
7
43
|
### 🎉 Features
|
package/README.md
CHANGED
|
@@ -4,7 +4,17 @@ Version-bumping and changelog-generation toolkit for release workflows.
|
|
|
4
4
|
|
|
5
5
|
Provides a self-contained CLI that auto-discovers workspaces from `pnpm-workspace.yaml`, parses conventional commits, determines version bumps, updates `package.json` files, and generates changelogs from `git-cliff --context` output rendered in-process (with optional [editorial overrides](#editorial-overrides)).
|
|
6
6
|
|
|
7
|
-
<!-- section:release-notes
|
|
7
|
+
<!-- section:release-notes -->
|
|
8
|
+
## Release notes — v10.1.0 (2026-08-03)
|
|
9
|
+
|
|
10
|
+
### 🎉 Features
|
|
11
|
+
|
|
12
|
+
- Publish nmr's readyup kit with a test-tier conformance check (#580)
|
|
13
|
+
|
|
14
|
+
`@williamthorsen/nmr` is now bundled with ReadyUp kits that check a repo's alignment with `nmr` requirements and recommendations.
|
|
15
|
+
|
|
16
|
+
`rdy run --from npm:@williamthorsen/nmr` checks the repo against the kits without prior configuration. Once the package is added to the ReadyUp config, `rdy run --packages` will run the `nmr` kits along with those of any other registered package. Requires `readyup` v0.23 or greater.
|
|
17
|
+
<!-- /section:release-notes -->
|
|
8
18
|
|
|
9
19
|
## Installation
|
|
10
20
|
|
|
@@ -59,7 +69,7 @@ That's it for most repos. The CLI auto-discovers workspaces and applies sensible
|
|
|
59
69
|
## How it works
|
|
60
70
|
|
|
61
71
|
1. **Workspace discovery**: reads `pnpm-workspace.yaml` and resolves its `packages` globs to find workspace directories. Each directory containing a `package.json` becomes a workspace. If no workspace file is found, the repo is treated as a single-package project.
|
|
62
|
-
2. **Config loading**: loads `.config/release-kit.config.ts` (if present)
|
|
72
|
+
2. **Config loading**: loads `.config/release-kit.config.ts` (if present) and merges it with discovered defaults.
|
|
63
73
|
3. **Commit analysis**: for each workspace, finds commits since the last version tag, parses them for type and scope, and determines the appropriate version bump.
|
|
64
74
|
4. **Version bump + changelog**: bumps `package.json` versions, builds structured `ChangelogEntry[]` from `git-cliff --context`, applies any [editorial overrides](#editorial-overrides) from per-scope `.meta/changelog-overrides.json` files, and renders both `CHANGELOG.md` and `.meta/changelog.json` from that single source. `git-cliff` is invoked only for its `--context` JSON; markdown rendering happens in-process so `.meta/changelog.json` and `CHANGELOG.md` always agree.
|
|
65
75
|
5. **Release tags file**: writes computed tags to `tmp/.release-tags` for the release workflow to read when tagging and pushing.
|
|
@@ -86,7 +96,7 @@ Configuration is optional. The CLI works out of the box by auto-discovering work
|
|
|
86
96
|
### Config file
|
|
87
97
|
|
|
88
98
|
```typescript
|
|
89
|
-
import { defineConfig } from '@williamthorsen/release-kit';
|
|
99
|
+
import { defineConfig } from '@williamthorsen/release-kit/config';
|
|
90
100
|
|
|
91
101
|
export default defineConfig({
|
|
92
102
|
// Exclude a workspace from release processing
|
|
@@ -105,6 +115,8 @@ export default defineConfig({
|
|
|
105
115
|
|
|
106
116
|
`defineConfig` is a type-safe identity function: it gives the config object validation and completion in `.ts` files and full inference in `.js` ones. The loader also accepts a plain `export default config` or `export const config = { ... }`.
|
|
107
117
|
|
|
118
|
+
Node loads the file directly, so a relative import inside it needs an explicit file extension — `./work-types.ts`, not `./work-types`.
|
|
119
|
+
|
|
108
120
|
### `ReleaseKitConfig` reference
|
|
109
121
|
|
|
110
122
|
| Field | Type | Description |
|
|
@@ -154,7 +166,7 @@ interface RetiredPackage {
|
|
|
154
166
|
Worked example — `preflight` was extracted from this monorepo and continues as the standalone `readyup` project. Its tags stay in this repo as historical anchors:
|
|
155
167
|
|
|
156
168
|
```typescript
|
|
157
|
-
import { defineConfig } from '@williamthorsen/release-kit';
|
|
169
|
+
import { defineConfig } from '@williamthorsen/release-kit/config';
|
|
158
170
|
|
|
159
171
|
export default defineConfig({
|
|
160
172
|
retiredPackages: [{ name: '@scope/preflight', tagPrefix: 'preflight-v', successor: 'readyup' }],
|
|
@@ -187,7 +199,7 @@ The rule is enforced at config load; the resulting error identifies both collidi
|
|
|
187
199
|
Some monorepos ship a single combined deliverable — a Chrome extension, a CLI binary, a packaged desktop app — for which the per-workspace tags and changelogs alone do not describe what the user actually receives. Declare the optional `project` block to add a project-level release stage that runs alongside the per-workspace pipeline.
|
|
188
200
|
|
|
189
201
|
```typescript
|
|
190
|
-
import type { ReleaseKitConfig } from '@williamthorsen/release-kit';
|
|
202
|
+
import type { ReleaseKitConfig } from '@williamthorsen/release-kit/config';
|
|
191
203
|
|
|
192
204
|
const config: ReleaseKitConfig = {
|
|
193
205
|
// Empty object is enough to opt in. Every non-excluded workspace contributes.
|
|
@@ -724,7 +736,7 @@ Every `sync-labels` subcommand refuses to run while the retired `.config/sync-la
|
|
|
724
736
|
#### Label configuration
|
|
725
737
|
|
|
726
738
|
```typescript
|
|
727
|
-
import { defineConfig } from '@williamthorsen/release-kit';
|
|
739
|
+
import { defineConfig } from '@williamthorsen/release-kit/config';
|
|
728
740
|
|
|
729
741
|
export default defineConfig({
|
|
730
742
|
repoLabels: {
|
|
@@ -871,7 +883,7 @@ Minimal worked example for a repo whose pre-v5 tags were `core-v0.2.7` and whose
|
|
|
871
883
|
|
|
872
884
|
```typescript
|
|
873
885
|
// .config/release-kit.config.ts
|
|
874
|
-
import type { ReleaseKitConfig } from '@williamthorsen/release-kit';
|
|
886
|
+
import type { ReleaseKitConfig } from '@williamthorsen/release-kit/config';
|
|
875
887
|
|
|
876
888
|
const config: ReleaseKitConfig = {
|
|
877
889
|
workspaces: [
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
1
|
export { type ChangelogOverrideScope, validateAllChangelogOverrides, type ValidateAllChangelogOverridesInputs, type ValidateAllChangelogOverridesResult, } from './changelogOverrides.js';
|
|
2
|
-
export { defineConfig } from './defineConfig.js';
|
|
3
|
-
export type { LabelSpec, ReleaseKitConfig, RepoLabelsConfig } from './types.js';
|
|
4
2
|
export { formatValidateOverridesResult, type ValidateOverridesCommandResult } from './validateOverridesCommand.js';
|
package/dist/esm/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export function releaseConfigScript(repoType) {
|
|
2
2
|
if (repoType === 'monorepo') {
|
|
3
|
-
return `import { defineConfig } from '@williamthorsen/release-kit';
|
|
3
|
+
return `import { defineConfig } from '@williamthorsen/release-kit/config';
|
|
4
4
|
|
|
5
5
|
export default defineConfig({
|
|
6
6
|
releaseNotes: {
|
|
@@ -22,7 +22,7 @@ export default defineConfig({
|
|
|
22
22
|
});
|
|
23
23
|
`;
|
|
24
24
|
}
|
|
25
|
-
return `import { defineConfig } from '@williamthorsen/release-kit';
|
|
25
|
+
return `import { defineConfig } from '@williamthorsen/release-kit/config';
|
|
26
26
|
|
|
27
27
|
export default defineConfig({
|
|
28
28
|
releaseNotes: {
|
package/dist/esm/loadConfig.js
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
1
9
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
10
|
import path from 'node:path';
|
|
11
|
+
import { pathToFileURL } from 'node:url';
|
|
3
12
|
import { DEFAULT_CHANGELOG_JSON_CONFIG, DEFAULT_PROJECT_TAG_PREFIX, DEFAULT_RELEASE_NOTES_CONFIG, DEFAULT_VERSION_PATTERNS, DEFAULT_WORK_TYPES, } from "./defaults.js";
|
|
4
13
|
import { deriveWorkspaceConfig } from "./deriveWorkspaceConfig.js";
|
|
5
14
|
import { isRecord } from "./typeGuards.js";
|
|
@@ -34,13 +43,8 @@ export async function loadConfig() {
|
|
|
34
43
|
if (!existsSync(absoluteConfigPath)) {
|
|
35
44
|
return undefined;
|
|
36
45
|
}
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const imported = await jiti.import(absoluteConfigPath);
|
|
40
|
-
if (!isRecord(imported)) {
|
|
41
|
-
throw new Error(`Config file must export an object, got ${Array.isArray(imported) ? 'array' : typeof imported}`);
|
|
42
|
-
}
|
|
43
|
-
const resolved = imported.default ?? imported.config;
|
|
46
|
+
const imported = await import(__rewriteRelativeImportExtension(pathToFileURL(absoluteConfigPath).href));
|
|
47
|
+
const resolved = isRecord(imported) ? (imported.default ?? imported.config) : undefined;
|
|
44
48
|
if (resolved === undefined) {
|
|
45
49
|
throw new Error('Config file must have a default export or a named `config` export (e.g., `export default { ... }` or `export const config = { ... }`)');
|
|
46
50
|
}
|
|
@@ -61,7 +61,7 @@ ${labelsBlock}
|
|
|
61
61
|
},`;
|
|
62
62
|
}
|
|
63
63
|
export function repoLabelsConfigScript(scopeLabels) {
|
|
64
|
-
return `import { defineConfig } from '@williamthorsen/release-kit';
|
|
64
|
+
return `import { defineConfig } from '@williamthorsen/release-kit/config';
|
|
65
65
|
|
|
66
66
|
export default defineConfig({
|
|
67
67
|
${renderRepoLabelsBlock(scopeLabels)}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@williamthorsen/release-kit",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.1.0",
|
|
4
4
|
"description": "Version-bumping and changelog-generation toolkit for release workflows",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"homepage": "https://github.com/williamthorsen/node-monorepo-tools/tree/main/packages/release-kit#readme",
|
|
@@ -19,6 +19,10 @@
|
|
|
19
19
|
".": {
|
|
20
20
|
"types": "./dist/esm/index.d.ts",
|
|
21
21
|
"import": "./dist/esm/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./config": {
|
|
24
|
+
"types": "./dist/esm/defineConfig.d.ts",
|
|
25
|
+
"import": "./dist/esm/defineConfig.js"
|
|
22
26
|
}
|
|
23
27
|
},
|
|
24
28
|
"bin": {
|
|
@@ -34,16 +38,15 @@
|
|
|
34
38
|
],
|
|
35
39
|
"dependencies": {
|
|
36
40
|
"glob": "13.0.6",
|
|
37
|
-
"jiti": "2.7.0",
|
|
38
41
|
"json-stringify-pretty-compact": "4.0.0",
|
|
39
42
|
"semver": "7.8.5",
|
|
40
43
|
"yaml": "2.9.0",
|
|
41
44
|
"zod": "4.4.3",
|
|
42
|
-
"@williamthorsen/nmr-core": "0.
|
|
45
|
+
"@williamthorsen/nmr-core": "0.9.0"
|
|
43
46
|
},
|
|
44
47
|
"devDependencies": {
|
|
45
48
|
"@types/semver": "7.7.1",
|
|
46
|
-
"smol-toml": "1.7.
|
|
49
|
+
"smol-toml": "1.7.1"
|
|
47
50
|
},
|
|
48
51
|
"engines": {
|
|
49
52
|
"node": ">=24"
|