@williamthorsen/release-kit 5.4.0 → 7.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/CHANGELOG.md +32 -0
- package/README.md +12 -12
- package/dist/esm/.cache +1 -1
- package/dist/esm/assertCleanWorkingTree.js +9 -14
- package/dist/esm/bin/release-kit.js +202 -229
- package/dist/esm/buildChangelogEntries.d.ts +2 -2
- package/dist/esm/buildChangelogEntries.js +142 -149
- package/dist/esm/buildDependencyGraph.d.ts +1 -1
- package/dist/esm/buildDependencyGraph.js +60 -59
- package/dist/esm/buildEmptyReleaseEntry.d.ts +1 -1
- package/dist/esm/buildEmptyReleaseEntry.js +12 -15
- package/dist/esm/buildReleaseSummary.d.ts +1 -1
- package/dist/esm/buildReleaseSummary.js +23 -26
- package/dist/esm/buildSyntheticChangelogEntry.d.ts +1 -1
- package/dist/esm/buildSyntheticChangelogEntry.js +9 -12
- package/dist/esm/bumpAllVersions.d.ts +1 -1
- package/dist/esm/bumpAllVersions.js +51 -52
- package/dist/esm/bumpVersion.d.ts +1 -1
- package/dist/esm/bumpVersion.js +25 -28
- package/dist/esm/changelogJsonFile.d.ts +1 -1
- package/dist/esm/changelogJsonFile.js +59 -62
- package/dist/esm/changelogJsonUtils.d.ts +1 -1
- package/dist/esm/changelogJsonUtils.js +35 -32
- package/dist/esm/changelogOverrides.d.ts +1 -1
- package/dist/esm/changelogOverrides.js +374 -377
- package/dist/esm/checkWorkTypesDrift.js +104 -99
- package/dist/esm/collectPolicyViolations.d.ts +2 -2
- package/dist/esm/collectPolicyViolations.js +11 -14
- package/dist/esm/commitCommand.js +48 -53
- package/dist/esm/compareVersions.js +20 -23
- package/dist/esm/createGithubRelease.js +56 -59
- package/dist/esm/createGithubReleaseCommand.js +21 -29
- package/dist/esm/createTags.js +57 -56
- package/dist/esm/decideRelease.d.ts +2 -2
- package/dist/esm/decideRelease.js +27 -41
- package/dist/esm/defaults.d.ts +3 -3
- package/dist/esm/defaults.js +36 -48
- package/dist/esm/deleteFileIfExists.js +10 -12
- package/dist/esm/deriveWorkspaceConfig.d.ts +1 -1
- package/dist/esm/deriveWorkspaceConfig.js +34 -36
- package/dist/esm/detectPackageManager.js +35 -37
- package/dist/esm/detectUndeclaredTagPrefixes.js +41 -40
- package/dist/esm/determineBumpFromCommits.d.ts +2 -2
- package/dist/esm/determineBumpFromCommits.js +25 -29
- package/dist/esm/determineBumpType.d.ts +1 -1
- package/dist/esm/determineBumpType.js +31 -32
- package/dist/esm/discoverWorkspaces.js +38 -40
- package/dist/esm/format.js +6 -11
- package/dist/esm/generateChangelogs.d.ts +1 -1
- package/dist/esm/generateChangelogs.js +13 -17
- package/dist/esm/getCommitsSinceTarget.d.ts +1 -1
- package/dist/esm/getCommitsSinceTarget.js +54 -55
- package/dist/esm/hasPrettierConfig.js +33 -35
- package/dist/esm/help/prepareHelp.d.ts +2 -0
- package/dist/esm/help/prepareHelp.js +26 -0
- package/dist/esm/index.d.ts +4 -4
- package/dist/esm/index.js +2 -8
- package/dist/esm/init/checks.js +28 -32
- package/dist/esm/init/detectRepoType.js +12 -15
- package/dist/esm/init/initCommand.js +60 -54
- package/dist/esm/init/parseJsonRecord.js +9 -11
- package/dist/esm/init/scaffold.d.ts +1 -1
- package/dist/esm/init/scaffold.js +32 -38
- package/dist/esm/init/templates.d.ts +1 -1
- package/dist/esm/init/templates.js +16 -22
- package/dist/esm/injectReleaseNotesIntoReadme.js +42 -49
- package/dist/esm/injectSection.js +17 -27
- package/dist/esm/loadConfig.d.ts +1 -1
- package/dist/esm/loadConfig.js +206 -225
- package/dist/esm/parseCommitMessage.d.ts +1 -1
- package/dist/esm/parseCommitMessage.js +72 -76
- package/dist/esm/parseRequestedTags.js +6 -9
- package/dist/esm/prepareCommand.d.ts +32 -1
- package/dist/esm/prepareCommand.js +225 -271
- package/dist/esm/previewTagPrefixes.d.ts +1 -1
- package/dist/esm/previewTagPrefixes.js +101 -96
- package/dist/esm/propagateBumps.d.ts +2 -2
- package/dist/esm/propagateBumps.js +48 -50
- package/dist/esm/publish.d.ts +2 -2
- package/dist/esm/publish.js +22 -28
- package/dist/esm/publishCommand.js +75 -86
- package/dist/esm/pushCommand.js +33 -40
- package/dist/esm/pushRelease.d.ts +1 -1
- package/dist/esm/pushRelease.js +21 -24
- package/dist/esm/readCurrentVersion.js +13 -17
- package/dist/esm/releasePrepare.d.ts +1 -1
- package/dist/esm/releasePrepare.js +213 -231
- package/dist/esm/releasePrepareMono.d.ts +2 -2
- package/dist/esm/releasePrepareMono.js +434 -493
- package/dist/esm/releasePrepareProject.d.ts +2 -2
- package/dist/esm/releasePrepareProject.js +143 -153
- package/dist/esm/renderChangelogMarkdown.d.ts +1 -1
- package/dist/esm/renderChangelogMarkdown.js +20 -24
- package/dist/esm/renderReleaseNotes.d.ts +1 -1
- package/dist/esm/renderReleaseNotes.js +50 -55
- package/dist/esm/reportPrepare.d.ts +1 -1
- package/dist/esm/reportPrepare.js +230 -231
- package/dist/esm/resolveCliffConfigPath.js +18 -23
- package/dist/esm/resolveCommandTags.d.ts +1 -1
- package/dist/esm/resolveCommandTags.js +47 -44
- package/dist/esm/resolveReleaseNotesConfig.d.ts +1 -1
- package/dist/esm/resolveReleaseNotesConfig.js +39 -41
- package/dist/esm/resolveReleaseTags.d.ts +1 -1
- package/dist/esm/resolveReleaseTags.js +39 -40
- package/dist/esm/runGitCliff.js +27 -30
- package/dist/esm/showTagPrefixesCommand.js +48 -70
- package/dist/esm/stripEmojiPrefix.js +2 -5
- package/dist/esm/stripScope.js +18 -21
- package/dist/esm/sync-labels/generateCommand.d.ts +1 -1
- package/dist/esm/sync-labels/generateCommand.js +51 -52
- package/dist/esm/sync-labels/initCommand.js +46 -47
- package/dist/esm/sync-labels/loadSyncLabelsConfig.d.ts +1 -1
- package/dist/esm/sync-labels/loadSyncLabelsConfig.js +46 -52
- package/dist/esm/sync-labels/presets.d.ts +1 -1
- package/dist/esm/sync-labels/presets.js +40 -43
- package/dist/esm/sync-labels/resolveLabels.d.ts +1 -1
- package/dist/esm/sync-labels/resolveLabels.js +28 -35
- package/dist/esm/sync-labels/syncCommand.js +30 -30
- package/dist/esm/sync-labels/templates.d.ts +1 -1
- package/dist/esm/sync-labels/templates.js +23 -26
- package/dist/esm/sync-labels/types.js +1 -0
- package/dist/esm/syncWorkTypes.js +83 -81
- package/dist/esm/tagCommand.js +12 -21
- package/dist/esm/typeGuards.js +4 -8
- package/dist/esm/types.js +66 -60
- package/dist/esm/validateConfig.d.ts +1 -1
- package/dist/esm/validateConfig.js +109 -115
- package/dist/esm/validateOnlyExcludesStrandedDependents.d.ts +2 -2
- package/dist/esm/validateOnlyExcludesStrandedDependents.js +97 -91
- package/dist/esm/validateOverridesCommand.d.ts +2 -2
- package/dist/esm/validateOverridesCommand.js +111 -111
- package/dist/esm/workTypesData.js +57 -60
- package/dist/esm/workTypesUtils.js +16 -21
- package/dist/esm/writeReleaseNotesPreviews.js +55 -57
- package/package.json +2 -6
|
@@ -1,19 +1,11 @@
|
|
|
1
|
-
import { execSync } from
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
2
|
import { buildChangelogEntries } from "./buildChangelogEntries.js";
|
|
3
3
|
import { buildDependencyGraph } from "./buildDependencyGraph.js";
|
|
4
4
|
import { buildEmptyReleaseEntry } from "./buildEmptyReleaseEntry.js";
|
|
5
5
|
import { buildSyntheticChangelogEntry } from "./buildSyntheticChangelogEntry.js";
|
|
6
6
|
import { bumpAllVersions, setAllVersions } from "./bumpAllVersions.js";
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
resolveChangelogJsonPath,
|
|
10
|
-
upsertChangelogJsonAndReturn
|
|
11
|
-
} from "./changelogJsonFile.js";
|
|
12
|
-
import {
|
|
13
|
-
applyWorkspaceOverrides,
|
|
14
|
-
createOverrideContext,
|
|
15
|
-
formatStaleOverrideKeyWarning
|
|
16
|
-
} from "./changelogOverrides.js";
|
|
7
|
+
import { mergeChangelogEntriesWithDisk, resolveChangelogJsonPath, upsertChangelogJsonAndReturn, } from "./changelogJsonFile.js";
|
|
8
|
+
import { applyWorkspaceOverrides, createOverrideContext, formatStaleOverrideKeyWarning, } from "./changelogOverrides.js";
|
|
17
9
|
import { createPolicyViolationCollector } from "./collectPolicyViolations.js";
|
|
18
10
|
import { isForwardVersion } from "./compareVersions.js";
|
|
19
11
|
import { decideRelease } from "./decideRelease.js";
|
|
@@ -30,526 +22,475 @@ import { writeChangelogMarkdown } from "./renderChangelogMarkdown.js";
|
|
|
30
22
|
import { deriveSectionOrder } from "./resolveReleaseNotesConfig.js";
|
|
31
23
|
import { refreshGitCliffCache } from "./runGitCliff.js";
|
|
32
24
|
import { writeReleaseNotesPreviews } from "./writeReleaseNotesPreviews.js";
|
|
33
|
-
function releasePrepareMono(config, options) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
fullReleaseSet,
|
|
68
|
-
config,
|
|
69
|
-
directResults,
|
|
70
|
-
previousTags,
|
|
71
|
-
dryRun,
|
|
72
|
-
workspaces,
|
|
73
|
-
previewOptions,
|
|
74
|
-
overrideContext,
|
|
75
|
-
sectionOrder
|
|
76
|
-
});
|
|
77
|
-
const configOrder = new Map(config.workspaces.map((w, i) => [w.dir, i]));
|
|
78
|
-
workspaces.sort((a, b) => {
|
|
79
|
-
const orderA = configOrder.get(a.name ?? "") ?? 0;
|
|
80
|
-
const orderB = configOrder.get(b.name ?? "") ?? 0;
|
|
81
|
-
return orderA - orderB;
|
|
82
|
-
});
|
|
83
|
-
let project;
|
|
84
|
-
if (config.project !== void 0) {
|
|
85
|
-
project = tryStage(
|
|
86
|
-
"project release stage",
|
|
87
|
-
() => releasePrepareProject({
|
|
25
|
+
export function releasePrepareMono(config, options) {
|
|
26
|
+
const { dryRun, withReleaseNotes } = options;
|
|
27
|
+
if (withReleaseNotes === true && !config.changelogJson.enabled) {
|
|
28
|
+
console.warn('Warning: --with-release-notes requires changelogJson.enabled; skipping preview generation');
|
|
29
|
+
}
|
|
30
|
+
const sectionOrder = deriveSectionOrder(resolveWorkTypes(config.workTypes));
|
|
31
|
+
const overrideContext = createOverrideContext(config.workspaces);
|
|
32
|
+
const { directBumps, directResults, skippedResults, currentVersions } = determineDirectBumps(config, options);
|
|
33
|
+
const previousTags = new Map();
|
|
34
|
+
for (const result of directResults.values()) {
|
|
35
|
+
previousTags.set(result.workspace.dir, result.tag);
|
|
36
|
+
}
|
|
37
|
+
for (const skipped of skippedResults) {
|
|
38
|
+
previousTags.set(skipped.workspace.dir, skipped.tag);
|
|
39
|
+
}
|
|
40
|
+
const graph = buildDependencyGraph(config.workspaces);
|
|
41
|
+
const fullReleaseSet = propagateBumps(directBumps, graph, currentVersions);
|
|
42
|
+
const { sorted: sortedDirs, cyclicDirs } = topologicalSort(fullReleaseSet, graph);
|
|
43
|
+
const warnings = [];
|
|
44
|
+
if (cyclicDirs.length > 0) {
|
|
45
|
+
warnings.push(`Circular workspace dependencies detected among: ${cyclicDirs.join(', ')}. ` +
|
|
46
|
+
'Propagation metadata may be incomplete for these workspaces.');
|
|
47
|
+
}
|
|
48
|
+
const workspaces = collectSkippedWorkspaces(skippedResults, fullReleaseSet);
|
|
49
|
+
const previewOptions = {
|
|
50
|
+
enabled: withReleaseNotes === true && config.changelogJson.enabled,
|
|
51
|
+
sectionOrder,
|
|
52
|
+
};
|
|
53
|
+
if (fullReleaseSet.size > 0) {
|
|
54
|
+
refreshGitCliffCache();
|
|
55
|
+
}
|
|
56
|
+
const { tags, modifiedFiles } = executeReleaseSet({
|
|
57
|
+
sortedDirs,
|
|
58
|
+
fullReleaseSet,
|
|
88
59
|
config,
|
|
89
|
-
|
|
90
|
-
|
|
60
|
+
directResults,
|
|
61
|
+
previousTags,
|
|
62
|
+
dryRun,
|
|
63
|
+
workspaces,
|
|
64
|
+
previewOptions,
|
|
65
|
+
overrideContext,
|
|
66
|
+
sectionOrder,
|
|
67
|
+
});
|
|
68
|
+
const configOrder = new Map(config.workspaces.map((w, i) => [w.dir, i]));
|
|
69
|
+
workspaces.sort((a, b) => {
|
|
70
|
+
const orderA = configOrder.get(a.name ?? '') ?? 0;
|
|
71
|
+
const orderB = configOrder.get(b.name ?? '') ?? 0;
|
|
72
|
+
return orderA - orderB;
|
|
73
|
+
});
|
|
74
|
+
let project;
|
|
75
|
+
if (config.project !== undefined) {
|
|
76
|
+
project = tryStage('project release stage', () => releasePrepareProject({
|
|
77
|
+
config,
|
|
78
|
+
options,
|
|
79
|
+
modifiedFiles,
|
|
80
|
+
tags,
|
|
81
|
+
rootOverrides: overrideContext.project,
|
|
82
|
+
overrideWarnings: overrideContext.overrideWarnings,
|
|
83
|
+
globalMatchedRootKeys: overrideContext.globalMatchedRootKeys,
|
|
84
|
+
}));
|
|
85
|
+
}
|
|
86
|
+
const formatCommand = runFormatCommand(config, tags, modifiedFiles, dryRun);
|
|
87
|
+
for (const overrideKey of overrideContext.project.keys()) {
|
|
88
|
+
if (!overrideContext.globalMatchedRootKeys.has(overrideKey)) {
|
|
89
|
+
overrideContext.overrideWarnings.push(formatStaleOverrideKeyWarning(overrideKey));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const allWarnings = [...warnings, ...overrideContext.overrideWarnings];
|
|
93
|
+
return {
|
|
94
|
+
workspaces,
|
|
91
95
|
tags,
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
const formatCommand = runFormatCommand(config, tags, modifiedFiles, dryRun);
|
|
99
|
-
for (const overrideKey of overrideContext.project.keys()) {
|
|
100
|
-
if (!overrideContext.globalMatchedRootKeys.has(overrideKey)) {
|
|
101
|
-
overrideContext.overrideWarnings.push(formatStaleOverrideKeyWarning(overrideKey));
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
const allWarnings = [...warnings, ...overrideContext.overrideWarnings];
|
|
105
|
-
return {
|
|
106
|
-
workspaces,
|
|
107
|
-
tags,
|
|
108
|
-
formatCommand,
|
|
109
|
-
dryRun,
|
|
110
|
-
...allWarnings.length > 0 ? { warnings: allWarnings } : {},
|
|
111
|
-
...project === void 0 ? {} : { project }
|
|
112
|
-
};
|
|
96
|
+
formatCommand,
|
|
97
|
+
dryRun,
|
|
98
|
+
...(allWarnings.length > 0 ? { warnings: allWarnings } : {}),
|
|
99
|
+
...(project === undefined ? {} : { project }),
|
|
100
|
+
};
|
|
113
101
|
}
|
|
114
102
|
function determineDirectBumps(config, options) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
const since = tag === void 0 ? "(no previous release found)" : `since ${tag}`;
|
|
136
|
-
if (tag === void 0) {
|
|
137
|
-
maybeEmitBaselineHint(workspace, knownPrefixes, hintState);
|
|
138
|
-
}
|
|
139
|
-
const primaryPackageFile = workspace.packageFiles[0];
|
|
140
|
-
if (primaryPackageFile !== void 0) {
|
|
141
|
-
const currentVersion = tryStage(stageLabel, () => readCurrentVersion(primaryPackageFile));
|
|
142
|
-
if (currentVersion !== void 0) {
|
|
143
|
-
currentVersions.set(workspace.dir, currentVersion);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
if (setVersion !== void 0) {
|
|
147
|
-
const currentVersion = currentVersions.get(workspace.dir);
|
|
148
|
-
if (currentVersion === void 0) {
|
|
149
|
-
throw new Error(
|
|
150
|
-
`Cannot validate --set-version: failed to read current version from ${primaryPackageFile ?? "(no package file)"}`
|
|
151
|
-
);
|
|
152
|
-
}
|
|
153
|
-
if (!isForwardVersion(currentVersion, setVersion)) {
|
|
154
|
-
throw new Error(`--set-version ${setVersion} is not greater than current version ${currentVersion}`);
|
|
155
|
-
}
|
|
156
|
-
directBumps.set(workspace.dir, { releaseType: "patch", newVersionOverride: setVersion });
|
|
157
|
-
directResults.set(workspace.dir, {
|
|
158
|
-
workspace,
|
|
159
|
-
tag,
|
|
160
|
-
commits,
|
|
161
|
-
releaseType: void 0,
|
|
162
|
-
parsedCommitCount: void 0,
|
|
163
|
-
unparseableCommits: void 0,
|
|
164
|
-
policyViolations: void 0,
|
|
165
|
-
bumpOverride: void 0,
|
|
166
|
-
setVersion
|
|
167
|
-
});
|
|
168
|
-
continue;
|
|
169
|
-
}
|
|
170
|
-
const collector = createPolicyViolationCollector();
|
|
171
|
-
const decision = tryStage(
|
|
172
|
-
stageLabel,
|
|
173
|
-
() => decideRelease({
|
|
174
|
-
commits,
|
|
175
|
-
force,
|
|
176
|
-
bumpOverride,
|
|
177
|
-
workTypes,
|
|
178
|
-
versionPatterns,
|
|
179
|
-
scopeAliases: config.scopeAliases,
|
|
180
|
-
breakingPolicies,
|
|
181
|
-
onPolicyViolation: collector.onPolicyViolation,
|
|
182
|
-
skipReasons: {
|
|
183
|
-
noCommits: `No commits for ${name} ${since}. Pass --force to release at patch. Skipping.`,
|
|
184
|
-
noBumpWorthy: `No bump-worthy commits for ${name} ${since}. Pass --force to release at patch (or --force --bump=X for a different level). Skipping.`
|
|
103
|
+
const { force, bumpOverride, setVersion } = options;
|
|
104
|
+
if (setVersion !== undefined && config.workspaces.length !== 1) {
|
|
105
|
+
throw new Error(`--set-version requires exactly one workspace; received ${config.workspaces.length}`);
|
|
106
|
+
}
|
|
107
|
+
const workTypes = config.workTypes ?? { ...DEFAULT_WORK_TYPES };
|
|
108
|
+
const versionPatterns = config.versionPatterns ?? { ...DEFAULT_VERSION_PATTERNS };
|
|
109
|
+
const breakingPolicies = config.breakingPolicies ?? DEFAULT_BREAKING_POLICIES;
|
|
110
|
+
const directBumps = new Map();
|
|
111
|
+
const directResults = new Map();
|
|
112
|
+
const skippedResults = [];
|
|
113
|
+
const currentVersions = new Map();
|
|
114
|
+
const hintState = { emitted: false };
|
|
115
|
+
const knownPrefixes = config.workspaces.flatMap(getAllTagPrefixes);
|
|
116
|
+
for (const workspace of config.workspaces) {
|
|
117
|
+
const name = workspace.dir;
|
|
118
|
+
const stageLabel = workspaceStageLabel(workspace.dir);
|
|
119
|
+
const { tag, commits } = tryStage(stageLabel, () => getCommitsSinceTarget(getAllTagPrefixes(workspace), workspace.paths));
|
|
120
|
+
const since = tag === undefined ? '(no previous release found)' : `since ${tag}`;
|
|
121
|
+
if (tag === undefined) {
|
|
122
|
+
maybeEmitBaselineHint(workspace, knownPrefixes, hintState);
|
|
185
123
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
124
|
+
const primaryPackageFile = workspace.packageFiles[0];
|
|
125
|
+
if (primaryPackageFile !== undefined) {
|
|
126
|
+
const currentVersion = tryStage(stageLabel, () => readCurrentVersion(primaryPackageFile));
|
|
127
|
+
if (currentVersion !== undefined) {
|
|
128
|
+
currentVersions.set(workspace.dir, currentVersion);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (setVersion !== undefined) {
|
|
132
|
+
const currentVersion = currentVersions.get(workspace.dir);
|
|
133
|
+
if (currentVersion === undefined) {
|
|
134
|
+
throw new Error(`Cannot validate --set-version: failed to read current version from ${primaryPackageFile ?? '(no package file)'}`);
|
|
135
|
+
}
|
|
136
|
+
if (!isForwardVersion(currentVersion, setVersion)) {
|
|
137
|
+
throw new Error(`--set-version ${setVersion} is not greater than current version ${currentVersion}`);
|
|
138
|
+
}
|
|
139
|
+
directBumps.set(workspace.dir, { releaseType: 'patch', newVersionOverride: setVersion });
|
|
140
|
+
directResults.set(workspace.dir, {
|
|
141
|
+
workspace,
|
|
142
|
+
tag,
|
|
143
|
+
commits,
|
|
144
|
+
releaseType: undefined,
|
|
145
|
+
parsedCommitCount: undefined,
|
|
146
|
+
unparseableCommits: undefined,
|
|
147
|
+
policyViolations: undefined,
|
|
148
|
+
bumpOverride: undefined,
|
|
149
|
+
setVersion,
|
|
150
|
+
});
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
const collector = createPolicyViolationCollector();
|
|
154
|
+
const decision = tryStage(stageLabel, () => decideRelease({
|
|
155
|
+
commits,
|
|
156
|
+
force,
|
|
157
|
+
bumpOverride,
|
|
158
|
+
workTypes,
|
|
159
|
+
versionPatterns,
|
|
160
|
+
scopeAliases: config.scopeAliases,
|
|
161
|
+
breakingPolicies,
|
|
162
|
+
onPolicyViolation: collector.onPolicyViolation,
|
|
163
|
+
skipReasons: {
|
|
164
|
+
noCommits: `No commits for ${name} ${since}. Pass --force to release at patch. Skipping.`,
|
|
165
|
+
noBumpWorthy: `No bump-worthy commits for ${name} ${since}. Pass --force to release at patch (or --force --bump=X for a different level). Skipping.`,
|
|
166
|
+
},
|
|
167
|
+
}));
|
|
168
|
+
const policyViolations = collector.violations.length > 0 ? collector.violations : undefined;
|
|
169
|
+
if (decision.outcome === 'skip') {
|
|
170
|
+
skippedResults.push({
|
|
171
|
+
workspace,
|
|
172
|
+
tag,
|
|
173
|
+
commitCount: commits.length,
|
|
174
|
+
parsedCommitCount: decision.parsedCommitCount,
|
|
175
|
+
unparseableCommits: decision.unparseableCommits,
|
|
176
|
+
policyViolations,
|
|
177
|
+
skipReason: decision.skipReason,
|
|
178
|
+
});
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
directBumps.set(workspace.dir, { releaseType: decision.releaseType });
|
|
182
|
+
directResults.set(workspace.dir, {
|
|
183
|
+
workspace,
|
|
184
|
+
tag,
|
|
185
|
+
commits,
|
|
186
|
+
releaseType: decision.releaseType,
|
|
187
|
+
parsedCommitCount: decision.parsedCommitCount,
|
|
188
|
+
unparseableCommits: decision.unparseableCommits,
|
|
189
|
+
policyViolations,
|
|
190
|
+
bumpOverride,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
return { directBumps, directResults, skippedResults, currentVersions };
|
|
214
194
|
}
|
|
215
195
|
function collectSkippedWorkspaces(skippedResults, fullReleaseSet) {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
196
|
+
const workspaces = [];
|
|
197
|
+
for (const skipped of skippedResults) {
|
|
198
|
+
if (fullReleaseSet.has(skipped.workspace.dir)) {
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
const result = {
|
|
202
|
+
name: skipped.workspace.dir,
|
|
203
|
+
status: 'skipped',
|
|
204
|
+
commitCount: skipped.commitCount,
|
|
205
|
+
skipReason: skipped.skipReason,
|
|
206
|
+
};
|
|
207
|
+
if (skipped.tag !== undefined) {
|
|
208
|
+
result.previousTag = skipped.tag;
|
|
209
|
+
}
|
|
210
|
+
if (skipped.parsedCommitCount !== undefined) {
|
|
211
|
+
result.parsedCommitCount = skipped.parsedCommitCount;
|
|
212
|
+
}
|
|
213
|
+
if (skipped.unparseableCommits !== undefined) {
|
|
214
|
+
result.unparseableCommits = skipped.unparseableCommits;
|
|
215
|
+
}
|
|
216
|
+
if (skipped.policyViolations !== undefined) {
|
|
217
|
+
result.policyViolations = skipped.policyViolations;
|
|
218
|
+
}
|
|
219
|
+
workspaces.push(result);
|
|
238
220
|
}
|
|
239
|
-
workspaces
|
|
240
|
-
}
|
|
241
|
-
return workspaces;
|
|
221
|
+
return workspaces;
|
|
242
222
|
}
|
|
243
223
|
function executeReleaseSet(args) {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
224
|
+
const { sortedDirs, fullReleaseSet, config, directResults, previousTags, dryRun, workspaces, previewOptions, overrideContext, sectionOrder, } = args;
|
|
225
|
+
const tags = [];
|
|
226
|
+
const modifiedFiles = [];
|
|
227
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
228
|
+
for (const dir of sortedDirs) {
|
|
229
|
+
const releaseEntry = fullReleaseSet.get(dir);
|
|
230
|
+
if (releaseEntry === undefined) {
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
const workspace = findWorkspace(config.workspaces, dir);
|
|
234
|
+
if (workspace === undefined) {
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
tryStage(workspaceStageLabel(dir), () => executeWorkspaceRelease({
|
|
238
|
+
dir,
|
|
239
|
+
workspace,
|
|
240
|
+
releaseEntry,
|
|
241
|
+
directResult: directResults.get(dir),
|
|
242
|
+
previousTags,
|
|
243
|
+
config,
|
|
244
|
+
dryRun,
|
|
245
|
+
today,
|
|
246
|
+
tags,
|
|
247
|
+
modifiedFiles,
|
|
248
|
+
workspaces,
|
|
249
|
+
previewOptions,
|
|
250
|
+
overrideContext,
|
|
251
|
+
sectionOrder,
|
|
252
|
+
}));
|
|
253
|
+
}
|
|
254
|
+
return { tags, modifiedFiles };
|
|
255
|
+
}
|
|
256
|
+
function executeWorkspaceRelease(args) {
|
|
257
|
+
const { dir, workspace, releaseEntry, directResult, previousTags, config, dryRun, today, tags, modifiedFiles, workspaces, previewOptions, overrideContext, sectionOrder, } = args;
|
|
258
|
+
const setVersionTarget = directResult?.setVersion;
|
|
259
|
+
const bump = setVersionTarget === undefined
|
|
260
|
+
? bumpAllVersions(workspace.packageFiles, releaseEntry.releaseType, dryRun)
|
|
261
|
+
: setAllVersions(workspace.packageFiles, setVersionTarget, dryRun);
|
|
262
|
+
const newTag = `${workspace.tagPrefix}${bump.newVersion}`;
|
|
263
|
+
tags.push(newTag);
|
|
264
|
+
modifiedFiles.push(...workspace.packageFiles, ...workspace.changelogPaths.map((p) => `${p}/CHANGELOG.md`));
|
|
265
|
+
const isPropagationOnly = directResult === undefined;
|
|
266
|
+
const isEmptyRange = directResult !== undefined && directResult.commits.length === 0;
|
|
267
|
+
const changelogFiles = generateWorkspaceChangelogs({
|
|
272
268
|
workspace,
|
|
273
269
|
releaseEntry,
|
|
274
|
-
|
|
275
|
-
|
|
270
|
+
newTag,
|
|
271
|
+
newVersion: bump.newVersion,
|
|
272
|
+
isPropagationOnly,
|
|
273
|
+
isEmptyRange,
|
|
276
274
|
config,
|
|
277
275
|
dryRun,
|
|
278
276
|
today,
|
|
279
|
-
tags,
|
|
280
277
|
modifiedFiles,
|
|
281
|
-
workspaces,
|
|
282
278
|
previewOptions,
|
|
283
279
|
overrideContext,
|
|
284
|
-
sectionOrder
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
workspaces
|
|
303
|
-
previewOptions,
|
|
304
|
-
overrideContext,
|
|
305
|
-
sectionOrder
|
|
306
|
-
} = args;
|
|
307
|
-
const setVersionTarget = directResult?.setVersion;
|
|
308
|
-
const bump = setVersionTarget === void 0 ? bumpAllVersions(workspace.packageFiles, releaseEntry.releaseType, dryRun) : setAllVersions(workspace.packageFiles, setVersionTarget, dryRun);
|
|
309
|
-
const newTag = `${workspace.tagPrefix}${bump.newVersion}`;
|
|
310
|
-
tags.push(newTag);
|
|
311
|
-
modifiedFiles.push(...workspace.packageFiles, ...workspace.changelogPaths.map((p) => `${p}/CHANGELOG.md`));
|
|
312
|
-
const isPropagationOnly = directResult === void 0;
|
|
313
|
-
const isEmptyRange = directResult !== void 0 && directResult.commits.length === 0;
|
|
314
|
-
const changelogFiles = generateWorkspaceChangelogs({
|
|
315
|
-
workspace,
|
|
316
|
-
releaseEntry,
|
|
317
|
-
newTag,
|
|
318
|
-
newVersion: bump.newVersion,
|
|
319
|
-
isPropagationOnly,
|
|
320
|
-
isEmptyRange,
|
|
321
|
-
config,
|
|
322
|
-
dryRun,
|
|
323
|
-
today,
|
|
324
|
-
modifiedFiles,
|
|
325
|
-
previewOptions,
|
|
326
|
-
overrideContext,
|
|
327
|
-
sectionOrder
|
|
328
|
-
});
|
|
329
|
-
const released = {
|
|
330
|
-
name: dir,
|
|
331
|
-
status: "released",
|
|
332
|
-
commitCount: directResult?.commits.length ?? 0,
|
|
333
|
-
currentVersion: bump.currentVersion,
|
|
334
|
-
newVersion: bump.newVersion,
|
|
335
|
-
tag: newTag,
|
|
336
|
-
bumpedFiles: bump.files,
|
|
337
|
-
changelogFiles
|
|
338
|
-
};
|
|
339
|
-
attachReleasedWorkspaceOptionals(released, {
|
|
340
|
-
previousTag: directResult?.tag ?? previousTags.get(dir),
|
|
341
|
-
directResult,
|
|
342
|
-
releaseEntry,
|
|
343
|
-
setVersionTarget
|
|
344
|
-
});
|
|
345
|
-
workspaces.push(released);
|
|
280
|
+
sectionOrder,
|
|
281
|
+
});
|
|
282
|
+
const released = {
|
|
283
|
+
name: dir,
|
|
284
|
+
status: 'released',
|
|
285
|
+
commitCount: directResult?.commits.length ?? 0,
|
|
286
|
+
currentVersion: bump.currentVersion,
|
|
287
|
+
newVersion: bump.newVersion,
|
|
288
|
+
tag: newTag,
|
|
289
|
+
bumpedFiles: bump.files,
|
|
290
|
+
changelogFiles,
|
|
291
|
+
};
|
|
292
|
+
attachReleasedWorkspaceOptionals(released, {
|
|
293
|
+
previousTag: directResult?.tag ?? previousTags.get(dir),
|
|
294
|
+
directResult,
|
|
295
|
+
releaseEntry,
|
|
296
|
+
setVersionTarget,
|
|
297
|
+
});
|
|
298
|
+
workspaces.push(released);
|
|
346
299
|
}
|
|
347
300
|
function attachReleasedWorkspaceOptionals(released, args) {
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
301
|
+
const { previousTag, directResult, releaseEntry, setVersionTarget } = args;
|
|
302
|
+
if (previousTag !== undefined) {
|
|
303
|
+
released.previousTag = previousTag;
|
|
304
|
+
}
|
|
305
|
+
if (directResult?.parsedCommitCount !== undefined) {
|
|
306
|
+
released.parsedCommitCount = directResult.parsedCommitCount;
|
|
307
|
+
}
|
|
308
|
+
if (setVersionTarget === undefined) {
|
|
309
|
+
released.releaseType = releaseEntry.releaseType;
|
|
310
|
+
}
|
|
311
|
+
if (directResult?.commits !== undefined) {
|
|
312
|
+
released.commits = directResult.commits;
|
|
313
|
+
}
|
|
314
|
+
if (directResult?.unparseableCommits !== undefined) {
|
|
315
|
+
released.unparseableCommits = directResult.unparseableCommits;
|
|
316
|
+
}
|
|
317
|
+
if (directResult?.policyViolations !== undefined) {
|
|
318
|
+
released.policyViolations = directResult.policyViolations;
|
|
319
|
+
}
|
|
320
|
+
if (releaseEntry.propagatedFrom !== undefined) {
|
|
321
|
+
released.propagatedFrom = releaseEntry.propagatedFrom;
|
|
322
|
+
}
|
|
323
|
+
if (directResult?.bumpOverride !== undefined) {
|
|
324
|
+
released.bumpOverride = directResult.bumpOverride;
|
|
325
|
+
}
|
|
326
|
+
if (setVersionTarget !== undefined) {
|
|
327
|
+
released.setVersion = setVersionTarget;
|
|
328
|
+
}
|
|
376
329
|
}
|
|
377
330
|
function generateWorkspaceChangelogs(args) {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
modifiedFiles.push(jsonPath);
|
|
412
|
-
firstChangelogJsonPath ??= jsonPath;
|
|
413
|
-
}
|
|
414
|
-
changelogFiles.push(
|
|
415
|
-
writeChangelogMarkdown({
|
|
416
|
-
changelogPath,
|
|
417
|
-
entries: mergedEntries,
|
|
418
|
-
sectionOrder,
|
|
419
|
-
dryRun
|
|
420
|
-
})
|
|
421
|
-
);
|
|
422
|
-
}
|
|
423
|
-
maybeWritePreviews(workspace, newTag, firstChangelogJsonPath, previewOptions, dryRun);
|
|
424
|
-
return changelogFiles;
|
|
331
|
+
const { workspace, releaseEntry, newTag, newVersion, isPropagationOnly, isEmptyRange, config, dryRun, today, modifiedFiles, previewOptions, overrideContext, sectionOrder, } = args;
|
|
332
|
+
const newEntries = buildWorkspaceEntries({
|
|
333
|
+
workspace,
|
|
334
|
+
releaseEntry,
|
|
335
|
+
newTag,
|
|
336
|
+
newVersion,
|
|
337
|
+
isPropagationOnly,
|
|
338
|
+
isEmptyRange,
|
|
339
|
+
config,
|
|
340
|
+
today,
|
|
341
|
+
});
|
|
342
|
+
const applied = applyWorkspaceOverrides(newEntries, workspace.workspacePath, overrideContext);
|
|
343
|
+
const changelogFiles = [];
|
|
344
|
+
let firstChangelogJsonPath;
|
|
345
|
+
for (const changelogPath of workspace.changelogPaths) {
|
|
346
|
+
const jsonPath = resolveChangelogJsonPath(config, changelogPath);
|
|
347
|
+
const shouldWriteJson = config.changelogJson.enabled && !dryRun;
|
|
348
|
+
const mergedEntries = shouldWriteJson
|
|
349
|
+
? upsertChangelogJsonAndReturn(jsonPath, applied.entries)
|
|
350
|
+
: mergeChangelogEntriesWithDisk(jsonPath, applied.entries);
|
|
351
|
+
if (config.changelogJson.enabled) {
|
|
352
|
+
modifiedFiles.push(jsonPath);
|
|
353
|
+
firstChangelogJsonPath ??= jsonPath;
|
|
354
|
+
}
|
|
355
|
+
changelogFiles.push(writeChangelogMarkdown({
|
|
356
|
+
changelogPath,
|
|
357
|
+
entries: mergedEntries,
|
|
358
|
+
sectionOrder,
|
|
359
|
+
dryRun,
|
|
360
|
+
}));
|
|
361
|
+
}
|
|
362
|
+
maybeWritePreviews(workspace, newTag, firstChangelogJsonPath, previewOptions, dryRun);
|
|
363
|
+
return changelogFiles;
|
|
425
364
|
}
|
|
426
365
|
function buildWorkspaceEntries(args) {
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
366
|
+
const { workspace, releaseEntry, newTag, newVersion, isPropagationOnly, isEmptyRange, config, today } = args;
|
|
367
|
+
if (isPropagationOnly && releaseEntry.propagatedFrom !== undefined) {
|
|
368
|
+
return [buildSyntheticChangelogEntry(releaseEntry.propagatedFrom, newVersion, today)];
|
|
369
|
+
}
|
|
370
|
+
if (isEmptyRange) {
|
|
371
|
+
return [buildEmptyReleaseEntry(newVersion, today)];
|
|
372
|
+
}
|
|
373
|
+
const tagPattern = buildTagPattern(getAllTagPrefixes(workspace));
|
|
374
|
+
return buildChangelogEntries(config, newTag, { tagPattern, includePaths: workspace.paths });
|
|
436
375
|
}
|
|
437
376
|
function maybeWritePreviews(workspace, newTag, changelogJsonPath, previewOptions, dryRun) {
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
377
|
+
if (!previewOptions.enabled || changelogJsonPath === undefined) {
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
writeReleaseNotesPreviews({
|
|
381
|
+
workspacePath: workspace.workspacePath,
|
|
382
|
+
tag: newTag,
|
|
383
|
+
changelogJsonPath,
|
|
384
|
+
sectionOrder: previewOptions.sectionOrder,
|
|
385
|
+
dryRun,
|
|
386
|
+
});
|
|
448
387
|
}
|
|
449
388
|
function runFormatCommand(config, tags, modifiedFiles, dryRun) {
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
389
|
+
const formatCommandStr = config.formatCommand ?? (hasPrettierConfig() ? 'npx prettier --write' : undefined);
|
|
390
|
+
if (tags.length === 0 || formatCommandStr === undefined) {
|
|
391
|
+
return undefined;
|
|
392
|
+
}
|
|
393
|
+
const fullCommand = `${formatCommandStr} ${modifiedFiles.join(' ')}`;
|
|
394
|
+
if (dryRun) {
|
|
395
|
+
return { command: fullCommand, executed: false, files: modifiedFiles };
|
|
396
|
+
}
|
|
397
|
+
try {
|
|
398
|
+
execSync(fullCommand, { stdio: 'inherit' });
|
|
399
|
+
}
|
|
400
|
+
catch (error) {
|
|
401
|
+
const baseMessage = error instanceof Error ? error.message : String(error);
|
|
402
|
+
throw new Error(`format stage: ${baseMessage} (command: '${fullCommand}')`, { cause: error });
|
|
403
|
+
}
|
|
404
|
+
return { command: fullCommand, executed: true, files: modifiedFiles };
|
|
465
405
|
}
|
|
466
406
|
function findWorkspace(workspaces, dir) {
|
|
467
|
-
|
|
407
|
+
return workspaces.find((w) => w.dir === dir);
|
|
468
408
|
}
|
|
469
409
|
function wrapStageError(stageLabel, error) {
|
|
470
|
-
|
|
471
|
-
|
|
410
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
411
|
+
return new Error(`${stageLabel}: ${message}`, { cause: error });
|
|
472
412
|
}
|
|
473
413
|
function tryStage(stageLabel, fn) {
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
414
|
+
try {
|
|
415
|
+
return fn();
|
|
416
|
+
}
|
|
417
|
+
catch (error) {
|
|
418
|
+
throw wrapStageError(stageLabel, error);
|
|
419
|
+
}
|
|
479
420
|
}
|
|
480
421
|
function workspaceStageLabel(dir) {
|
|
481
|
-
|
|
422
|
+
return `workspace '${dir}' release stage`;
|
|
482
423
|
}
|
|
483
424
|
function maybeEmitBaselineHint(workspace, knownPrefixes, state) {
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
425
|
+
if (state.emitted)
|
|
426
|
+
return;
|
|
427
|
+
if ((workspace.legacyIdentities?.length ?? 0) > 0)
|
|
428
|
+
return;
|
|
429
|
+
const candidates = detectUndeclaredTagPrefixes(knownPrefixes);
|
|
430
|
+
if (candidates.length === 0)
|
|
431
|
+
return;
|
|
432
|
+
const totalTags = candidates.reduce((sum, candidate) => sum + candidate.tagCount, 0);
|
|
433
|
+
const example = candidates[0]?.exampleTags[0] ?? `${candidates[0]?.prefix ?? ''}?`;
|
|
434
|
+
process.stderr.write(`Hint: no baseline tag found for ${workspace.dir} under '${workspace.tagPrefix}', but ` +
|
|
435
|
+
`${totalTags} candidate-shaped tags exist (e.g., ${example}). ` +
|
|
436
|
+
"Run 'release-kit show-tag-prefixes' to check for undeclared legacy prefixes.\n");
|
|
437
|
+
state.emitted = true;
|
|
494
438
|
}
|
|
495
439
|
function topologicalSort(releaseSet, graph) {
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
440
|
+
const releaseDirs = new Set(releaseSet.keys());
|
|
441
|
+
if (releaseDirs.size === 0) {
|
|
442
|
+
return { sorted: [], cyclicDirs: [] };
|
|
443
|
+
}
|
|
444
|
+
const inDegree = new Map();
|
|
445
|
+
const forwardEdges = new Map();
|
|
446
|
+
for (const dir of releaseDirs) {
|
|
447
|
+
inDegree.set(dir, 0);
|
|
448
|
+
forwardEdges.set(dir, []);
|
|
449
|
+
}
|
|
450
|
+
for (const [packageName, dependents] of graph.dependentsOf) {
|
|
451
|
+
const depDir = graph.packageNameToDir.get(packageName);
|
|
452
|
+
if (depDir === undefined || !releaseDirs.has(depDir)) {
|
|
453
|
+
continue;
|
|
454
|
+
}
|
|
455
|
+
for (const dependent of dependents) {
|
|
456
|
+
if (!releaseDirs.has(dependent.dir)) {
|
|
457
|
+
continue;
|
|
458
|
+
}
|
|
459
|
+
const edges = forwardEdges.get(depDir);
|
|
460
|
+
if (edges !== undefined) {
|
|
461
|
+
edges.push(dependent.dir);
|
|
462
|
+
}
|
|
463
|
+
inDegree.set(dependent.dir, (inDegree.get(dependent.dir) ?? 0) + 1);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
const queue = [];
|
|
467
|
+
for (const [dir, degree] of inDegree) {
|
|
468
|
+
if (degree === 0) {
|
|
469
|
+
queue.push(dir);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
const sorted = [];
|
|
473
|
+
while (queue.length > 0) {
|
|
474
|
+
const dir = queue.shift();
|
|
475
|
+
if (dir === undefined) {
|
|
476
|
+
break;
|
|
477
|
+
}
|
|
478
|
+
sorted.push(dir);
|
|
479
|
+
for (const dependent of forwardEdges.get(dir) ?? []) {
|
|
480
|
+
const newDegree = (inDegree.get(dependent) ?? 1) - 1;
|
|
481
|
+
inDegree.set(dependent, newDegree);
|
|
482
|
+
if (newDegree === 0) {
|
|
483
|
+
queue.push(dependent);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
const sortedSet = new Set(sorted);
|
|
488
|
+
const cyclicDirs = [];
|
|
489
|
+
for (const dir of releaseDirs) {
|
|
490
|
+
if (!sortedSet.has(dir)) {
|
|
491
|
+
sorted.push(dir);
|
|
492
|
+
cyclicDirs.push(dir);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
return { sorted, cyclicDirs };
|
|
552
496
|
}
|
|
553
|
-
export {
|
|
554
|
-
releasePrepareMono
|
|
555
|
-
};
|