@williamthorsen/release-kit 11.0.0 → 13.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 +274 -2
- package/.readyup/kits/default.js +18 -33
- package/.readyup/kits/npm-auto-publish.js +24 -23
- package/.readyup/manifest.json +16 -11
- package/CHANGELOG.md +98 -0
- package/README.md +57 -69
- package/bin/release-kit.js +1 -1
- package/dist/esm/assertCleanWorkingTree.d.ts +1 -5
- package/dist/esm/assertTaggedBaseline.d.ts +29 -0
- package/dist/esm/assertTaggedBaseline.js +41 -0
- package/dist/esm/attachChangelogDiagnostics.d.ts +4 -0
- package/dist/esm/attachChangelogDiagnostics.js +14 -0
- package/dist/esm/bin/release-kit.js +88 -24
- package/dist/esm/buildChangelogEntries.d.ts +69 -17
- package/dist/esm/buildChangelogEntries.js +222 -120
- package/dist/esm/buildDependencyGraph.d.ts +6 -6
- package/dist/esm/buildEmptyReleaseEntry.d.ts +1 -8
- package/dist/esm/buildReleaseSummary.d.ts +2 -8
- package/dist/esm/buildReleaseSummary.js +2 -2
- package/dist/esm/buildSyntheticChangelogEntry.d.ts +3 -5
- package/dist/esm/buildSyntheticChangelogEntry.js +2 -2
- package/dist/esm/bumpVersion.d.ts +1 -8
- package/dist/esm/changelogJsonFile.d.ts +5 -7
- package/dist/esm/changelogJsonFile.js +2 -17
- package/dist/esm/changelogJsonUtils.d.ts +7 -10
- package/dist/esm/changelogOverrides.d.ts +79 -100
- package/dist/esm/changelogOverrides.js +138 -58
- package/dist/esm/classifyChangelogCommit.d.ts +36 -0
- package/dist/esm/classifyChangelogCommit.js +34 -0
- package/dist/esm/commitCommand.d.ts +2 -4
- package/dist/esm/compareVersions.d.ts +10 -4
- package/dist/esm/compareVersions.js +16 -0
- package/dist/esm/configFlagSchema.d.ts +1 -1
- package/dist/esm/createGithubRelease.d.ts +7 -19
- package/dist/esm/createGithubReleaseCommand.d.ts +5 -5
- package/dist/esm/createGithubReleaseCommand.js +9 -9
- package/dist/esm/createTags.d.ts +2 -3
- package/dist/esm/decideRelease.d.ts +11 -41
- package/dist/esm/decideRelease.js +5 -27
- package/dist/esm/defaults.d.ts +5 -24
- package/dist/esm/defaults.js +7 -5
- package/dist/esm/defineConfig.d.ts +1 -1
- package/dist/esm/deleteFileIfExists.d.ts +1 -1
- package/dist/esm/deriveReleaseNotesConfig.d.ts +20 -0
- package/dist/esm/deriveReleaseNotesConfig.js +21 -0
- package/dist/esm/deriveWorkspaceConfig.d.ts +3 -5
- package/dist/esm/detectPackageManager.d.ts +2 -4
- package/dist/esm/detectUndeclaredTagPrefixes.d.ts +4 -6
- package/dist/esm/detectUndeclaredTagPrefixes.js +1 -1
- package/dist/esm/determineBumpType.d.ts +11 -11
- package/dist/esm/determineBumpType.js +6 -7
- package/dist/esm/discoverWorkspaces.d.ts +14 -15
- package/dist/esm/discoverWorkspaces.js +12 -12
- package/dist/esm/enterRepoRoot.d.ts +12 -0
- package/dist/esm/enterRepoRoot.js +16 -0
- package/dist/esm/enumerateReleaseWindows.d.ts +50 -0
- package/dist/esm/enumerateReleaseWindows.js +124 -0
- package/dist/esm/extractMigration.d.ts +6 -8
- package/dist/esm/findUnroutedEntryScopes.d.ts +16 -0
- package/dist/esm/findUnroutedEntryScopes.js +57 -0
- package/dist/esm/formatExcludedSkip.d.ts +3 -0
- package/dist/esm/formatExcludedSkip.js +3 -0
- package/dist/esm/formatPrivateSkip.d.ts +1 -6
- package/dist/esm/generateChangelogs.d.ts +13 -26
- package/dist/esm/generateChangelogs.js +0 -14
- package/dist/esm/glyphs.d.ts +2 -2
- package/dist/esm/help/prepareHelp.d.ts +3 -4
- package/dist/esm/help/prepareHelp.js +7 -8
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/init/checks.d.ts +3 -3
- package/dist/esm/init/checks.js +4 -1
- package/dist/esm/init/detectRepoType.d.ts +2 -3
- package/dist/esm/init/hasProvenance.d.ts +2 -0
- package/dist/esm/init/hasProvenance.js +3 -0
- package/dist/esm/init/initCommand.d.ts +3 -6
- package/dist/esm/init/initCommand.js +11 -11
- package/dist/esm/init/parseJsonRecord.d.ts +1 -4
- package/dist/esm/init/scaffold.d.ts +1 -3
- package/dist/esm/init/scaffold.js +2 -30
- package/dist/esm/init/templates.d.ts +9 -11
- package/dist/esm/init/templates.js +12 -11
- package/dist/esm/init/updateTemplatesCommand.d.ts +13 -0
- package/dist/esm/init/updateTemplatesCommand.js +64 -0
- package/dist/esm/injectReleaseNotesIntoReadme.d.ts +12 -17
- package/dist/esm/injectSection.d.ts +3 -3
- package/dist/esm/loadConfig.d.ts +16 -14
- package/dist/esm/loadConfig.js +2 -5
- package/dist/esm/loadValidatedConfig.d.ts +16 -19
- package/dist/esm/loadValidatedConfig.js +6 -1
- package/dist/esm/packsPath.d.ts +9 -9
- package/dist/esm/parseChangeRecordBlock.d.ts +37 -0
- package/dist/esm/parseChangeRecordBlock.js +134 -0
- package/dist/esm/parseCommitMessage.d.ts +42 -32
- package/dist/esm/parseCommitMessage.js +33 -41
- package/dist/esm/parseRequestedTags.d.ts +3 -3
- package/dist/esm/planReleaseNotesPreviews.d.ts +6 -6
- package/dist/esm/planVersionBump.d.ts +5 -3
- package/dist/esm/planVersionBump.js +3 -0
- package/dist/esm/prepareCommand.d.ts +4 -7
- package/dist/esm/prepareCommand.js +17 -18
- package/dist/esm/previewTagPrefixes.d.ts +8 -10
- package/dist/esm/propagateBumps.d.ts +6 -7
- package/dist/esm/publish.d.ts +1 -1
- package/dist/esm/publishCommand.d.ts +4 -3
- package/dist/esm/publishCommand.js +8 -8
- package/dist/esm/pushCommand.d.ts +4 -3
- package/dist/esm/pushCommand.js +8 -2
- package/dist/esm/pushRelease.d.ts +2 -2
- package/dist/esm/readChangelogSections.d.ts +33 -0
- package/dist/esm/readChangelogSections.js +80 -0
- package/dist/esm/releaseFiles.d.ts +5 -7
- package/dist/esm/releasePlan.d.ts +11 -13
- package/dist/esm/releasePrepare.d.ts +25 -25
- package/dist/esm/releasePrepare.js +80 -80
- package/dist/esm/releasePrepareMono.d.ts +9 -7
- package/dist/esm/releasePrepareMono.js +114 -99
- package/dist/esm/releasePrepareProject.d.ts +19 -29
- package/dist/esm/releasePrepareProject.js +46 -45
- package/dist/esm/renderChangelogMarkdown.d.ts +10 -4
- package/dist/esm/renderChangelogMarkdown.js +27 -2
- package/dist/esm/renderReleaseNotes.d.ts +3 -11
- package/dist/esm/renderReleaseNotes.js +2 -6
- package/dist/esm/reportPrepare.d.ts +4 -5
- package/dist/esm/reportPrepare.js +67 -42
- package/dist/esm/resolveCommandTags.d.ts +15 -11
- package/dist/esm/resolveCommandTags.js +35 -5
- package/dist/esm/resolveConfigFlag.d.ts +7 -0
- package/dist/esm/resolveConfigFlag.js +4 -0
- package/dist/esm/resolveReleaseTags.d.ts +6 -8
- package/dist/esm/resolveReleaseTags.js +1 -1
- package/dist/esm/resolveStylesOrExit.d.ts +2 -2
- package/dist/esm/showTagPrefixesCommand.d.ts +7 -10
- package/dist/esm/showTagPrefixesCommand.js +4 -4
- package/dist/esm/stripEmojiPrefix.d.ts +1 -0
- package/dist/esm/stripScope.d.ts +2 -2
- package/dist/esm/stripScope.js +3 -3
- package/dist/esm/sync-labels/generateCommand.d.ts +11 -10
- package/dist/esm/sync-labels/generateCommand.js +11 -8
- package/dist/esm/sync-labels/initCommand.d.ts +6 -7
- package/dist/esm/sync-labels/initCommand.js +2 -2
- package/dist/esm/sync-labels/presets.d.ts +5 -4
- package/dist/esm/sync-labels/presets.js +9 -9
- package/dist/esm/sync-labels/resolveLabels.d.ts +7 -7
- package/dist/esm/sync-labels/resolveLabels.js +1 -1
- package/dist/esm/sync-labels/retiredConfig.d.ts +4 -5
- package/dist/esm/sync-labels/syncCommand.d.ts +1 -4
- package/dist/esm/sync-labels/templates.d.ts +3 -3
- package/dist/esm/sync-labels/templates.js +3 -3
- package/dist/esm/sync-labels/typeLabels.d.ts +14 -0
- package/dist/esm/sync-labels/typeLabels.js +38 -0
- package/dist/esm/sync-labels/types.d.ts +1 -1
- package/dist/esm/tagCommand.d.ts +1 -1
- package/dist/esm/typeGuards.d.ts +2 -2
- package/dist/esm/types.d.ts +185 -116
- package/dist/esm/types.js +2 -2
- package/dist/esm/validateConfig.d.ts +2 -11
- package/dist/esm/validateConfig.js +5 -1
- package/dist/esm/validateOnlyExcludesStrandedDependents.d.ts +14 -12
- package/dist/esm/validateOverridesCommand.d.ts +19 -21
- package/dist/esm/validateOverridesCommand.js +16 -23
- package/docs/api.md +6 -6
- package/docs/changelogs.md +90 -28
- package/docs/configuration.md +30 -29
- package/docs/editorial-overrides.md +90 -31
- package/docs/labels.md +21 -19
- package/docs/project-releases.md +14 -14
- package/docs/publishing.md +5 -5
- package/docs/readiness-checks.md +3 -3
- package/docs/releasing.md +54 -24
- package/docs/work-types.md +46 -58
- package/package.json +7 -7
- package/presets/labels/common.yaml +1 -41
- package/schemas/changelog-overrides.json +39 -0
- package/cliff.toml.template +0 -65
- package/dist/esm/collectPolicyViolations.d.ts +0 -15
- package/dist/esm/collectPolicyViolations.js +0 -12
- package/dist/esm/determineBumpFromCommits.d.ts +0 -17
- package/dist/esm/determineBumpFromCommits.js +0 -28
- package/dist/esm/getCommitsSinceTarget.d.ts +0 -21
- package/dist/esm/getCommitsSinceTarget.js +0 -66
- package/dist/esm/resolveCliffConfigPath.d.ts +0 -11
- package/dist/esm/resolveCliffConfigPath.js +0 -20
- package/dist/esm/resolveReleaseNotesConfig.d.ts +0 -26
- package/dist/esm/resolveReleaseNotesConfig.js +0 -29
- package/dist/esm/runGitCliff.d.ts +0 -38
- package/dist/esm/runGitCliff.js +0 -25
- package/dist/esm/workTypesData.d.ts +0 -50
- package/dist/esm/workTypesData.js +0 -145
- package/schemas/label-map.json +0 -24
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import type { ReleasePlan } from './releasePlan.js';
|
|
2
2
|
import type { ReleasePrepareOptions } from './releasePrepare.js';
|
|
3
|
-
import type {
|
|
3
|
+
import type { MonorepoPrepareConfig } from './types.js';
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Orchestrates release preparation for a monorepo with multiple workspaces.
|
|
6
6
|
*
|
|
7
|
-
* Phase 1:
|
|
8
|
-
* Phase 2:
|
|
9
|
-
* Phase 2b:
|
|
10
|
-
* Phase 3:
|
|
7
|
+
* Phase 1: Determines direct bumps from commits for each workspace.
|
|
8
|
+
* Phase 2: Builds the dependency graph and propagates bumps to dependents.
|
|
9
|
+
* Phase 2b: Sorts the full release set topologically.
|
|
10
|
+
* Phase 3: Plans bumps and changelogs in dependency order.
|
|
11
|
+
* Phase 3b: Plans the project release.
|
|
12
|
+
* Phase 4: Renders the format command.
|
|
11
13
|
*/
|
|
12
|
-
export declare function releasePrepareMono(config:
|
|
14
|
+
export declare function releasePrepareMono(config: MonorepoPrepareConfig, options: ReleasePrepareOptions): ReleasePlan;
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
import { join as joinPath } from 'node:path';
|
|
2
2
|
import { chainError } from '@williamthorsen/toolbelt.errors/candidate';
|
|
3
|
-
import {
|
|
3
|
+
import { assertTaggedBaseline, findUntaggedBaseline } from "./assertTaggedBaseline.js";
|
|
4
|
+
import { attachChangelogDiagnostics } from "./attachChangelogDiagnostics.js";
|
|
5
|
+
import { readReleaseHistory, toReleaseEntries } from "./buildChangelogEntries.js";
|
|
4
6
|
import { buildDependencyGraph } from "./buildDependencyGraph.js";
|
|
5
|
-
import { buildEmptyReleaseEntry } from "./buildEmptyReleaseEntry.js";
|
|
6
7
|
import { buildReleaseSummary } from "./buildReleaseSummary.js";
|
|
7
8
|
import { buildSyntheticChangelogEntry } from "./buildSyntheticChangelogEntry.js";
|
|
8
9
|
import { mergeChangelogEntriesWithDisk, renderChangelogJson, resolveChangelogJsonPath } from "./changelogJsonFile.js";
|
|
9
10
|
import { applyWorkspaceOverrides, createOverrideContext, formatStaleOverrideKeyWarning, } from "./changelogOverrides.js";
|
|
10
|
-
import { createPolicyViolationCollector } from "./collectPolicyViolations.js";
|
|
11
11
|
import { decideRelease } from "./decideRelease.js";
|
|
12
|
-
import {
|
|
12
|
+
import { deriveDependenciesHeader, deriveSectionOrder } from "./deriveReleaseNotesConfig.js";
|
|
13
13
|
import { detectUndeclaredTagPrefixes } from "./detectUndeclaredTagPrefixes.js";
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
14
|
+
import { findUnroutedEntryScopes } from "./findUnroutedEntryScopes.js";
|
|
15
|
+
import { getAllTagPrefixes } from "./generateChangelogs.js";
|
|
16
16
|
import { hasPrettierConfig } from "./hasPrettierConfig.js";
|
|
17
17
|
import { resolveWorkTypes } from "./loadConfig.js";
|
|
18
18
|
import { planReleaseNotesPreviews } from "./planReleaseNotesPreviews.js";
|
|
19
19
|
import { planVersionBump, planVersionSet } from "./planVersionBump.js";
|
|
20
20
|
import { propagateBumps } from "./propagateBumps.js";
|
|
21
|
+
import { planPreservedSections } from "./readChangelogSections.js";
|
|
21
22
|
import { releasePrepareProject } from "./releasePrepareProject.js";
|
|
22
23
|
import { renderChangelogMarkdown } from "./renderChangelogMarkdown.js";
|
|
23
|
-
import { deriveSectionOrder } from "./resolveReleaseNotesConfig.js";
|
|
24
24
|
export function releasePrepareMono(config, options) {
|
|
25
25
|
const { only, withReleaseNotes } = options;
|
|
26
26
|
const writes = [];
|
|
@@ -28,18 +28,18 @@ export function releasePrepareMono(config, options) {
|
|
|
28
28
|
if (withReleaseNotes === true && !config.changelogJson.enabled) {
|
|
29
29
|
warnings.push('--with-release-notes requires changelogJson.enabled; skipping preview generation');
|
|
30
30
|
}
|
|
31
|
-
const
|
|
31
|
+
const workTypes = resolveWorkTypes(config.workTypes);
|
|
32
|
+
const sectionOrder = deriveSectionOrder(workTypes);
|
|
33
|
+
const dependenciesHeader = deriveDependenciesHeader(workTypes);
|
|
32
34
|
const overrideContext = createOverrideContext(config.workspaces);
|
|
33
|
-
const { directBumps, directResults, skippedResults } = determineDirectBumps(config, options);
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
previousTags.set(result.workspace.dir, result.tag);
|
|
37
|
-
}
|
|
38
|
-
for (const skipped of skippedResults) {
|
|
39
|
-
previousTags.set(skipped.workspace.dir, skipped.tag);
|
|
40
|
-
}
|
|
35
|
+
const { directBumps, directResults, skippedResults, untaggedBaselines } = determineDirectBumps(config, options);
|
|
36
|
+
reportUnroutedEntryScopes([...directResults.values(), ...skippedResults], config, options);
|
|
37
|
+
const skippedHistories = new Map(skippedResults.map((skipped) => [skipped.workspace.dir, skipped.history]));
|
|
41
38
|
const graph = buildDependencyGraph(config.workspaces);
|
|
42
39
|
const fullReleaseSet = propagateBumps(directBumps, graph);
|
|
40
|
+
assertTaggedBaseline([...untaggedBaselines]
|
|
41
|
+
.filter(([dir]) => directBumps.has(dir) || !fullReleaseSet.has(dir))
|
|
42
|
+
.map(([, untagged]) => untagged));
|
|
43
43
|
const { sorted: sortedDirs, cyclicDirs } = topologicalSort(fullReleaseSet, graph);
|
|
44
44
|
if (cyclicDirs.length > 0) {
|
|
45
45
|
warnings.push(`Circular workspace dependencies detected among: ${cyclicDirs.join(', ')}. ` +
|
|
@@ -55,13 +55,14 @@ export function releasePrepareMono(config, options) {
|
|
|
55
55
|
fullReleaseSet,
|
|
56
56
|
config,
|
|
57
57
|
directResults,
|
|
58
|
-
|
|
58
|
+
skippedHistories,
|
|
59
59
|
writes,
|
|
60
60
|
warnings,
|
|
61
61
|
workspaces,
|
|
62
62
|
previewOptions,
|
|
63
63
|
overrideContext,
|
|
64
64
|
sectionOrder,
|
|
65
|
+
dependenciesHeader,
|
|
65
66
|
});
|
|
66
67
|
const configOrder = new Map(config.workspaces.map((w, i) => [w.dir, i]));
|
|
67
68
|
workspaces.sort((a, b) => {
|
|
@@ -111,18 +112,28 @@ function determineDirectBumps(config, options) {
|
|
|
111
112
|
if (setVersion !== undefined && config.workspaces.length !== 1) {
|
|
112
113
|
throw new Error(`--set-version requires exactly one workspace; received ${config.workspaces.length}`);
|
|
113
114
|
}
|
|
114
|
-
const workTypes = config.workTypes ?? { ...DEFAULT_WORK_TYPES };
|
|
115
|
-
const versionPatterns = config.versionPatterns ?? { ...DEFAULT_VERSION_PATTERNS };
|
|
116
|
-
const breakingPolicies = config.breakingPolicies ?? DEFAULT_BREAKING_POLICIES;
|
|
117
115
|
const directBumps = new Map();
|
|
118
116
|
const directResults = new Map();
|
|
119
117
|
const skippedResults = [];
|
|
118
|
+
const untaggedBaselines = new Map();
|
|
120
119
|
const hintState = { emitted: false };
|
|
121
120
|
const knownPrefixes = config.workspaces.flatMap(getAllTagPrefixes);
|
|
122
121
|
for (const workspace of config.workspaces) {
|
|
123
122
|
const name = workspace.dir;
|
|
124
123
|
const stageLabel = workspaceStageLabel(workspace.dir);
|
|
125
|
-
const
|
|
124
|
+
const tagPrefixes = getAllTagPrefixes(workspace);
|
|
125
|
+
const history = tryStage(stageLabel, () => readReleaseHistory(config, { tagPrefixes, paths: workspace.paths, workspaceDir: workspace.dir }));
|
|
126
|
+
const untagged = tryStage(stageLabel, () => findUntaggedBaseline({
|
|
127
|
+
label: `workspace '${workspace.dir}'`,
|
|
128
|
+
packageFiles: workspace.packageFiles,
|
|
129
|
+
changelogPaths: workspace.changelogPaths,
|
|
130
|
+
tagPrefixes,
|
|
131
|
+
previousTag: history.previousTag,
|
|
132
|
+
}, config));
|
|
133
|
+
if (untagged !== undefined) {
|
|
134
|
+
untaggedBaselines.set(workspace.dir, untagged);
|
|
135
|
+
}
|
|
136
|
+
const tag = history.previousTag;
|
|
126
137
|
const since = tag === undefined ? '(no previous release found)' : `since ${tag}`;
|
|
127
138
|
if (tag === undefined) {
|
|
128
139
|
maybeEmitBaselineHint(workspace, knownPrefixes, hintState);
|
|
@@ -131,58 +142,42 @@ function determineDirectBumps(config, options) {
|
|
|
131
142
|
directBumps.set(workspace.dir, { releaseType: 'patch', newVersionOverride: setVersion });
|
|
132
143
|
directResults.set(workspace.dir, {
|
|
133
144
|
workspace,
|
|
134
|
-
|
|
135
|
-
commits,
|
|
145
|
+
history,
|
|
136
146
|
releaseType: undefined,
|
|
137
|
-
parsedCommitCount: undefined,
|
|
138
|
-
unparseableCommits: undefined,
|
|
139
|
-
policyViolations: undefined,
|
|
140
147
|
bumpOverride: undefined,
|
|
141
148
|
setVersion,
|
|
142
149
|
});
|
|
143
150
|
continue;
|
|
144
151
|
}
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
commits,
|
|
152
|
+
const decision = decideRelease({
|
|
153
|
+
naturalBump: history.unreleased.bump,
|
|
154
|
+
commitCount: history.unreleased.commits.length,
|
|
148
155
|
force,
|
|
149
156
|
bumpOverride,
|
|
150
|
-
workTypes,
|
|
151
|
-
versionPatterns,
|
|
152
|
-
scopeAliases: config.scopeAliases,
|
|
153
|
-
breakingPolicies,
|
|
154
|
-
onPolicyViolation: collector.onPolicyViolation,
|
|
155
157
|
skipReasons: {
|
|
156
158
|
noCommits: `No commits for ${name} ${since}. Pass --force to release at patch. Skipping.`,
|
|
157
159
|
noBumpWorthy: `No bump-worthy commits for ${name} ${since}. Pass --force to release at patch (or --force --bump=X for a different level). Skipping.`,
|
|
158
160
|
},
|
|
159
|
-
})
|
|
160
|
-
const policyViolations = collector.violations.length > 0 ? collector.violations : undefined;
|
|
161
|
+
});
|
|
161
162
|
if (decision.outcome === 'skip') {
|
|
162
|
-
skippedResults.push({
|
|
163
|
-
workspace,
|
|
164
|
-
tag,
|
|
165
|
-
commitCount: commits.length,
|
|
166
|
-
parsedCommitCount: decision.parsedCommitCount,
|
|
167
|
-
unparseableCommits: decision.unparseableCommits,
|
|
168
|
-
policyViolations,
|
|
169
|
-
skipReason: decision.skipReason,
|
|
170
|
-
});
|
|
163
|
+
skippedResults.push({ workspace, history, skipReason: decision.skipReason });
|
|
171
164
|
continue;
|
|
172
165
|
}
|
|
173
166
|
directBumps.set(workspace.dir, { releaseType: decision.releaseType });
|
|
174
167
|
directResults.set(workspace.dir, {
|
|
175
168
|
workspace,
|
|
176
|
-
|
|
177
|
-
commits,
|
|
169
|
+
history,
|
|
178
170
|
releaseType: decision.releaseType,
|
|
179
|
-
parsedCommitCount: decision.parsedCommitCount,
|
|
180
|
-
unparseableCommits: decision.unparseableCommits,
|
|
181
|
-
policyViolations,
|
|
182
171
|
bumpOverride,
|
|
183
172
|
});
|
|
184
173
|
}
|
|
185
|
-
return { directBumps, directResults, skippedResults };
|
|
174
|
+
return { directBumps, directResults, skippedResults, untaggedBaselines };
|
|
175
|
+
}
|
|
176
|
+
function reportUnroutedEntryScopes(results, config, options) {
|
|
177
|
+
const findings = findUnroutedEntryScopes(results.map(({ workspace, history }) => ({ dir: workspace.dir, commits: history.unreleased.commits })), options.configuredWorkspaceDirs ?? config.workspaces.map((workspace) => workspace.dir), config.scopeAliases ?? {});
|
|
178
|
+
for (const { workspace, history } of results) {
|
|
179
|
+
history.unreleased.diagnostics.unroutedEntryScopes = findings.get(workspace.dir) ?? [];
|
|
180
|
+
}
|
|
186
181
|
}
|
|
187
182
|
function collectSkippedWorkspaces(skippedResults, fullReleaseSet) {
|
|
188
183
|
const workspaces = [];
|
|
@@ -190,30 +185,27 @@ function collectSkippedWorkspaces(skippedResults, fullReleaseSet) {
|
|
|
190
185
|
if (fullReleaseSet.has(skipped.workspace.dir)) {
|
|
191
186
|
continue;
|
|
192
187
|
}
|
|
188
|
+
const { previousTag, unreleased } = skipped.history;
|
|
193
189
|
const result = {
|
|
194
190
|
name: skipped.workspace.dir,
|
|
195
191
|
status: 'skipped',
|
|
196
|
-
commitCount:
|
|
192
|
+
commitCount: unreleased.commits.length,
|
|
193
|
+
parsedCommitCount: unreleased.parsedCommitCount,
|
|
197
194
|
skipReason: skipped.skipReason,
|
|
198
195
|
};
|
|
199
|
-
if (
|
|
200
|
-
result.previousTag =
|
|
196
|
+
if (previousTag !== undefined) {
|
|
197
|
+
result.previousTag = previousTag;
|
|
201
198
|
}
|
|
202
|
-
if (
|
|
203
|
-
result.
|
|
204
|
-
}
|
|
205
|
-
if (skipped.unparseableCommits !== undefined) {
|
|
206
|
-
result.unparseableCommits = skipped.unparseableCommits;
|
|
207
|
-
}
|
|
208
|
-
if (skipped.policyViolations !== undefined) {
|
|
209
|
-
result.policyViolations = skipped.policyViolations;
|
|
199
|
+
if (unreleased.unparseableCommits !== undefined) {
|
|
200
|
+
result.unparseableCommits = unreleased.unparseableCommits;
|
|
210
201
|
}
|
|
202
|
+
attachChangelogDiagnostics(result, unreleased.diagnostics);
|
|
211
203
|
workspaces.push(result);
|
|
212
204
|
}
|
|
213
205
|
return workspaces;
|
|
214
206
|
}
|
|
215
207
|
function executeReleaseSet(args) {
|
|
216
|
-
const { sortedDirs, fullReleaseSet, config, directResults,
|
|
208
|
+
const { sortedDirs, fullReleaseSet, config, directResults, skippedHistories, writes, warnings, workspaces, previewOptions, overrideContext, sectionOrder, dependenciesHeader, } = args;
|
|
217
209
|
const tags = [];
|
|
218
210
|
const modifiedFiles = [];
|
|
219
211
|
const today = new Date().toISOString().slice(0, 10);
|
|
@@ -231,7 +223,7 @@ function executeReleaseSet(args) {
|
|
|
231
223
|
workspace,
|
|
232
224
|
releaseEntry,
|
|
233
225
|
directResult: directResults.get(dir),
|
|
234
|
-
|
|
226
|
+
skippedHistory: skippedHistories.get(dir),
|
|
235
227
|
config,
|
|
236
228
|
today,
|
|
237
229
|
tags,
|
|
@@ -242,12 +234,13 @@ function executeReleaseSet(args) {
|
|
|
242
234
|
previewOptions,
|
|
243
235
|
overrideContext,
|
|
244
236
|
sectionOrder,
|
|
237
|
+
dependenciesHeader,
|
|
245
238
|
}));
|
|
246
239
|
}
|
|
247
240
|
return { tags, modifiedFiles };
|
|
248
241
|
}
|
|
249
242
|
function executeWorkspaceRelease(args) {
|
|
250
|
-
const { dir, workspace, releaseEntry, directResult,
|
|
243
|
+
const { dir, workspace, releaseEntry, directResult, skippedHistory, config, today, tags, modifiedFiles, writes, warnings, workspaces, previewOptions, overrideContext, sectionOrder, dependenciesHeader, } = args;
|
|
251
244
|
const setVersionTarget = directResult?.setVersion;
|
|
252
245
|
const bump = setVersionTarget === undefined
|
|
253
246
|
? planVersionBump(workspace.packageFiles, releaseEntry.releaseType)
|
|
@@ -256,15 +249,13 @@ function executeWorkspaceRelease(args) {
|
|
|
256
249
|
tags.push(newTag);
|
|
257
250
|
writes.push(...bump.writes);
|
|
258
251
|
modifiedFiles.push(...workspace.packageFiles, ...workspace.changelogPaths.map((changelogPath) => joinPath(changelogPath, 'CHANGELOG.md')));
|
|
259
|
-
const
|
|
260
|
-
const
|
|
261
|
-
const { changelogFiles, previewFiles } = generateWorkspaceChangelogs({
|
|
252
|
+
const phase1History = directResult?.history ?? skippedHistory;
|
|
253
|
+
const { changelogFiles, changelogPreservation, previewFiles } = generateWorkspaceChangelogs({
|
|
262
254
|
workspace,
|
|
263
255
|
releaseEntry,
|
|
264
256
|
newTag,
|
|
265
257
|
newVersion: bump.newVersion,
|
|
266
|
-
|
|
267
|
-
isEmptyRange,
|
|
258
|
+
history: directResult?.history,
|
|
268
259
|
config,
|
|
269
260
|
today,
|
|
270
261
|
modifiedFiles,
|
|
@@ -273,45 +264,42 @@ function executeWorkspaceRelease(args) {
|
|
|
273
264
|
previewOptions,
|
|
274
265
|
overrideContext,
|
|
275
266
|
sectionOrder,
|
|
267
|
+
dependenciesHeader,
|
|
276
268
|
});
|
|
277
269
|
const released = {
|
|
278
270
|
name: dir,
|
|
279
271
|
status: 'released',
|
|
280
|
-
commitCount:
|
|
272
|
+
commitCount: phase1History?.unreleased.commits.length ?? 0,
|
|
281
273
|
currentVersion: bump.currentVersion,
|
|
282
274
|
newVersion: bump.newVersion,
|
|
283
275
|
tag: newTag,
|
|
284
276
|
bumpedFiles: bump.writes.map((write) => write.path),
|
|
285
277
|
changelogFiles,
|
|
286
278
|
...(previewFiles.length > 0 && { previewFiles }),
|
|
279
|
+
...(changelogPreservation.length > 0 && { changelogPreservation }),
|
|
287
280
|
};
|
|
288
281
|
attachReleasedWorkspaceOptionals(released, {
|
|
289
|
-
previousTag:
|
|
282
|
+
previousTag: phase1History?.previousTag,
|
|
290
283
|
directResult,
|
|
284
|
+
skippedHistory,
|
|
291
285
|
releaseEntry,
|
|
292
286
|
setVersionTarget,
|
|
293
287
|
});
|
|
294
288
|
workspaces.push(released);
|
|
295
289
|
}
|
|
296
290
|
function attachReleasedWorkspaceOptionals(released, args) {
|
|
297
|
-
const { previousTag, directResult, releaseEntry, setVersionTarget } = args;
|
|
291
|
+
const { previousTag, directResult, skippedHistory, releaseEntry, setVersionTarget } = args;
|
|
298
292
|
if (previousTag !== undefined) {
|
|
299
293
|
released.previousTag = previousTag;
|
|
300
294
|
}
|
|
301
|
-
if (directResult?.parsedCommitCount !== undefined) {
|
|
302
|
-
released.parsedCommitCount = directResult.parsedCommitCount;
|
|
303
|
-
}
|
|
304
295
|
if (setVersionTarget === undefined) {
|
|
305
296
|
released.releaseType = releaseEntry.releaseType;
|
|
306
297
|
}
|
|
307
|
-
if (directResult
|
|
308
|
-
released.
|
|
298
|
+
if (directResult !== undefined) {
|
|
299
|
+
attachDirectHistory(released, directResult.history.unreleased, setVersionTarget === undefined);
|
|
309
300
|
}
|
|
310
|
-
|
|
311
|
-
released
|
|
312
|
-
}
|
|
313
|
-
if (directResult?.policyViolations !== undefined) {
|
|
314
|
-
released.policyViolations = directResult.policyViolations;
|
|
301
|
+
else {
|
|
302
|
+
attachPropagatedHistory(released, skippedHistory?.unreleased);
|
|
315
303
|
}
|
|
316
304
|
if (releaseEntry.propagatedFrom !== undefined) {
|
|
317
305
|
released.propagatedFrom = releaseEntry.propagatedFrom;
|
|
@@ -323,20 +311,41 @@ function attachReleasedWorkspaceOptionals(released, args) {
|
|
|
323
311
|
released.setVersion = setVersionTarget;
|
|
324
312
|
}
|
|
325
313
|
}
|
|
314
|
+
function attachDirectHistory(released, unreleased, hasDecidedBump) {
|
|
315
|
+
released.commits = unreleased.commits;
|
|
316
|
+
if (hasDecidedBump) {
|
|
317
|
+
released.parsedCommitCount = unreleased.parsedCommitCount;
|
|
318
|
+
if (unreleased.unparseableCommits !== undefined) {
|
|
319
|
+
released.unparseableCommits = unreleased.unparseableCommits;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
attachChangelogDiagnostics(released, unreleased.diagnostics);
|
|
323
|
+
}
|
|
324
|
+
function attachPropagatedHistory(released, unreleased) {
|
|
325
|
+
released.propagatedOnly = true;
|
|
326
|
+
if (unreleased === undefined) {
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
released.commits = unreleased.commits;
|
|
330
|
+
if (unreleased.unparseableCommits !== undefined) {
|
|
331
|
+
released.unparseableCommits = unreleased.unparseableCommits;
|
|
332
|
+
}
|
|
333
|
+
attachChangelogDiagnostics(released, unreleased.diagnostics);
|
|
334
|
+
}
|
|
326
335
|
function generateWorkspaceChangelogs(args) {
|
|
327
|
-
const { workspace, releaseEntry, newTag, newVersion,
|
|
328
|
-
const
|
|
336
|
+
const { workspace, releaseEntry, newTag, newVersion, history, config, today, modifiedFiles, writes, warnings, previewOptions, overrideContext, sectionOrder, dependenciesHeader, } = args;
|
|
337
|
+
const entries = buildWorkspaceEntries({
|
|
329
338
|
workspace,
|
|
330
339
|
releaseEntry,
|
|
331
340
|
newTag,
|
|
332
341
|
newVersion,
|
|
333
|
-
|
|
334
|
-
isEmptyRange,
|
|
335
|
-
config,
|
|
342
|
+
history,
|
|
336
343
|
today,
|
|
344
|
+
dependenciesHeader,
|
|
337
345
|
});
|
|
338
|
-
const applied = applyWorkspaceOverrides(
|
|
346
|
+
const applied = applyWorkspaceOverrides(entries, workspace.workspacePath, overrideContext);
|
|
339
347
|
const changelogFiles = [];
|
|
348
|
+
const changelogPreservation = [];
|
|
340
349
|
let firstMergedEntries;
|
|
341
350
|
for (const changelogPath of workspace.changelogPaths) {
|
|
342
351
|
const jsonPath = resolveChangelogJsonPath(config, changelogPath);
|
|
@@ -347,23 +356,29 @@ function generateWorkspaceChangelogs(args) {
|
|
|
347
356
|
firstMergedEntries ??= mergedEntries;
|
|
348
357
|
}
|
|
349
358
|
const changelogFile = joinPath(changelogPath, 'CHANGELOG.md');
|
|
350
|
-
|
|
359
|
+
const preserved = planPreservedSections(changelogFile, mergedEntries);
|
|
360
|
+
writes.push({
|
|
361
|
+
path: changelogFile,
|
|
362
|
+
content: renderChangelogMarkdown(mergedEntries, { sectionOrder, preservedSections: preserved.sections }),
|
|
363
|
+
});
|
|
351
364
|
changelogFiles.push(changelogFile);
|
|
365
|
+
if (preserved.preservation !== undefined) {
|
|
366
|
+
changelogPreservation.push(preserved.preservation);
|
|
367
|
+
}
|
|
352
368
|
}
|
|
353
369
|
const previews = planPreviews(workspace, newTag, firstMergedEntries, previewOptions, warnings);
|
|
354
370
|
writes.push(...previews);
|
|
355
|
-
return { changelogFiles, previewFiles: previews.map((write) => write.path) };
|
|
371
|
+
return { changelogFiles, changelogPreservation, previewFiles: previews.map((write) => write.path) };
|
|
356
372
|
}
|
|
357
373
|
function buildWorkspaceEntries(args) {
|
|
358
|
-
const { workspace, releaseEntry, newTag, newVersion,
|
|
359
|
-
if (
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
return [
|
|
374
|
+
const { workspace, releaseEntry, newTag, newVersion, history, today, dependenciesHeader } = args;
|
|
375
|
+
if (history === undefined) {
|
|
376
|
+
if (releaseEntry.propagatedFrom === undefined) {
|
|
377
|
+
throw new Error(`Workspace '${workspace.dir}' has neither a direct release nor a propagation source`);
|
|
378
|
+
}
|
|
379
|
+
return [buildSyntheticChangelogEntry(releaseEntry.propagatedFrom, newVersion, today, dependenciesHeader)];
|
|
364
380
|
}
|
|
365
|
-
|
|
366
|
-
return buildChangelogEntries(config, newTag, { tagPattern, includePaths: workspace.paths });
|
|
381
|
+
return toReleaseEntries(history, newTag, today);
|
|
367
382
|
}
|
|
368
383
|
function planPreviews(workspace, newTag, entries, previewOptions, warnings) {
|
|
369
384
|
if (!previewOptions.enabled || entries === undefined) {
|
|
@@ -1,57 +1,47 @@
|
|
|
1
1
|
import type { PlannedWrite } from './releasePlan.js';
|
|
2
2
|
import type { ReleasePrepareOptions } from './releasePrepare.js';
|
|
3
|
-
import type { ChangelogOverride,
|
|
3
|
+
import type { ChangelogOverride, MonorepoPrepareConfig, ProjectPrepareResult } from './types.js';
|
|
4
4
|
/** Inputs to the project-release stage. */
|
|
5
5
|
export interface ReleasePrepareProjectArgs {
|
|
6
6
|
/** Resolved monorepo config; `config.project` must be defined when this function is called. */
|
|
7
|
-
config:
|
|
7
|
+
config: MonorepoPrepareConfig;
|
|
8
8
|
options: ReleasePrepareOptions;
|
|
9
9
|
/** Mutated in-place to append project-level files (root package.json, root CHANGELOG.md, root changelog.json). */
|
|
10
10
|
modifiedFiles: string[];
|
|
11
|
-
/** Mutated in-place to append every file this stage intends to write. */
|
|
11
|
+
/** Mutated in-place to append every file that this stage intends to write. */
|
|
12
12
|
writes: PlannedWrite[];
|
|
13
13
|
/** Mutated in-place to append the project tag. */
|
|
14
14
|
tags: string[];
|
|
15
15
|
/**
|
|
16
|
-
* Mutated in-place to
|
|
17
|
-
*
|
|
16
|
+
* Mutated in-place to receive the warnings that this stage raises and that are not override-specific.
|
|
17
|
+
* Defaults to a discardable sink.
|
|
18
18
|
*/
|
|
19
19
|
warnings?: string[];
|
|
20
20
|
/**
|
|
21
|
-
* Root-tier editorial overrides
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* meaning at the aggregated project tier.
|
|
21
|
+
* Root-tier editorial overrides. Defaults to an empty map. The project changelog applies only the
|
|
22
|
+
* root-tier file: Per-workspace files describe per-workspace editorial intent and are
|
|
23
|
+
* meaningless at the aggregated project tier.
|
|
25
24
|
*/
|
|
26
25
|
rootOverrides?: Map<string, ChangelogOverride>;
|
|
27
26
|
/**
|
|
28
|
-
* Mutated in-place to
|
|
29
|
-
*
|
|
30
|
-
* a discardable sink when omitted.
|
|
27
|
+
* Mutated in-place to receive override-application warnings. Stale-key warnings are not among them: Those
|
|
28
|
+
* depend on the matches of every batch, which `globalMatchedRootKeys` collects. Defaults to a discardable sink.
|
|
31
29
|
*/
|
|
32
30
|
overrideWarnings?: string[];
|
|
33
31
|
/**
|
|
34
|
-
* Mutated in-place
|
|
35
|
-
*
|
|
36
|
-
* sink when omitted.
|
|
32
|
+
* Mutated in-place to receive every root-tier override key that this stage matches, so that stale-key
|
|
33
|
+
* warnings can cover the whole run. Defaults to a discardable sink.
|
|
37
34
|
*/
|
|
38
35
|
globalMatchedRootKeys?: Set<string>;
|
|
39
36
|
}
|
|
40
37
|
/**
|
|
41
|
-
*
|
|
38
|
+
* Runs the project-level release stage: reads the history, decides the bump, and plans the root `package.json`
|
|
39
|
+
* bump, the root `CHANGELOG.md`, and optionally `changelog.json` and release-notes previews. Contributing paths
|
|
40
|
+
* come from the resolved `project.paths`, which defaults to the union of every (already-filtered) workspace's
|
|
41
|
+
* `paths`.
|
|
42
42
|
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* the resolved `project.paths`, which defaults to the union of every (already-filtered)
|
|
47
|
-
* workspace's `paths`.
|
|
48
|
-
*
|
|
49
|
-
* Returns a structured `{ status: 'skipped', skipReason, ... }` result when neither
|
|
50
|
-
* commits nor `--force` provide a release signal. The caller should attach the returned
|
|
51
|
-
* result to `PrepareResult.project`. `undefined` is returned only when there is no
|
|
52
|
-
* configured `project` block — handled at the call site, not here.
|
|
53
|
-
*
|
|
54
|
-
* Caller contract: `prepareCommand` rejects `--only` upstream when a project block is
|
|
55
|
-
* configured, so this orchestrator never has to reason about workspace-narrowing flags.
|
|
43
|
+
* Returns a `skipped` result when neither commits nor `--force` provide a release signal, and throws when
|
|
44
|
+
* `config.project` is undefined. A run narrowed by `--only` does not reach this stage, so it doesn't
|
|
45
|
+
* read any narrowing flag.
|
|
56
46
|
*/
|
|
57
47
|
export declare function releasePrepareProject(args: ReleasePrepareProjectArgs): ProjectPrepareResult;
|