@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 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 --><!-- /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) via [jiti](https://github.com/unjs/jiti) and merges it with discovered defaults.
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: [
@@ -1,2 +1,3 @@
1
1
  import type { ReleaseKitConfig } from './types.js';
2
+ export type { LabelSpec, ReleaseKitConfig, RepoLabelsConfig } from './types.js';
2
3
  export declare function defineConfig(config: ReleaseKitConfig): ReleaseKitConfig;
@@ -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,3 +1,2 @@
1
1
  export { validateAllChangelogOverrides, } from "./changelogOverrides.js";
2
- export { defineConfig } from "./defineConfig.js";
3
2
  export { formatValidateOverridesResult } from "./validateOverridesCommand.js";
@@ -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: {
@@ -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 { createJiti } = await import('jiti');
38
- const jiti = createJiti(import.meta.url);
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": "9.1.1",
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.7.3"
45
+ "@williamthorsen/nmr-core": "0.9.0"
43
46
  },
44
47
  "devDependencies": {
45
48
  "@types/semver": "7.7.1",
46
- "smol-toml": "1.7.0"
49
+ "smol-toml": "1.7.1"
47
50
  },
48
51
  "engines": {
49
52
  "node": ">=24"