@williamthorsen/release-kit 4.8.0 → 5.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 +134 -4
- package/README.md +404 -40
- package/cliff.toml.template +2 -1
- package/dist/esm/.cache +1 -1
- package/dist/esm/assertCleanWorkingTree.js +1 -1
- package/dist/esm/bin/release-kit.js +45 -14
- package/dist/esm/buildChangelogEntries.d.ts +3 -0
- package/dist/esm/{generateChangelogJson.js → buildChangelogEntries.js} +40 -77
- package/dist/esm/buildDependencyGraph.d.ts +4 -3
- package/dist/esm/buildDependencyGraph.js +18 -11
- package/dist/esm/buildReleaseSummary.js +12 -4
- package/dist/esm/buildSyntheticChangelogEntry.d.ts +5 -0
- package/dist/esm/buildSyntheticChangelogEntry.js +13 -0
- package/dist/esm/bumpAllVersions.d.ts +1 -0
- package/dist/esm/bumpAllVersions.js +16 -2
- package/dist/esm/bumpVersion.js +3 -0
- package/dist/esm/changelogJsonFile.d.ts +4 -0
- package/dist/esm/changelogJsonFile.js +68 -0
- package/dist/esm/commitCommand.js +1 -1
- package/dist/esm/compareVersions.d.ts +1 -0
- package/dist/esm/compareVersions.js +27 -0
- package/dist/esm/createGithubRelease.d.ts +6 -2
- package/dist/esm/createGithubRelease.js +17 -17
- package/dist/esm/createGithubReleaseCommand.d.ts +1 -0
- package/dist/esm/createGithubReleaseCommand.js +41 -0
- package/dist/esm/decideRelease.d.ts +25 -0
- package/dist/esm/decideRelease.js +28 -0
- package/dist/esm/defaults.d.ts +1 -0
- package/dist/esm/defaults.js +7 -3
- package/dist/esm/deriveWorkspaceConfig.d.ts +2 -0
- package/dist/esm/deriveWorkspaceConfig.js +37 -0
- package/dist/esm/detectUndeclaredTagPrefixes.d.ts +7 -0
- package/dist/esm/detectUndeclaredTagPrefixes.js +46 -0
- package/dist/esm/generateChangelogs.d.ts +1 -1
- package/dist/esm/generateChangelogs.js +14 -3
- package/dist/esm/getCommitsSinceTarget.d.ts +1 -1
- package/dist/esm/getCommitsSinceTarget.js +8 -4
- package/dist/esm/index.d.ts +2 -39
- package/dist/esm/index.js +0 -75
- package/dist/esm/init/initCommand.js +1 -1
- package/dist/esm/init/scaffold.d.ts +1 -1
- package/dist/esm/init/scaffold.js +8 -5
- package/dist/esm/init/templates.d.ts +1 -0
- package/dist/esm/init/templates.js +35 -5
- package/dist/esm/injectReleaseNotesIntoReadme.d.ts +6 -1
- package/dist/esm/injectReleaseNotesIntoReadme.js +20 -7
- package/dist/esm/loadConfig.d.ts +12 -2
- package/dist/esm/loadConfig.js +161 -14
- package/dist/esm/parseRequestedTags.d.ts +1 -0
- package/dist/esm/parseRequestedTags.js +10 -0
- package/dist/esm/prepareCommand.d.ts +3 -1
- package/dist/esm/prepareCommand.js +121 -31
- package/dist/esm/previewTagPrefixes.d.ts +30 -0
- package/dist/esm/previewTagPrefixes.js +120 -0
- package/dist/esm/propagateBumps.d.ts +1 -0
- package/dist/esm/propagateBumps.js +1 -1
- package/dist/esm/publish.d.ts +0 -1
- package/dist/esm/publish.js +3 -3
- package/dist/esm/publishCommand.js +18 -14
- package/dist/esm/pushCommand.js +5 -4
- package/dist/esm/readCurrentVersion.d.ts +1 -0
- package/dist/esm/readCurrentVersion.js +21 -0
- package/dist/esm/releasePrepare.d.ts +2 -0
- package/dist/esm/releasePrepare.js +140 -54
- package/dist/esm/releasePrepareMono.js +312 -143
- package/dist/esm/releasePrepareProject.d.ts +9 -0
- package/dist/esm/releasePrepareProject.js +109 -0
- package/dist/esm/renderReleaseNotes.d.ts +1 -0
- package/dist/esm/renderReleaseNotes.js +29 -2
- package/dist/esm/reportPrepare.js +146 -73
- package/dist/esm/resolveCliffConfigPath.js +1 -1
- package/dist/esm/resolveCommandTags.d.ts +1 -1
- package/dist/esm/resolveCommandTags.js +17 -13
- package/dist/esm/resolveReleaseNotesConfig.d.ts +8 -1
- package/dist/esm/resolveReleaseNotesConfig.js +17 -7
- package/dist/esm/resolveReleaseTags.d.ts +2 -1
- package/dist/esm/resolveReleaseTags.js +19 -14
- package/dist/esm/showTagPrefixesCommand.d.ts +1 -0
- package/dist/esm/showTagPrefixesCommand.js +84 -0
- package/dist/esm/sync-labels/initCommand.js +1 -1
- package/dist/esm/sync-labels/presets.js +1 -1
- package/dist/esm/tagCommand.js +1 -1
- package/dist/esm/types.d.ts +77 -19
- package/dist/esm/validateConfig.js +205 -36
- package/dist/esm/validateOnlyExcludesStrandedDependents.d.ts +14 -0
- package/dist/esm/validateOnlyExcludesStrandedDependents.js +109 -0
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/writeReleaseNotesPreviews.d.ts +18 -0
- package/dist/esm/writeReleaseNotesPreviews.js +65 -0
- package/package.json +5 -2
- package/presets/labels/common.yaml +9 -6
- package/schemas/label-map.json +24 -0
- package/dist/esm/component.d.ts +0 -2
- package/dist/esm/component.js +0 -14
- package/dist/esm/findPackageRoot.d.ts +0 -1
- package/dist/esm/findPackageRoot.js +0 -17
- package/dist/esm/generateChangelogJson.d.ts +0 -7
- package/dist/esm/githubReleaseCommand.d.ts +0 -1
- package/dist/esm/githubReleaseCommand.js +0 -35
|
@@ -1,35 +1,51 @@
|
|
|
1
1
|
import { execSync } from "node:child_process";
|
|
2
|
-
import {
|
|
2
|
+
import { buildChangelogEntries } from "./buildChangelogEntries.js";
|
|
3
3
|
import { buildDependencyGraph } from "./buildDependencyGraph.js";
|
|
4
|
-
import {
|
|
4
|
+
import { buildSyntheticChangelogEntry } from "./buildSyntheticChangelogEntry.js";
|
|
5
|
+
import { bumpAllVersions, setAllVersions } from "./bumpAllVersions.js";
|
|
6
|
+
import { resolveChangelogJsonPath, upsertChangelogJson } from "./changelogJsonFile.js";
|
|
7
|
+
import { isForwardVersion } from "./compareVersions.js";
|
|
8
|
+
import { decideRelease } from "./decideRelease.js";
|
|
5
9
|
import { DEFAULT_VERSION_PATTERNS, DEFAULT_WORK_TYPES } from "./defaults.js";
|
|
6
|
-
import {
|
|
7
|
-
import { generateChangelogJson, generateSyntheticChangelogJson } from "./generateChangelogJson.js";
|
|
10
|
+
import { detectUndeclaredTagPrefixes } from "./detectUndeclaredTagPrefixes.js";
|
|
8
11
|
import { buildTagPattern, generateChangelog } from "./generateChangelogs.js";
|
|
9
12
|
import { getCommitsSinceTarget } from "./getCommitsSinceTarget.js";
|
|
10
13
|
import { hasPrettierConfig } from "./hasPrettierConfig.js";
|
|
14
|
+
import { resolveWorkTypes } from "./loadConfig.js";
|
|
11
15
|
import { propagateBumps } from "./propagateBumps.js";
|
|
16
|
+
import { readCurrentVersion } from "./readCurrentVersion.js";
|
|
17
|
+
import { releasePrepareProject } from "./releasePrepareProject.js";
|
|
18
|
+
import { deriveSectionOrder } from "./resolveReleaseNotesConfig.js";
|
|
19
|
+
import { writeReleaseNotesPreviews } from "./writeReleaseNotesPreviews.js";
|
|
12
20
|
import { writeSyntheticChangelog } from "./writeSyntheticChangelog.js";
|
|
13
21
|
function releasePrepareMono(config, options) {
|
|
14
|
-
const { dryRun } = options;
|
|
22
|
+
const { dryRun, withReleaseNotes } = options;
|
|
23
|
+
if (withReleaseNotes === true && !config.changelogJson.enabled) {
|
|
24
|
+
console.warn("Warning: --with-release-notes requires changelogJson.enabled; skipping preview generation");
|
|
25
|
+
}
|
|
26
|
+
const sectionOrder = deriveSectionOrder(resolveWorkTypes(config.workTypes));
|
|
15
27
|
const { directBumps, directResults, skippedResults, currentVersions } = determineDirectBumps(config, options);
|
|
16
28
|
const previousTags = /* @__PURE__ */ new Map();
|
|
17
29
|
for (const result of directResults.values()) {
|
|
18
|
-
previousTags.set(result.
|
|
30
|
+
previousTags.set(result.workspace.dir, result.tag);
|
|
19
31
|
}
|
|
20
32
|
for (const skipped of skippedResults) {
|
|
21
|
-
previousTags.set(skipped.
|
|
33
|
+
previousTags.set(skipped.workspace.dir, skipped.tag);
|
|
22
34
|
}
|
|
23
|
-
const graph = buildDependencyGraph(config.
|
|
35
|
+
const graph = buildDependencyGraph(config.workspaces);
|
|
24
36
|
const fullReleaseSet = propagateBumps(directBumps, graph, currentVersions);
|
|
25
37
|
const { sorted: sortedDirs, cyclicDirs } = topologicalSort(fullReleaseSet, graph);
|
|
26
38
|
const warnings = [];
|
|
27
39
|
if (cyclicDirs.length > 0) {
|
|
28
40
|
warnings.push(
|
|
29
|
-
`Circular workspace dependencies detected among: ${cyclicDirs.join(", ")}. Propagation metadata may be incomplete for these
|
|
41
|
+
`Circular workspace dependencies detected among: ${cyclicDirs.join(", ")}. Propagation metadata may be incomplete for these workspaces.`
|
|
30
42
|
);
|
|
31
43
|
}
|
|
32
|
-
const
|
|
44
|
+
const workspaces = collectSkippedWorkspaces(skippedResults, fullReleaseSet);
|
|
45
|
+
const previewOptions = {
|
|
46
|
+
enabled: withReleaseNotes === true && config.changelogJson.enabled,
|
|
47
|
+
sectionOrder
|
|
48
|
+
};
|
|
33
49
|
const { tags, modifiedFiles } = executeReleaseSet(
|
|
34
50
|
sortedDirs,
|
|
35
51
|
fullReleaseSet,
|
|
@@ -37,108 +53,148 @@ function releasePrepareMono(config, options) {
|
|
|
37
53
|
directResults,
|
|
38
54
|
previousTags,
|
|
39
55
|
dryRun,
|
|
40
|
-
|
|
56
|
+
workspaces,
|
|
57
|
+
previewOptions
|
|
41
58
|
);
|
|
42
|
-
const configOrder = new Map(config.
|
|
43
|
-
|
|
59
|
+
const configOrder = new Map(config.workspaces.map((w, i) => [w.dir, i]));
|
|
60
|
+
workspaces.sort((a, b) => {
|
|
44
61
|
const orderA = configOrder.get(a.name ?? "") ?? 0;
|
|
45
62
|
const orderB = configOrder.get(b.name ?? "") ?? 0;
|
|
46
63
|
return orderA - orderB;
|
|
47
64
|
});
|
|
65
|
+
let project;
|
|
66
|
+
if (config.project !== void 0) {
|
|
67
|
+
project = tryStage("project release stage", () => releasePrepareProject({ config, options, modifiedFiles, tags }));
|
|
68
|
+
}
|
|
48
69
|
const formatCommand = runFormatCommand(config, tags, modifiedFiles, dryRun);
|
|
49
70
|
return {
|
|
50
|
-
|
|
71
|
+
workspaces,
|
|
51
72
|
tags,
|
|
52
73
|
formatCommand,
|
|
53
74
|
dryRun,
|
|
54
|
-
...warnings.length > 0 ? { warnings } : {}
|
|
75
|
+
...warnings.length > 0 ? { warnings } : {},
|
|
76
|
+
...project === void 0 ? {} : { project }
|
|
55
77
|
};
|
|
56
78
|
}
|
|
57
79
|
function determineDirectBumps(config, options) {
|
|
58
|
-
const { force, bumpOverride } = options;
|
|
80
|
+
const { force, bumpOverride, setVersion } = options;
|
|
81
|
+
if (setVersion !== void 0 && config.workspaces.length !== 1) {
|
|
82
|
+
throw new Error(`--set-version requires exactly one workspace; received ${config.workspaces.length}`);
|
|
83
|
+
}
|
|
59
84
|
const workTypes = config.workTypes ?? { ...DEFAULT_WORK_TYPES };
|
|
60
85
|
const versionPatterns = config.versionPatterns ?? { ...DEFAULT_VERSION_PATTERNS };
|
|
61
86
|
const directBumps = /* @__PURE__ */ new Map();
|
|
62
87
|
const directResults = /* @__PURE__ */ new Map();
|
|
63
88
|
const skippedResults = [];
|
|
64
89
|
const currentVersions = /* @__PURE__ */ new Map();
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
90
|
+
const hintState = { emitted: false };
|
|
91
|
+
const knownPrefixes = config.workspaces.flatMap(getAllTagPrefixes);
|
|
92
|
+
for (const workspace of config.workspaces) {
|
|
93
|
+
const name = workspace.dir;
|
|
94
|
+
const stageLabel = workspaceStageLabel(workspace.dir);
|
|
95
|
+
const { tag, commits } = tryStage(
|
|
96
|
+
stageLabel,
|
|
97
|
+
() => getCommitsSinceTarget(getAllTagPrefixes(workspace), workspace.paths)
|
|
98
|
+
);
|
|
68
99
|
const since = tag === void 0 ? "(no previous release found)" : `since ${tag}`;
|
|
69
|
-
|
|
100
|
+
if (tag === void 0) {
|
|
101
|
+
maybeEmitBaselineHint(workspace, knownPrefixes, hintState);
|
|
102
|
+
}
|
|
103
|
+
const primaryPackageFile = workspace.packageFiles[0];
|
|
70
104
|
if (primaryPackageFile !== void 0) {
|
|
71
|
-
const currentVersion = readCurrentVersion(primaryPackageFile);
|
|
105
|
+
const currentVersion = tryStage(stageLabel, () => readCurrentVersion(primaryPackageFile));
|
|
72
106
|
if (currentVersion !== void 0) {
|
|
73
|
-
currentVersions.set(
|
|
107
|
+
currentVersions.set(workspace.dir, currentVersion);
|
|
74
108
|
}
|
|
75
109
|
}
|
|
76
|
-
if (
|
|
77
|
-
|
|
78
|
-
|
|
110
|
+
if (setVersion !== void 0) {
|
|
111
|
+
const currentVersion = currentVersions.get(workspace.dir);
|
|
112
|
+
if (currentVersion === void 0) {
|
|
113
|
+
throw new Error(
|
|
114
|
+
`Cannot validate --set-version: failed to read current version from ${primaryPackageFile ?? "(no package file)"}`
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
if (!isForwardVersion(currentVersion, setVersion)) {
|
|
118
|
+
throw new Error(`--set-version ${setVersion} is not greater than current version ${currentVersion}`);
|
|
119
|
+
}
|
|
120
|
+
directBumps.set(workspace.dir, { releaseType: "patch", newVersionOverride: setVersion });
|
|
121
|
+
directResults.set(workspace.dir, {
|
|
122
|
+
workspace,
|
|
79
123
|
tag,
|
|
80
|
-
|
|
124
|
+
commits,
|
|
125
|
+
releaseType: void 0,
|
|
81
126
|
parsedCommitCount: void 0,
|
|
82
127
|
unparseableCommits: void 0,
|
|
83
|
-
|
|
128
|
+
bumpOverride: void 0,
|
|
129
|
+
setVersion
|
|
84
130
|
});
|
|
85
131
|
continue;
|
|
86
132
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
133
|
+
const decision = tryStage(
|
|
134
|
+
stageLabel,
|
|
135
|
+
() => decideRelease({
|
|
136
|
+
commits,
|
|
137
|
+
force,
|
|
138
|
+
bumpOverride,
|
|
139
|
+
workTypes,
|
|
140
|
+
versionPatterns,
|
|
141
|
+
scopeAliases: config.scopeAliases,
|
|
142
|
+
skipReasons: {
|
|
143
|
+
noCommits: `No commits for ${name} ${since}. Pass --force to release at patch. Skipping.`,
|
|
144
|
+
noBumpWorthy: `No bump-worthy commits for ${name} ${since}. Pass --force to release at patch (or --force --bump=X for a different level). Skipping.`
|
|
145
|
+
}
|
|
146
|
+
})
|
|
147
|
+
);
|
|
148
|
+
if (decision.outcome === "skip") {
|
|
99
149
|
skippedResults.push({
|
|
100
|
-
|
|
150
|
+
workspace,
|
|
101
151
|
tag,
|
|
102
152
|
commitCount: commits.length,
|
|
103
|
-
parsedCommitCount,
|
|
104
|
-
unparseableCommits,
|
|
105
|
-
skipReason:
|
|
153
|
+
parsedCommitCount: decision.parsedCommitCount,
|
|
154
|
+
unparseableCommits: decision.unparseableCommits,
|
|
155
|
+
skipReason: decision.skipReason
|
|
106
156
|
});
|
|
107
157
|
continue;
|
|
108
158
|
}
|
|
109
|
-
directBumps.set(
|
|
110
|
-
directResults.set(
|
|
111
|
-
|
|
159
|
+
directBumps.set(workspace.dir, { releaseType: decision.releaseType });
|
|
160
|
+
directResults.set(workspace.dir, {
|
|
161
|
+
workspace,
|
|
112
162
|
tag,
|
|
113
163
|
commits,
|
|
114
|
-
releaseType,
|
|
115
|
-
parsedCommitCount,
|
|
116
|
-
unparseableCommits
|
|
164
|
+
releaseType: decision.releaseType,
|
|
165
|
+
parsedCommitCount: decision.parsedCommitCount,
|
|
166
|
+
unparseableCommits: decision.unparseableCommits,
|
|
167
|
+
bumpOverride
|
|
117
168
|
});
|
|
118
169
|
}
|
|
119
170
|
return { directBumps, directResults, skippedResults, currentVersions };
|
|
120
171
|
}
|
|
121
|
-
function
|
|
122
|
-
const
|
|
172
|
+
function collectSkippedWorkspaces(skippedResults, fullReleaseSet) {
|
|
173
|
+
const workspaces = [];
|
|
123
174
|
for (const skipped of skippedResults) {
|
|
124
|
-
if (fullReleaseSet.has(skipped.
|
|
175
|
+
if (fullReleaseSet.has(skipped.workspace.dir)) {
|
|
125
176
|
continue;
|
|
126
177
|
}
|
|
127
|
-
|
|
128
|
-
name: skipped.
|
|
178
|
+
const result = {
|
|
179
|
+
name: skipped.workspace.dir,
|
|
129
180
|
status: "skipped",
|
|
130
|
-
previousTag: skipped.tag,
|
|
131
181
|
commitCount: skipped.commitCount,
|
|
132
|
-
parsedCommitCount: skipped.parsedCommitCount,
|
|
133
|
-
unparseableCommits: skipped.unparseableCommits,
|
|
134
|
-
bumpedFiles: [],
|
|
135
|
-
changelogFiles: [],
|
|
136
182
|
skipReason: skipped.skipReason
|
|
137
|
-
}
|
|
183
|
+
};
|
|
184
|
+
if (skipped.tag !== void 0) {
|
|
185
|
+
result.previousTag = skipped.tag;
|
|
186
|
+
}
|
|
187
|
+
if (skipped.parsedCommitCount !== void 0) {
|
|
188
|
+
result.parsedCommitCount = skipped.parsedCommitCount;
|
|
189
|
+
}
|
|
190
|
+
if (skipped.unparseableCommits !== void 0) {
|
|
191
|
+
result.unparseableCommits = skipped.unparseableCommits;
|
|
192
|
+
}
|
|
193
|
+
workspaces.push(result);
|
|
138
194
|
}
|
|
139
|
-
return
|
|
195
|
+
return workspaces;
|
|
140
196
|
}
|
|
141
|
-
function executeReleaseSet(sortedDirs, fullReleaseSet, config, directResults, previousTags, dryRun,
|
|
197
|
+
function executeReleaseSet(sortedDirs, fullReleaseSet, config, directResults, previousTags, dryRun, workspaces, previewOptions) {
|
|
142
198
|
const tags = [];
|
|
143
199
|
const modifiedFiles = [];
|
|
144
200
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
@@ -147,79 +203,178 @@ function executeReleaseSet(sortedDirs, fullReleaseSet, config, directResults, pr
|
|
|
147
203
|
if (releaseEntry === void 0) {
|
|
148
204
|
continue;
|
|
149
205
|
}
|
|
150
|
-
const
|
|
151
|
-
if (
|
|
206
|
+
const workspace = findWorkspace(config.workspaces, dir);
|
|
207
|
+
if (workspace === void 0) {
|
|
152
208
|
continue;
|
|
153
209
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
210
|
+
tryStage(
|
|
211
|
+
workspaceStageLabel(dir),
|
|
212
|
+
() => executeWorkspaceRelease({
|
|
213
|
+
dir,
|
|
214
|
+
workspace,
|
|
215
|
+
releaseEntry,
|
|
216
|
+
directResult: directResults.get(dir),
|
|
217
|
+
previousTags,
|
|
218
|
+
config,
|
|
219
|
+
dryRun,
|
|
220
|
+
today,
|
|
221
|
+
tags,
|
|
222
|
+
modifiedFiles,
|
|
223
|
+
workspaces,
|
|
224
|
+
previewOptions
|
|
225
|
+
})
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
return { tags, modifiedFiles };
|
|
229
|
+
}
|
|
230
|
+
function executeWorkspaceRelease(args) {
|
|
231
|
+
const {
|
|
232
|
+
dir,
|
|
233
|
+
workspace,
|
|
234
|
+
releaseEntry,
|
|
235
|
+
directResult,
|
|
236
|
+
previousTags,
|
|
237
|
+
config,
|
|
238
|
+
dryRun,
|
|
239
|
+
today,
|
|
240
|
+
tags,
|
|
241
|
+
modifiedFiles,
|
|
242
|
+
workspaces,
|
|
243
|
+
previewOptions
|
|
244
|
+
} = args;
|
|
245
|
+
const setVersionTarget = directResult?.setVersion;
|
|
246
|
+
const bump = setVersionTarget === void 0 ? bumpAllVersions(workspace.packageFiles, releaseEntry.releaseType, dryRun) : setAllVersions(workspace.packageFiles, setVersionTarget, dryRun);
|
|
247
|
+
const newTag = `${workspace.tagPrefix}${bump.newVersion}`;
|
|
248
|
+
tags.push(newTag);
|
|
249
|
+
modifiedFiles.push(...workspace.packageFiles, ...workspace.changelogPaths.map((p) => `${p}/CHANGELOG.md`));
|
|
250
|
+
const isPropagationOnly = directResult === void 0;
|
|
251
|
+
const changelogFiles = generateWorkspaceChangelogs({
|
|
252
|
+
workspace,
|
|
253
|
+
releaseEntry,
|
|
254
|
+
newTag,
|
|
255
|
+
newVersion: bump.newVersion,
|
|
256
|
+
isPropagationOnly,
|
|
257
|
+
config,
|
|
258
|
+
dryRun,
|
|
259
|
+
today,
|
|
260
|
+
modifiedFiles,
|
|
261
|
+
previewOptions
|
|
262
|
+
});
|
|
263
|
+
const released = {
|
|
264
|
+
name: dir,
|
|
265
|
+
status: "released",
|
|
266
|
+
commitCount: directResult?.commits.length ?? 0,
|
|
267
|
+
currentVersion: bump.currentVersion,
|
|
268
|
+
newVersion: bump.newVersion,
|
|
269
|
+
tag: newTag,
|
|
270
|
+
bumpedFiles: bump.files,
|
|
271
|
+
changelogFiles
|
|
272
|
+
};
|
|
273
|
+
const previousTag = directResult?.tag ?? previousTags.get(dir);
|
|
274
|
+
if (previousTag !== void 0) {
|
|
275
|
+
released.previousTag = previousTag;
|
|
276
|
+
}
|
|
277
|
+
if (directResult?.parsedCommitCount !== void 0) {
|
|
278
|
+
released.parsedCommitCount = directResult.parsedCommitCount;
|
|
279
|
+
}
|
|
280
|
+
if (setVersionTarget === void 0) {
|
|
281
|
+
released.releaseType = releaseEntry.releaseType;
|
|
282
|
+
}
|
|
283
|
+
if (directResult?.commits !== void 0) {
|
|
284
|
+
released.commits = directResult.commits;
|
|
285
|
+
}
|
|
286
|
+
if (directResult?.unparseableCommits !== void 0) {
|
|
287
|
+
released.unparseableCommits = directResult.unparseableCommits;
|
|
288
|
+
}
|
|
289
|
+
if (releaseEntry.propagatedFrom !== void 0) {
|
|
290
|
+
released.propagatedFrom = releaseEntry.propagatedFrom;
|
|
291
|
+
}
|
|
292
|
+
if (directResult?.bumpOverride !== void 0) {
|
|
293
|
+
released.bumpOverride = directResult.bumpOverride;
|
|
294
|
+
}
|
|
295
|
+
if (setVersionTarget !== void 0) {
|
|
296
|
+
released.setVersion = setVersionTarget;
|
|
297
|
+
}
|
|
298
|
+
workspaces.push(released);
|
|
299
|
+
}
|
|
300
|
+
function generateWorkspaceChangelogs(args) {
|
|
301
|
+
const {
|
|
302
|
+
workspace,
|
|
303
|
+
releaseEntry,
|
|
304
|
+
newTag,
|
|
305
|
+
newVersion,
|
|
306
|
+
isPropagationOnly,
|
|
307
|
+
config,
|
|
308
|
+
dryRun,
|
|
309
|
+
today,
|
|
310
|
+
modifiedFiles,
|
|
311
|
+
previewOptions
|
|
312
|
+
} = args;
|
|
313
|
+
const changelogFiles = [];
|
|
314
|
+
let firstChangelogJsonPath;
|
|
315
|
+
if (isPropagationOnly && releaseEntry.propagatedFrom !== void 0) {
|
|
316
|
+
for (const changelogPath of workspace.changelogPaths) {
|
|
317
|
+
changelogFiles.push(
|
|
318
|
+
writeSyntheticChangelog({
|
|
319
|
+
changelogPath,
|
|
320
|
+
newVersion,
|
|
321
|
+
date: today,
|
|
322
|
+
propagatedFrom: releaseEntry.propagatedFrom,
|
|
323
|
+
dryRun
|
|
324
|
+
})
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
if (config.changelogJson.enabled) {
|
|
328
|
+
const syntheticEntry = buildSyntheticChangelogEntry(releaseEntry.propagatedFrom, newVersion, today);
|
|
329
|
+
for (const changelogPath of workspace.changelogPaths) {
|
|
330
|
+
const jsonPath = resolveChangelogJsonPath(config, changelogPath);
|
|
331
|
+
if (!dryRun) {
|
|
332
|
+
upsertChangelogJson(jsonPath, [syntheticEntry]);
|
|
202
333
|
}
|
|
334
|
+
modifiedFiles.push(jsonPath);
|
|
335
|
+
firstChangelogJsonPath ??= jsonPath;
|
|
203
336
|
}
|
|
204
337
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
338
|
+
maybeWritePreviews(workspace, newTag, firstChangelogJsonPath, previewOptions, dryRun);
|
|
339
|
+
return changelogFiles;
|
|
340
|
+
}
|
|
341
|
+
const tagPattern = buildTagPattern(getAllTagPrefixes(workspace));
|
|
342
|
+
for (const changelogPath of workspace.changelogPaths) {
|
|
343
|
+
changelogFiles.push(
|
|
344
|
+
...generateChangelog(config, changelogPath, newTag, dryRun, {
|
|
345
|
+
tagPattern,
|
|
346
|
+
includePaths: workspace.paths
|
|
347
|
+
})
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
if (config.changelogJson.enabled) {
|
|
351
|
+
const entries = buildChangelogEntries(config, newTag, {
|
|
352
|
+
tagPattern,
|
|
353
|
+
includePaths: workspace.paths
|
|
220
354
|
});
|
|
355
|
+
for (const changelogPath of workspace.changelogPaths) {
|
|
356
|
+
const jsonPath = resolveChangelogJsonPath(config, changelogPath);
|
|
357
|
+
if (!dryRun) {
|
|
358
|
+
upsertChangelogJson(jsonPath, entries);
|
|
359
|
+
}
|
|
360
|
+
modifiedFiles.push(jsonPath);
|
|
361
|
+
firstChangelogJsonPath ??= jsonPath;
|
|
362
|
+
}
|
|
221
363
|
}
|
|
222
|
-
|
|
364
|
+
maybeWritePreviews(workspace, newTag, firstChangelogJsonPath, previewOptions, dryRun);
|
|
365
|
+
return changelogFiles;
|
|
366
|
+
}
|
|
367
|
+
function maybeWritePreviews(workspace, newTag, changelogJsonPath, previewOptions, dryRun) {
|
|
368
|
+
if (!previewOptions.enabled || changelogJsonPath === void 0) {
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
writeReleaseNotesPreviews({
|
|
372
|
+
workspacePath: workspace.workspacePath,
|
|
373
|
+
tag: newTag,
|
|
374
|
+
changelogJsonPath,
|
|
375
|
+
sectionOrder: previewOptions.sectionOrder,
|
|
376
|
+
dryRun
|
|
377
|
+
});
|
|
223
378
|
}
|
|
224
379
|
function runFormatCommand(config, tags, modifiedFiles, dryRun) {
|
|
225
380
|
const formatCommandStr = config.formatCommand ?? (hasPrettierConfig() ? "npx prettier --write" : void 0);
|
|
@@ -233,28 +388,39 @@ function runFormatCommand(config, tags, modifiedFiles, dryRun) {
|
|
|
233
388
|
try {
|
|
234
389
|
execSync(fullCommand, { stdio: "inherit" });
|
|
235
390
|
} catch (error) {
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
);
|
|
391
|
+
const baseMessage = error instanceof Error ? error.message : String(error);
|
|
392
|
+
throw new Error(`format stage: ${baseMessage} (command: '${fullCommand}')`, { cause: error });
|
|
239
393
|
}
|
|
240
394
|
return { command: fullCommand, executed: true, files: modifiedFiles };
|
|
241
395
|
}
|
|
242
|
-
function
|
|
243
|
-
return
|
|
396
|
+
function findWorkspace(workspaces, dir) {
|
|
397
|
+
return workspaces.find((w) => w.dir === dir);
|
|
244
398
|
}
|
|
245
|
-
function
|
|
246
|
-
|
|
399
|
+
function wrapStageError(stageLabel, error) {
|
|
400
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
401
|
+
return new Error(`${stageLabel}: ${message}`, { cause: error });
|
|
247
402
|
}
|
|
248
|
-
function
|
|
403
|
+
function tryStage(stageLabel, fn) {
|
|
249
404
|
try {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
return parsed.version;
|
|
254
|
-
}
|
|
255
|
-
} catch {
|
|
405
|
+
return fn();
|
|
406
|
+
} catch (error) {
|
|
407
|
+
throw wrapStageError(stageLabel, error);
|
|
256
408
|
}
|
|
257
|
-
|
|
409
|
+
}
|
|
410
|
+
function workspaceStageLabel(dir) {
|
|
411
|
+
return `workspace '${dir}' release stage`;
|
|
412
|
+
}
|
|
413
|
+
function maybeEmitBaselineHint(workspace, knownPrefixes, state) {
|
|
414
|
+
if (state.emitted) return;
|
|
415
|
+
if ((workspace.legacyIdentities?.length ?? 0) > 0) return;
|
|
416
|
+
const candidates = detectUndeclaredTagPrefixes(knownPrefixes);
|
|
417
|
+
if (candidates.length === 0) return;
|
|
418
|
+
const totalTags = candidates.reduce((sum, candidate) => sum + candidate.tagCount, 0);
|
|
419
|
+
const example = candidates[0]?.exampleTags[0] ?? `${candidates[0]?.prefix ?? ""}?`;
|
|
420
|
+
console.error(
|
|
421
|
+
`Hint: no baseline tag found for ${workspace.dir} under '${workspace.tagPrefix}', but ${totalTags} candidate-shaped tags exist (e.g., ${example}). Run 'release-kit show-tag-prefixes' to check for undeclared legacy prefixes.`
|
|
422
|
+
);
|
|
423
|
+
state.emitted = true;
|
|
258
424
|
}
|
|
259
425
|
function topologicalSort(releaseSet, graph) {
|
|
260
426
|
const releaseDirs = new Set(releaseSet.keys());
|
|
@@ -314,6 +480,9 @@ function topologicalSort(releaseSet, graph) {
|
|
|
314
480
|
}
|
|
315
481
|
return { sorted, cyclicDirs };
|
|
316
482
|
}
|
|
483
|
+
function getAllTagPrefixes(workspace) {
|
|
484
|
+
return [workspace.tagPrefix, ...workspace.legacyIdentities?.map((identity) => identity.tagPrefix) ?? []];
|
|
485
|
+
}
|
|
317
486
|
export {
|
|
318
487
|
releasePrepareMono
|
|
319
488
|
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ReleasePrepareOptions } from './releasePrepare.ts';
|
|
2
|
+
import type { MonorepoReleaseConfig, ProjectPrepareResult } from './types.ts';
|
|
3
|
+
export interface ReleasePrepareProjectArgs {
|
|
4
|
+
config: MonorepoReleaseConfig;
|
|
5
|
+
options: ReleasePrepareOptions;
|
|
6
|
+
modifiedFiles: string[];
|
|
7
|
+
tags: string[];
|
|
8
|
+
}
|
|
9
|
+
export declare function releasePrepareProject(args: ReleasePrepareProjectArgs): ProjectPrepareResult;
|