@williamthorsen/release-kit 15.0.3 → 16.0.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/.meta/changelog.json +66 -0
- package/.readyup/kits/default.js +13 -13
- package/.readyup/kits/npm-auto-publish.js +4 -4
- package/.readyup/manifest.json +12 -12
- package/CHANGELOG.md +19 -0
- package/README.md +7 -1
- package/dist/esm/applyChangelogOverrides.js +6 -6
- package/dist/esm/assertReleasesOnNpm.js +11 -11
- package/dist/esm/assertTaggedBaseline.js +5 -5
- package/dist/esm/bin/release-kit.js +16 -16
- package/dist/esm/buildChangelogEntries.d.ts +19 -19
- package/dist/esm/buildChangelogEntries.js +40 -36
- package/dist/esm/buildChangelogItem.js +24 -24
- package/dist/esm/buildDependencyGraph.js +23 -23
- package/dist/esm/buildReleasedResult.js +21 -19
- package/dist/esm/buildSyntheticChangelogEntry.js +2 -2
- package/dist/esm/bumpVersion.js +8 -8
- package/dist/esm/changelogArchive.d.ts +1 -1
- package/dist/esm/changelogArchive.js +2 -2
- package/dist/esm/changelogJsonFile.js +5 -5
- package/dist/esm/changelogJsonUtils.js +3 -3
- package/dist/esm/changelogOverrides.d.ts +5 -5
- package/dist/esm/changelogOverrides.js +23 -23
- package/dist/esm/classifyChangelogCommit.js +4 -4
- package/dist/esm/commitCommand.js +3 -3
- package/dist/esm/compareVersions.js +13 -13
- package/dist/esm/configSchema.d.ts +2 -2
- package/dist/esm/configSchema.js +1 -1
- package/dist/esm/createGithubRelease.d.ts +4 -4
- package/dist/esm/createGithubRelease.js +10 -10
- package/dist/esm/createGithubReleaseCommand.js +9 -9
- package/dist/esm/createTags.d.ts +2 -2
- package/dist/esm/createTags.js +8 -8
- package/dist/esm/decideDirectReleases.d.ts +5 -5
- package/dist/esm/decideDirectReleases.js +25 -25
- package/dist/esm/decideRelease.d.ts +1 -1
- package/dist/esm/decideRelease.js +2 -2
- package/dist/esm/deriveDirectoryConfig.d.ts +1 -1
- package/dist/esm/deriveDirectoryConfig.js +18 -18
- package/dist/esm/deriveWorkspaceConfig.js +4 -4
- package/dist/esm/detectPackageManager.js +5 -5
- package/dist/esm/detectUndeclaredTagPrefixes.js +6 -6
- package/dist/esm/enumerateReleaseWindows.d.ts +1 -1
- package/dist/esm/enumerateReleaseWindows.js +7 -7
- package/dist/esm/findTransitiveDependents.js +5 -5
- package/dist/esm/findUnroutedEntryScopes.js +11 -11
- package/dist/esm/format.d.ts +1 -1
- package/dist/esm/format.js +1 -1
- package/dist/esm/formatPrepareFiles.d.ts +3 -3
- package/dist/esm/formatPrepareFiles.js +10 -10
- package/dist/esm/formatPrepareWarnings.js +6 -6
- package/dist/esm/hasPrettierConfig.js +2 -2
- package/dist/esm/init/checks.js +5 -3
- package/dist/esm/init/detectRepoType.js +3 -3
- package/dist/esm/init/initCommand.d.ts +4 -4
- package/dist/esm/init/initCommand.js +7 -7
- package/dist/esm/init/parseJsonRecord.d.ts +1 -1
- package/dist/esm/init/parseJsonRecord.js +4 -4
- package/dist/esm/init/scaffold.d.ts +4 -4
- package/dist/esm/init/scaffold.js +15 -15
- package/dist/esm/init/templates.d.ts +10 -10
- package/dist/esm/init/templates.js +5 -5
- package/dist/esm/init/updateTemplatesCommand.d.ts +2 -2
- package/dist/esm/init/updateTemplatesCommand.js +14 -12
- package/dist/esm/injectReleaseNotesIntoReadme.d.ts +1 -1
- package/dist/esm/injectReleaseNotesIntoReadme.js +6 -6
- package/dist/esm/injectSection.js +8 -8
- package/dist/esm/loadChangelogOverrides.d.ts +1 -1
- package/dist/esm/loadChangelogOverrides.js +9 -9
- package/dist/esm/loadConfig.d.ts +3 -3
- package/dist/esm/loadConfig.js +10 -10
- package/dist/esm/loadValidatedConfig.js +4 -4
- package/dist/esm/mergeConfig.d.ts +1 -1
- package/dist/esm/mergeConfig.js +27 -27
- package/dist/esm/monorepoConfigAssertions.js +15 -15
- package/dist/esm/npmRegistry.js +4 -4
- package/dist/esm/packsPath.js +3 -3
- package/dist/esm/parseChangeRecordBlock.js +33 -33
- package/dist/esm/parseCommitMessage.js +5 -5
- package/dist/esm/planChangelogFiles.js +8 -8
- package/dist/esm/planReleaseNotesPreviews.js +10 -10
- package/dist/esm/planVersionBump.js +24 -16
- package/dist/esm/prepareArgs.d.ts +9 -9
- package/dist/esm/prepareArgs.js +11 -11
- package/dist/esm/prepareCommand.js +23 -23
- package/dist/esm/prepareComposite.d.ts +4 -4
- package/dist/esm/prepareComposite.js +16 -16
- package/dist/esm/{releasePrepareTargets.d.ts → prepareReleaseTargets.d.ts} +9 -9
- package/dist/esm/{releasePrepareTargets.js → prepareReleaseTargets.js} +40 -40
- package/dist/esm/prepareRunContext.d.ts +1 -1
- package/dist/esm/prepareRunContext.js +5 -5
- package/dist/esm/prepareTarget.d.ts +3 -3
- package/dist/esm/prepareTarget.js +41 -39
- package/dist/esm/previewTagPrefixes.js +19 -19
- package/dist/esm/propagateBumps.js +8 -8
- package/dist/esm/publish.d.ts +2 -2
- package/dist/esm/publish.js +5 -5
- package/dist/esm/publishCommand.js +20 -20
- package/dist/esm/pushCommand.js +8 -8
- package/dist/esm/pushRelease.d.ts +1 -1
- package/dist/esm/pushRelease.js +2 -2
- package/dist/esm/readChangelogSections.d.ts +1 -1
- package/dist/esm/readChangelogSections.js +16 -16
- package/dist/esm/releasePlan.js +25 -25
- package/dist/esm/renderChangelogMarkdown.d.ts +4 -4
- package/dist/esm/renderChangelogMarkdown.js +18 -15
- package/dist/esm/renderReleaseNotes.d.ts +1 -1
- package/dist/esm/renderReleaseNotes.js +16 -16
- package/dist/esm/reportPrepare.js +34 -34
- package/dist/esm/resolveCommandTags.js +9 -9
- package/dist/esm/resolveReleaseDeclaration.d.ts +2 -2
- package/dist/esm/resolveReleaseDeclaration.js +22 -22
- package/dist/esm/resolveReleaseTags.js +17 -15
- package/dist/esm/resolveReleaseTargets.js +2 -2
- package/dist/esm/showTagPrefixesCommand.js +4 -4
- package/dist/esm/sync-labels/generateCommand.d.ts +3 -3
- package/dist/esm/sync-labels/generateCommand.js +10 -10
- package/dist/esm/sync-labels/initCommand.d.ts +3 -3
- package/dist/esm/sync-labels/initCommand.js +15 -15
- package/dist/esm/sync-labels/presets.js +3 -3
- package/dist/esm/sync-labels/resolveLabels.js +13 -13
- package/dist/esm/sync-labels/templates.d.ts +2 -2
- package/dist/esm/sync-labels/templates.js +1 -1
- package/dist/esm/tagCommand.js +4 -4
- package/dist/esm/topologicalSort.d.ts +2 -2
- package/dist/esm/topologicalSort.js +7 -7
- package/dist/esm/types.d.ts +3 -3
- package/dist/esm/validateAllChangelogOverrides.js +9 -9
- package/dist/esm/validateConfig.d.ts +1 -1
- package/dist/esm/validateConfig.js +60 -50
- package/dist/esm/validateOverridesCommand.js +2 -2
- package/docs/changelogs.md +5 -5
- package/docs/configuration.md +1 -1
- package/docs/work-types.md +1 -1
- package/package.json +1 -1
package/.meta/changelog.json
CHANGED
|
@@ -1,4 +1,70 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "16.0.0",
|
|
4
|
+
"date": "2026-10-28",
|
|
5
|
+
"sections": [
|
|
6
|
+
{
|
|
7
|
+
"title": "🎉 Features",
|
|
8
|
+
"audience": "all",
|
|
9
|
+
"items": [
|
|
10
|
+
{
|
|
11
|
+
"description": "Renames the `changelogMarkdown.keepVersions` config key to `changelogMarkdown.keptVersionCount` and makes config validation reject the old key with an error that names the replacement. (#1134)",
|
|
12
|
+
"breaking": true,
|
|
13
|
+
"migration": "Rename `changelogMarkdown.keepVersions` to `changelogMarkdown.keptVersionCount` in `.config/release-kit.config.ts`, keeping the same value.",
|
|
14
|
+
"hash": "3d44603845a461295a5a62eee60cf151b5291f1a",
|
|
15
|
+
"entry": 1
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"title": "♻️ Refactoring",
|
|
21
|
+
"audience": "dev",
|
|
22
|
+
"items": [
|
|
23
|
+
{
|
|
24
|
+
"description": "Renames the boolean options, fields, and parameters in `release-kit` to take an `is`, `has`, `does`, or `should` prefix, such as `dryRun` to `isDryRun` and `exists` to `doesExist`, and leaves every CLI flag spelling unchanged. (#1132)",
|
|
25
|
+
"hash": "dcb78f0657c580eb7c7be94859e4185ae9f3d3be",
|
|
26
|
+
"entry": 1
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"description": "Renames the values and type fields declared in `release-kit`'s source files from the first alphabetically through `prepareTarget.ts` so that each name ends with its kind, such as `parsedJson` for `parsed` and `unreleasedReading` for the history field `unreleased`, without changing behavior. (#1133)",
|
|
30
|
+
"hash": "eae8b6458dca1927393d64626d4731fc7c9f9df1",
|
|
31
|
+
"entry": 1
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"description": "Renames values and type fields across release-kit's source so that each name ends with its kind, such as `applied` to `appliedWrites` and `TargetPrepareOptions.only` to `onlyTargetIds`. (#1134)",
|
|
35
|
+
"hash": "3d44603845a461295a5a62eee60cf151b5291f1a",
|
|
36
|
+
"entry": 2
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"description": "Renames `release-kit`'s source functions and test helpers so that each name starts with a transitive verb that states its action, for example `releasePrepareTargets` to `prepareReleaseTargets` (with its module and test files), `publishWorkflow` to `renderPublishWorkflow`, and `toChangelogEntries` to `convertToChangelogEntries`, without changing the exports of `.` or `./config`. (#1137)",
|
|
40
|
+
"hash": "a84d9ce0652754a417b85c3f9cd14a6e400c7b51",
|
|
41
|
+
"entry": 1
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"description": "Renames identifiers in `release-kit` so that each measurement ends with its unit, such as `timestamp` becoming `timestampSec` on `ReleaseWindow` and `SUBJECT_COLUMN_BUDGET` becoming `SUBJECT_BUDGET_COLUMNS`, and so that obscure abbreviations are spelled out, such as `pkg` becoming `packageJson` and `dep` becoming `dependency`. (#1138)",
|
|
45
|
+
"hash": "f75938c0bfe9365a76b15aa6b4b9d195046c8c78",
|
|
46
|
+
"entry": 1
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"title": "🧪 Tests",
|
|
52
|
+
"audience": "dev",
|
|
53
|
+
"items": [
|
|
54
|
+
{
|
|
55
|
+
"description": "Renames the values declared in release-kit's `src/__tests__` files, from the first one alphabetically through `prepareCommand.unit.test.ts`, so that each name ends with its kind, such as `underlying` to `underlyingError` and `unreleased` to `unreleasedReading`. (#1135)",
|
|
56
|
+
"hash": "b98d26e24e86835ce6edc78f53a964bcc84472fb",
|
|
57
|
+
"entry": 1
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"description": "Suffixes the values declared in release-kit's remaining tests with their kind, such as `known` to `knownFlags`, `silent` to `silencedConsole`, and `actual` to `actualModule`, in the `src/__tests__` files after `prepareCommand.unit.test.ts` and the tests under `src/init/__tests__` and `src/sync-labels/__tests__`. (#1136)",
|
|
61
|
+
"hash": "1e947eb5c2d168ffd3d1cf9cf8b0b4e720eaf991",
|
|
62
|
+
"entry": 1
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
},
|
|
2
68
|
{
|
|
3
69
|
"version": "15.0.3",
|
|
4
70
|
"date": "2026-10-27",
|
package/.readyup/kits/default.js
CHANGED
|
@@ -24,14 +24,14 @@ function isRecord(value) {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
// src/init/parseJsonRecord.ts
|
|
27
|
-
function parseJsonRecord(
|
|
28
|
-
let
|
|
27
|
+
function parseJsonRecord(jsonText) {
|
|
28
|
+
let parsedJson;
|
|
29
29
|
try {
|
|
30
|
-
|
|
30
|
+
parsedJson = JSON.parse(jsonText);
|
|
31
31
|
} catch {
|
|
32
32
|
return void 0;
|
|
33
33
|
}
|
|
34
|
-
return isRecord(
|
|
34
|
+
return isRecord(parsedJson) ? parsedJson : void 0;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
// src/init/detectRepoType.ts
|
|
@@ -40,9 +40,9 @@ function detectRepoType() {
|
|
|
40
40
|
return "monorepo";
|
|
41
41
|
}
|
|
42
42
|
if (existsSync("package.json")) {
|
|
43
|
-
const
|
|
44
|
-
const
|
|
45
|
-
if (
|
|
43
|
+
const manifestJson = readFileSync("package.json", "utf8");
|
|
44
|
+
const packageJson = parseJsonRecord(manifestJson);
|
|
45
|
+
if (packageJson !== void 0 && Array.isArray(packageJson["workspaces"])) {
|
|
46
46
|
return "monorepo";
|
|
47
47
|
}
|
|
48
48
|
}
|
|
@@ -67,9 +67,9 @@ function packsPath(filesField, path) {
|
|
|
67
67
|
var GLOB_TOKEN_PATTERN = /\*\*\/|\*\*|\*|\?|[^*?]+/g;
|
|
68
68
|
function compileEntry(entry) {
|
|
69
69
|
if (entry.startsWith("!")) return void 0;
|
|
70
|
-
const
|
|
71
|
-
if (
|
|
72
|
-
return new RegExp(`^${translateGlob(
|
|
70
|
+
const normalizedEntry = entry.replace(/^\.?\//, "").replace(/\/+$/, "");
|
|
71
|
+
if (normalizedEntry === "") return void 0;
|
|
72
|
+
return new RegExp(`^${translateGlob(normalizedEntry)}$`);
|
|
73
73
|
}
|
|
74
74
|
function isStringArray(value) {
|
|
75
75
|
return Array.isArray(value) && value.every((entry) => typeof entry === "string");
|
|
@@ -105,7 +105,7 @@ function translateGlob(pattern) {
|
|
|
105
105
|
function changelogArchivesAreEnabled() {
|
|
106
106
|
const content = readFile(".config/release-kit.config.ts");
|
|
107
107
|
if (content === void 0) return false;
|
|
108
|
-
return /changelogMarkdown\s*:\s*\{[^}]*
|
|
108
|
+
return /changelogMarkdown\s*:\s*\{[^}]*keptVersionCount\s*:/.test(content);
|
|
109
109
|
}
|
|
110
110
|
function changelogJsonIsEnabled() {
|
|
111
111
|
const content = readFile(".config/release-kit.config.ts");
|
|
@@ -234,7 +234,7 @@ var CREATE_GITHUB_RELEASE_WORKFLOW_HASH_SINGLE = "d6de961de913c67b08dfa7e07f7349
|
|
|
234
234
|
|
|
235
235
|
// .readyup/kits/default.ts
|
|
236
236
|
function getMinVersion() {
|
|
237
|
-
const picked = { "version": "
|
|
237
|
+
const picked = { "version": "16.0.0" };
|
|
238
238
|
if (typeof picked["version"] !== "string") {
|
|
239
239
|
throw new TypeError("release-kit/package.json: 'version' must be a string");
|
|
240
240
|
}
|
|
@@ -405,7 +405,7 @@ var default_default = defineRdyKit({
|
|
|
405
405
|
severity: "warn",
|
|
406
406
|
skip: () => {
|
|
407
407
|
if (!hasPublishablePackages()) return "no publishable packages";
|
|
408
|
-
return !changelogArchivesAreEnabled() && "changelogMarkdown.
|
|
408
|
+
return !changelogArchivesAreEnabled() && "changelogMarkdown.keptVersionCount is not set";
|
|
409
409
|
},
|
|
410
410
|
check: () => packagesShipChangelogArchives(),
|
|
411
411
|
fix: 'Add "changelogs/" to the files field of each affected package.json, so that the links from CHANGELOG.md to its archive files resolve in the published package'
|
|
@@ -60,16 +60,16 @@ function lookUpNpmPackage(packageName, registry) {
|
|
|
60
60
|
return classifyNpmPackageLookup(runNpmJson(args));
|
|
61
61
|
}
|
|
62
62
|
function readNpmError(stdout) {
|
|
63
|
-
let
|
|
63
|
+
let parsedJson;
|
|
64
64
|
try {
|
|
65
|
-
|
|
65
|
+
parsedJson = JSON.parse(stdout);
|
|
66
66
|
} catch {
|
|
67
67
|
return void 0;
|
|
68
68
|
}
|
|
69
|
-
if (!isRecord(
|
|
69
|
+
if (!isRecord(parsedJson) || !isRecord(parsedJson["error"]) || typeof parsedJson["error"]["code"] !== "string") {
|
|
70
70
|
return void 0;
|
|
71
71
|
}
|
|
72
|
-
const { code, summary } =
|
|
72
|
+
const { code, summary } = parsedJson["error"];
|
|
73
73
|
return { code, summary: typeof summary === "string" ? summary : "" };
|
|
74
74
|
}
|
|
75
75
|
function runNpmJson(args) {
|
package/.readyup/manifest.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"checklist": "release-kit",
|
|
8
8
|
"checks": [
|
|
9
9
|
"@williamthorsen/release-kit in devDependencies",
|
|
10
|
-
"@williamthorsen/release-kit >=
|
|
10
|
+
"@williamthorsen/release-kit >= 16.0.0",
|
|
11
11
|
"release.yaml workflow exists",
|
|
12
12
|
"release.yaml matches template",
|
|
13
13
|
"release.yaml does not reference deprecated tag ref",
|
|
@@ -43,12 +43,12 @@
|
|
|
43
43
|
"esbuildVersion": "0.28.2",
|
|
44
44
|
"inputs": [
|
|
45
45
|
{
|
|
46
|
-
"hash": "
|
|
46
|
+
"hash": "56566d0b",
|
|
47
47
|
"kind": "module",
|
|
48
48
|
"path": "kits/default.ts"
|
|
49
49
|
},
|
|
50
50
|
{
|
|
51
|
-
"hash": "
|
|
51
|
+
"hash": "dafe3ffb",
|
|
52
52
|
"kind": "module",
|
|
53
53
|
"path": "lib/changelog-checks.ts"
|
|
54
54
|
},
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"path": "lib/workflow-hashes.ts"
|
|
64
64
|
},
|
|
65
65
|
{
|
|
66
|
-
"hash": "
|
|
66
|
+
"hash": "de7d08de",
|
|
67
67
|
"kind": "inline",
|
|
68
68
|
"path": "../package.json",
|
|
69
69
|
"paths": [
|
|
@@ -71,22 +71,22 @@
|
|
|
71
71
|
]
|
|
72
72
|
},
|
|
73
73
|
{
|
|
74
|
-
"hash": "
|
|
74
|
+
"hash": "694186f4",
|
|
75
75
|
"kind": "module",
|
|
76
76
|
"path": "../src/changelogArchive.ts"
|
|
77
77
|
},
|
|
78
78
|
{
|
|
79
|
-
"hash": "
|
|
79
|
+
"hash": "65fa2f33",
|
|
80
80
|
"kind": "module",
|
|
81
81
|
"path": "../src/init/detectRepoType.ts"
|
|
82
82
|
},
|
|
83
83
|
{
|
|
84
|
-
"hash": "
|
|
84
|
+
"hash": "9ca0f6bf",
|
|
85
85
|
"kind": "module",
|
|
86
86
|
"path": "../src/init/parseJsonRecord.ts"
|
|
87
87
|
},
|
|
88
88
|
{
|
|
89
|
-
"hash": "
|
|
89
|
+
"hash": "2210df36",
|
|
90
90
|
"kind": "module",
|
|
91
91
|
"path": "../src/packsPath.ts"
|
|
92
92
|
},
|
|
@@ -100,8 +100,8 @@
|
|
|
100
100
|
"path": "kits/default.js",
|
|
101
101
|
"readyupVersion": "0.44.0",
|
|
102
102
|
"source": "kits/default.ts",
|
|
103
|
-
"sourceHash": "
|
|
104
|
-
"targetHash": "
|
|
103
|
+
"sourceHash": "56566d0b",
|
|
104
|
+
"targetHash": "43d5913f"
|
|
105
105
|
},
|
|
106
106
|
{
|
|
107
107
|
"checklistChecks": [
|
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
"path": "../src/init/hasProvenance.ts"
|
|
146
146
|
},
|
|
147
147
|
{
|
|
148
|
-
"hash": "
|
|
148
|
+
"hash": "bb8746b3",
|
|
149
149
|
"kind": "module",
|
|
150
150
|
"path": "../src/npmRegistry.ts"
|
|
151
151
|
},
|
|
@@ -160,7 +160,7 @@
|
|
|
160
160
|
"readyupVersion": "0.44.0",
|
|
161
161
|
"source": "kits/npm-auto-publish.ts",
|
|
162
162
|
"sourceHash": "682fdd4a",
|
|
163
|
-
"targetHash": "
|
|
163
|
+
"targetHash": "84f31b6d"
|
|
164
164
|
}
|
|
165
165
|
]
|
|
166
166
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## 16.0.0 — 2026-10-28
|
|
6
|
+
|
|
7
|
+
### 🎉 Features
|
|
8
|
+
|
|
9
|
+
- 🚨 **Breaking:** Renames the `changelogMarkdown.keepVersions` config key to `changelogMarkdown.keptVersionCount` and makes config validation reject the old key with an error that names the replacement. (#1134)
|
|
10
|
+
|
|
11
|
+
### ♻️ Refactoring
|
|
12
|
+
|
|
13
|
+
- Renames the boolean options, fields, and parameters in `release-kit` to take an `is`, `has`, `does`, or `should` prefix, such as `dryRun` to `isDryRun` and `exists` to `doesExist`, and leaves every CLI flag spelling unchanged. (#1132)
|
|
14
|
+
- Renames the values and type fields declared in `release-kit`'s source files from the first alphabetically through `prepareTarget.ts` so that each name ends with its kind, such as `parsedJson` for `parsed` and `unreleasedReading` for the history field `unreleased`, without changing behavior. (#1133)
|
|
15
|
+
- Renames values and type fields across release-kit's source so that each name ends with its kind, such as `applied` to `appliedWrites` and `TargetPrepareOptions.only` to `onlyTargetIds`. (#1134)
|
|
16
|
+
- Renames `release-kit`'s source functions and test helpers so that each name starts with a transitive verb that states its action, for example `releasePrepareTargets` to `prepareReleaseTargets` (with its module and test files), `publishWorkflow` to `renderPublishWorkflow`, and `toChangelogEntries` to `convertToChangelogEntries`, without changing the exports of `.` or `./config`. (#1137)
|
|
17
|
+
- Renames identifiers in `release-kit` so that each measurement ends with its unit, such as `timestamp` becoming `timestampSec` on `ReleaseWindow` and `SUBJECT_COLUMN_BUDGET` becoming `SUBJECT_BUDGET_COLUMNS`, and so that obscure abbreviations are spelled out, such as `pkg` becoming `packageJson` and `dep` becoming `dependency`. (#1138)
|
|
18
|
+
|
|
19
|
+
### 🧪 Tests
|
|
20
|
+
|
|
21
|
+
- Renames the values declared in release-kit's `src/__tests__` files, from the first one alphabetically through `prepareCommand.unit.test.ts`, so that each name ends with its kind, such as `underlying` to `underlyingError` and `unreleased` to `unreleasedReading`. (#1135)
|
|
22
|
+
- Suffixes the values declared in release-kit's remaining tests with their kind, such as `known` to `knownFlags`, `silent` to `silencedConsole`, and `actual` to `actualModule`, in the `src/__tests__` files after `prepareCommand.unit.test.ts` and the tests under `src/init/__tests__` and `src/sync-labels/__tests__`. (#1136)
|
|
23
|
+
|
|
5
24
|
## 15.0.3 — 2026-10-27
|
|
6
25
|
|
|
7
26
|
### ♻️ Refactoring
|
package/README.md
CHANGED
|
@@ -6,7 +6,13 @@ Version-bumping and changelog-generation toolkit for release workflows.
|
|
|
6
6
|
|
|
7
7
|
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 the same commit history that decides each bump (with optional [editorial overrides](docs/editorial-overrides.md)).
|
|
8
8
|
|
|
9
|
-
<!-- section:release-notes
|
|
9
|
+
<!-- section:release-notes -->
|
|
10
|
+
## Release notes — v16.0.0 (2026-10-28)
|
|
11
|
+
|
|
12
|
+
### 🎉 Features
|
|
13
|
+
|
|
14
|
+
- 🚨 **Breaking:** Renames the `changelogMarkdown.keepVersions` config key to `changelogMarkdown.keptVersionCount` and makes config validation reject the old key with an error that names the replacement. (#1134)
|
|
15
|
+
<!-- /section:release-notes -->
|
|
10
16
|
|
|
11
17
|
## Installation
|
|
12
18
|
|
|
@@ -55,10 +55,10 @@ export function resolveOverrideKey(overrideKey, positionsByHash) {
|
|
|
55
55
|
if (hashes.length > 1) {
|
|
56
56
|
return { kind: 'ambiguous', hashes };
|
|
57
57
|
}
|
|
58
|
-
const
|
|
58
|
+
const availablePositions = [...(positionsByHash.get(hash) ?? [])];
|
|
59
59
|
const positions = entry === undefined
|
|
60
|
-
?
|
|
61
|
-
:
|
|
60
|
+
? availablePositions.toSorted((left, right) => (left ?? 0) - (right ?? 0))
|
|
61
|
+
: availablePositions.filter((position) => position === entry);
|
|
62
62
|
return positions.length === 0 ? { kind: 'none' } : { kind: 'items', hash, positions };
|
|
63
63
|
}
|
|
64
64
|
function applyOverridesToItems(items, itemIdToOverride) {
|
|
@@ -133,10 +133,10 @@ function resolveOverrideKeys(positionsByHash, overrides) {
|
|
|
133
133
|
}
|
|
134
134
|
const { hash, positions } = resolution;
|
|
135
135
|
if (parseOverrideKey(overrideKey).entry === undefined && positions.length > 1) {
|
|
136
|
-
const
|
|
137
|
-
if (
|
|
136
|
+
const setFields = ['description', 'body'].filter((field) => override[field] !== undefined);
|
|
137
|
+
if (setFields.length > 0) {
|
|
138
138
|
const ordinalKeys = positions.map((position) => `${overrideKey}:${position}`).join(', ');
|
|
139
|
-
errors.push(`Override key '${overrideKey}' sets ${
|
|
139
|
+
errors.push(`Override key '${overrideKey}' sets ${setFields.join(' and ')} on a commit with several items; use ${ordinalKeys}`);
|
|
140
140
|
continue;
|
|
141
141
|
}
|
|
142
142
|
}
|
|
@@ -4,8 +4,8 @@ import { isPublishableManifest } from "./isPublishableManifest.js";
|
|
|
4
4
|
import { lookUpNpmPackage } from "./npmRegistry.js";
|
|
5
5
|
import { isRecord } from "./typeGuards.js";
|
|
6
6
|
export function assertReleasesOnNpm(workspacePaths) {
|
|
7
|
-
const
|
|
8
|
-
const
|
|
7
|
+
const unpublishedCandidates = [];
|
|
8
|
+
const unverifiableCandidates = [];
|
|
9
9
|
for (const workspacePath of workspacePaths) {
|
|
10
10
|
const candidate = buildNpmCandidate(workspacePath);
|
|
11
11
|
if (candidate === undefined) {
|
|
@@ -13,16 +13,16 @@ export function assertReleasesOnNpm(workspacePaths) {
|
|
|
13
13
|
}
|
|
14
14
|
const lookup = lookUpNpmPackage(candidate.name, candidate.registry);
|
|
15
15
|
if (lookup.status === 'unpublished') {
|
|
16
|
-
|
|
16
|
+
unpublishedCandidates.push(candidate);
|
|
17
17
|
}
|
|
18
18
|
else if (lookup.status === 'unverifiable') {
|
|
19
|
-
|
|
19
|
+
unverifiableCandidates.push({ candidate, detail: lookup.detail });
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
-
if (
|
|
22
|
+
if (unpublishedCandidates.length === 0 && unverifiableCandidates.length === 0) {
|
|
23
23
|
return;
|
|
24
24
|
}
|
|
25
|
-
throw new Error(describeRefusal(
|
|
25
|
+
throw new Error(describeRefusal(unpublishedCandidates, unverifiableCandidates));
|
|
26
26
|
}
|
|
27
27
|
function buildNpmCandidate(workspacePath) {
|
|
28
28
|
const manifest = JSON.parse(readFileSync(join(workspacePath, 'package.json'), 'utf8'));
|
|
@@ -37,19 +37,19 @@ function buildNpmCandidate(workspacePath) {
|
|
|
37
37
|
...(typeof registry === 'string' && { registry }),
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
|
-
function describeRefusal(
|
|
40
|
+
function describeRefusal(unpublishedCandidates, unverifiableCandidates) {
|
|
41
41
|
const sections = ['Cannot prepare the release: npm must already have every package that the release publishes.'];
|
|
42
|
-
if (
|
|
42
|
+
if (unpublishedCandidates.length > 0) {
|
|
43
43
|
sections.push([
|
|
44
44
|
'Not on npm yet:',
|
|
45
|
-
...
|
|
45
|
+
...unpublishedCandidates.map(({ name, workspacePath }) => ` - ${name}: run "npm publish --access public" from ${workspacePath}`),
|
|
46
46
|
'Then register each one as a trusted publisher; "rdy run --from npm:@williamthorsen/release-kit npm-auto-publish" prints the command.',
|
|
47
47
|
].join('\n'));
|
|
48
48
|
}
|
|
49
|
-
if (
|
|
49
|
+
if (unverifiableCandidates.length > 0) {
|
|
50
50
|
sections.push([
|
|
51
51
|
'Could not confirm on npm:',
|
|
52
|
-
...
|
|
52
|
+
...unverifiableCandidates.map(({ candidate, detail }) => ` - ${candidate.name}: ${detail}`),
|
|
53
53
|
].join('\n'));
|
|
54
54
|
}
|
|
55
55
|
return sections.join('\n\n');
|
|
@@ -4,10 +4,10 @@ import { readChangelogEntries } from "./changelogJsonUtils.js";
|
|
|
4
4
|
import { readCurrentVersion } from "./planVersionBump.js";
|
|
5
5
|
import { readChangelogSections } from "./readChangelogSections.js";
|
|
6
6
|
export function assertTaggedBaseline(findings) {
|
|
7
|
-
const
|
|
8
|
-
if (
|
|
7
|
+
const untaggedFindings = findings.filter((finding) => finding !== undefined);
|
|
8
|
+
if (untaggedFindings.length === 0)
|
|
9
9
|
return;
|
|
10
|
-
const lines =
|
|
10
|
+
const lines = untaggedFindings.map(({ label, version, tag }) => ` - ${label}: ${version} (create tag ${tag})`);
|
|
11
11
|
throw new Error([
|
|
12
12
|
'The current version is recorded in the changelog, but its tag is not the previous tag reachable from HEAD:',
|
|
13
13
|
...lines,
|
|
@@ -31,9 +31,9 @@ export function findUntaggedBaseline(target, config) {
|
|
|
31
31
|
function readRecordedVersions(changelogPaths, config) {
|
|
32
32
|
const versions = new Set();
|
|
33
33
|
for (const changelogPath of changelogPaths) {
|
|
34
|
-
const {
|
|
34
|
+
const { versionedSections } = readChangelogSections(join(changelogPath, 'CHANGELOG.md'));
|
|
35
35
|
const entries = readChangelogEntries(resolveChangelogJsonPath(config, changelogPath)) ?? [];
|
|
36
|
-
for (const { version } of [...
|
|
36
|
+
for (const { version } of [...versionedSections, ...entries]) {
|
|
37
37
|
versions.add(version);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -127,12 +127,12 @@ if (command === 'init') {
|
|
|
127
127
|
}
|
|
128
128
|
enterRepoRootOrExit();
|
|
129
129
|
const initFlagSchema = {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
130
|
+
isDryRun: { long: '--dry-run', type: 'boolean' },
|
|
131
|
+
shouldForce: { long: '--force', type: 'boolean' },
|
|
132
|
+
shouldScaffoldConfig: { long: '--with-config', type: 'boolean' },
|
|
133
133
|
};
|
|
134
|
-
const {
|
|
135
|
-
const exitCode = initCommand({
|
|
134
|
+
const { isDryRun, shouldForce, shouldScaffoldConfig } = parseArgsOrExit(flags, initFlagSchema).flags;
|
|
135
|
+
const exitCode = initCommand({ isDryRun, shouldForce, styles, shouldScaffoldConfig });
|
|
136
136
|
process.exit(exitCode);
|
|
137
137
|
}
|
|
138
138
|
if (command === 'update-templates') {
|
|
@@ -142,10 +142,10 @@ if (command === 'update-templates') {
|
|
|
142
142
|
}
|
|
143
143
|
enterRepoRootOrExit();
|
|
144
144
|
const updateTemplatesFlagSchema = {
|
|
145
|
-
|
|
145
|
+
isDryRun: { long: '--dry-run', type: 'boolean' },
|
|
146
146
|
};
|
|
147
|
-
const {
|
|
148
|
-
const exitCode = updateTemplatesCommand({
|
|
147
|
+
const { isDryRun } = parseArgsOrExit(flags, updateTemplatesFlagSchema).flags;
|
|
148
|
+
const exitCode = updateTemplatesCommand({ isDryRun, styles });
|
|
149
149
|
process.exit(exitCode);
|
|
150
150
|
}
|
|
151
151
|
if (command === 'sync-labels') {
|
|
@@ -163,15 +163,15 @@ if (command === 'sync-labels') {
|
|
|
163
163
|
const { invocationDir } = enterRepoRootOrExit();
|
|
164
164
|
const syncLabelsInitFlagSchema = {
|
|
165
165
|
...configFlagSchema,
|
|
166
|
-
|
|
167
|
-
|
|
166
|
+
isDryRun: { long: '--dry-run', type: 'boolean' },
|
|
167
|
+
shouldForce: { long: '--force', type: 'boolean' },
|
|
168
168
|
};
|
|
169
|
-
const { config,
|
|
169
|
+
const { config, isDryRun, shouldForce } = parseArgsOrExit(subflags, syncLabelsInitFlagSchema).flags;
|
|
170
170
|
const configPath = resolveConfigFlag(config, invocationDir);
|
|
171
171
|
const exitCode = await syncLabelsInitCommand({
|
|
172
172
|
...(configPath !== undefined && { configPath }),
|
|
173
|
-
|
|
174
|
-
|
|
173
|
+
isDryRun,
|
|
174
|
+
shouldForce,
|
|
175
175
|
styles,
|
|
176
176
|
});
|
|
177
177
|
process.exit(exitCode);
|
|
@@ -184,11 +184,11 @@ if (command === 'sync-labels') {
|
|
|
184
184
|
const { invocationDir } = enterRepoRootOrExit();
|
|
185
185
|
const generateFlagSchema = {
|
|
186
186
|
...configFlagSchema,
|
|
187
|
-
|
|
187
|
+
shouldCheck: { long: '--check', type: 'boolean' },
|
|
188
188
|
};
|
|
189
|
-
const {
|
|
189
|
+
const { shouldCheck, config } = parseArgsOrExit(subflags, generateFlagSchema).flags;
|
|
190
190
|
const configPath = resolveConfigFlag(config, invocationDir);
|
|
191
|
-
const exitCode = await generateCommand({
|
|
191
|
+
const exitCode = await generateCommand({ shouldCheck, ...(configPath !== undefined && { configPath }), styles });
|
|
192
192
|
process.exit(exitCode);
|
|
193
193
|
}
|
|
194
194
|
if (subcommand === 'sync') {
|
|
@@ -5,12 +5,30 @@ import type { ChangelogEntry, ChangelogSection, ReleaseSettings, ReleaseType } f
|
|
|
5
5
|
/**
|
|
6
6
|
* Builds structured changelog entries from the release windows of git history, naming the unreleased window `tag`.
|
|
7
7
|
*
|
|
8
|
-
* Composes `readReleaseHistory` and `
|
|
8
|
+
* Composes `readReleaseHistory` and `convertToChangelogEntries` for a caller that knows the tag before it reads.
|
|
9
9
|
*/
|
|
10
10
|
export declare function buildChangelogEntries(config: ReleaseHistoryConfig, tag: string, options: GenerateChangelogOptions): {
|
|
11
11
|
entries: ChangelogEntry[];
|
|
12
12
|
diagnostics: ChangelogDiagnostics;
|
|
13
13
|
};
|
|
14
|
+
/** Labels the unreleased window of `history` with `tag` and returns the entries of every window, newest first. */
|
|
15
|
+
export declare function convertToChangelogEntries(history: ReleaseHistory, tag: string): ChangelogEntry[];
|
|
16
|
+
/** One read of a scope's release windows. */
|
|
17
|
+
export interface ReleaseHistory {
|
|
18
|
+
/** The newest matching tag that HEAD reaches; undefined when none does. */
|
|
19
|
+
previousTag: string | undefined;
|
|
20
|
+
/** Entries of the released windows, newest first; a window that doesn't yield any item contributes none. */
|
|
21
|
+
releasedEntries: ChangelogEntry[];
|
|
22
|
+
unreleasedReading: UnreleasedWindowReading;
|
|
23
|
+
}
|
|
24
|
+
/** The configuration that `readReleaseHistory` reads. */
|
|
25
|
+
export type ReleaseHistoryConfig = Pick<ReleaseSettings, 'breakingPolicies' | 'changelogJson' | 'scopeAliases' | 'versionPatterns' | 'workTypes'>;
|
|
26
|
+
/**
|
|
27
|
+
* Returns the entries that a direct release tagged `tag` records: those of `convertToChangelogEntries`, or, when the
|
|
28
|
+
* unreleased window doesn't yield any item, the synthetic "Forced version bump." entry dated `today` ahead of the
|
|
29
|
+
* released entries.
|
|
30
|
+
*/
|
|
31
|
+
export declare function convertToReleaseEntries(history: ReleaseHistory, tag: string, today: string): ChangelogEntry[];
|
|
14
32
|
/**
|
|
15
33
|
* Reads a scope's release windows once and returns the changelog items of every window, with what the unreleased
|
|
16
34
|
* window decides: its commits, its bump, and its diagnostics.
|
|
@@ -21,16 +39,6 @@ export declare function buildChangelogEntries(config: ReleaseHistoryConfig, tag:
|
|
|
21
39
|
* only for the unreleased window, since the released windows were reported when they were prepared.
|
|
22
40
|
*/
|
|
23
41
|
export declare function readReleaseHistory(config: ReleaseHistoryConfig, options: GenerateChangelogOptions): ReleaseHistory;
|
|
24
|
-
/** One read of a scope's release windows. */
|
|
25
|
-
export interface ReleaseHistory {
|
|
26
|
-
/** The newest matching tag that HEAD reaches; undefined when none does. */
|
|
27
|
-
previousTag: string | undefined;
|
|
28
|
-
/** Entries of the released windows, newest first; a window that doesn't yield any item contributes none. */
|
|
29
|
-
releasedEntries: ChangelogEntry[];
|
|
30
|
-
unreleased: UnreleasedWindowReading;
|
|
31
|
-
}
|
|
32
|
-
/** The configuration that `readReleaseHistory` reads. */
|
|
33
|
-
export type ReleaseHistoryConfig = Pick<ReleaseSettings, 'breakingPolicies' | 'changelogJson' | 'scopeAliases' | 'versionPatterns' | 'workTypes'>;
|
|
34
42
|
/**
|
|
35
43
|
* Strips a section title down to its bare name.
|
|
36
44
|
*
|
|
@@ -39,14 +47,6 @@ export type ReleaseHistoryConfig = Pick<ReleaseSettings, 'breakingPolicies' | 'c
|
|
|
39
47
|
* through this helper lets the two forms match.
|
|
40
48
|
*/
|
|
41
49
|
export declare function stripGroupDecorations(group: string): string;
|
|
42
|
-
/** Labels the unreleased window of `history` with `tag` and returns the entries of every window, newest first. */
|
|
43
|
-
export declare function toChangelogEntries(history: ReleaseHistory, tag: string): ChangelogEntry[];
|
|
44
|
-
/**
|
|
45
|
-
* Returns the entries that a direct release tagged `tag` records: those of `toChangelogEntries`, or, when the
|
|
46
|
-
* unreleased window doesn't yield any item, the synthetic "Forced version bump." entry dated `today` ahead of the
|
|
47
|
-
* released entries.
|
|
48
|
-
*/
|
|
49
|
-
export declare function toReleaseEntries(history: ReleaseHistory, tag: string, today: string): ChangelogEntry[];
|
|
50
50
|
/** The unreleased window: its changelog sections and commits, and the bump and diagnostics that they determine. */
|
|
51
51
|
export interface UnreleasedWindowReading {
|
|
52
52
|
/** The highest bump that the window's items call for; undefined when the window doesn't yield any item. */
|