@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.
Files changed (135) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +12 -12
  3. package/dist/esm/.cache +1 -1
  4. package/dist/esm/assertCleanWorkingTree.js +9 -14
  5. package/dist/esm/bin/release-kit.js +202 -229
  6. package/dist/esm/buildChangelogEntries.d.ts +2 -2
  7. package/dist/esm/buildChangelogEntries.js +142 -149
  8. package/dist/esm/buildDependencyGraph.d.ts +1 -1
  9. package/dist/esm/buildDependencyGraph.js +60 -59
  10. package/dist/esm/buildEmptyReleaseEntry.d.ts +1 -1
  11. package/dist/esm/buildEmptyReleaseEntry.js +12 -15
  12. package/dist/esm/buildReleaseSummary.d.ts +1 -1
  13. package/dist/esm/buildReleaseSummary.js +23 -26
  14. package/dist/esm/buildSyntheticChangelogEntry.d.ts +1 -1
  15. package/dist/esm/buildSyntheticChangelogEntry.js +9 -12
  16. package/dist/esm/bumpAllVersions.d.ts +1 -1
  17. package/dist/esm/bumpAllVersions.js +51 -52
  18. package/dist/esm/bumpVersion.d.ts +1 -1
  19. package/dist/esm/bumpVersion.js +25 -28
  20. package/dist/esm/changelogJsonFile.d.ts +1 -1
  21. package/dist/esm/changelogJsonFile.js +59 -62
  22. package/dist/esm/changelogJsonUtils.d.ts +1 -1
  23. package/dist/esm/changelogJsonUtils.js +35 -32
  24. package/dist/esm/changelogOverrides.d.ts +1 -1
  25. package/dist/esm/changelogOverrides.js +374 -377
  26. package/dist/esm/checkWorkTypesDrift.js +104 -99
  27. package/dist/esm/collectPolicyViolations.d.ts +2 -2
  28. package/dist/esm/collectPolicyViolations.js +11 -14
  29. package/dist/esm/commitCommand.js +48 -53
  30. package/dist/esm/compareVersions.js +20 -23
  31. package/dist/esm/createGithubRelease.js +56 -59
  32. package/dist/esm/createGithubReleaseCommand.js +21 -29
  33. package/dist/esm/createTags.js +57 -56
  34. package/dist/esm/decideRelease.d.ts +2 -2
  35. package/dist/esm/decideRelease.js +27 -41
  36. package/dist/esm/defaults.d.ts +3 -3
  37. package/dist/esm/defaults.js +36 -48
  38. package/dist/esm/deleteFileIfExists.js +10 -12
  39. package/dist/esm/deriveWorkspaceConfig.d.ts +1 -1
  40. package/dist/esm/deriveWorkspaceConfig.js +34 -36
  41. package/dist/esm/detectPackageManager.js +35 -37
  42. package/dist/esm/detectUndeclaredTagPrefixes.js +41 -40
  43. package/dist/esm/determineBumpFromCommits.d.ts +2 -2
  44. package/dist/esm/determineBumpFromCommits.js +25 -29
  45. package/dist/esm/determineBumpType.d.ts +1 -1
  46. package/dist/esm/determineBumpType.js +31 -32
  47. package/dist/esm/discoverWorkspaces.js +38 -40
  48. package/dist/esm/format.js +6 -11
  49. package/dist/esm/generateChangelogs.d.ts +1 -1
  50. package/dist/esm/generateChangelogs.js +13 -17
  51. package/dist/esm/getCommitsSinceTarget.d.ts +1 -1
  52. package/dist/esm/getCommitsSinceTarget.js +54 -55
  53. package/dist/esm/hasPrettierConfig.js +33 -35
  54. package/dist/esm/help/prepareHelp.d.ts +2 -0
  55. package/dist/esm/help/prepareHelp.js +26 -0
  56. package/dist/esm/index.d.ts +4 -4
  57. package/dist/esm/index.js +2 -8
  58. package/dist/esm/init/checks.js +28 -32
  59. package/dist/esm/init/detectRepoType.js +12 -15
  60. package/dist/esm/init/initCommand.js +60 -54
  61. package/dist/esm/init/parseJsonRecord.js +9 -11
  62. package/dist/esm/init/scaffold.d.ts +1 -1
  63. package/dist/esm/init/scaffold.js +32 -38
  64. package/dist/esm/init/templates.d.ts +1 -1
  65. package/dist/esm/init/templates.js +16 -22
  66. package/dist/esm/injectReleaseNotesIntoReadme.js +42 -49
  67. package/dist/esm/injectSection.js +17 -27
  68. package/dist/esm/loadConfig.d.ts +1 -1
  69. package/dist/esm/loadConfig.js +206 -225
  70. package/dist/esm/parseCommitMessage.d.ts +1 -1
  71. package/dist/esm/parseCommitMessage.js +72 -76
  72. package/dist/esm/parseRequestedTags.js +6 -9
  73. package/dist/esm/prepareCommand.d.ts +32 -1
  74. package/dist/esm/prepareCommand.js +225 -271
  75. package/dist/esm/previewTagPrefixes.d.ts +1 -1
  76. package/dist/esm/previewTagPrefixes.js +101 -96
  77. package/dist/esm/propagateBumps.d.ts +2 -2
  78. package/dist/esm/propagateBumps.js +48 -50
  79. package/dist/esm/publish.d.ts +2 -2
  80. package/dist/esm/publish.js +22 -28
  81. package/dist/esm/publishCommand.js +75 -86
  82. package/dist/esm/pushCommand.js +33 -40
  83. package/dist/esm/pushRelease.d.ts +1 -1
  84. package/dist/esm/pushRelease.js +21 -24
  85. package/dist/esm/readCurrentVersion.js +13 -17
  86. package/dist/esm/releasePrepare.d.ts +1 -1
  87. package/dist/esm/releasePrepare.js +213 -231
  88. package/dist/esm/releasePrepareMono.d.ts +2 -2
  89. package/dist/esm/releasePrepareMono.js +434 -493
  90. package/dist/esm/releasePrepareProject.d.ts +2 -2
  91. package/dist/esm/releasePrepareProject.js +143 -153
  92. package/dist/esm/renderChangelogMarkdown.d.ts +1 -1
  93. package/dist/esm/renderChangelogMarkdown.js +20 -24
  94. package/dist/esm/renderReleaseNotes.d.ts +1 -1
  95. package/dist/esm/renderReleaseNotes.js +50 -55
  96. package/dist/esm/reportPrepare.d.ts +1 -1
  97. package/dist/esm/reportPrepare.js +230 -231
  98. package/dist/esm/resolveCliffConfigPath.js +18 -23
  99. package/dist/esm/resolveCommandTags.d.ts +1 -1
  100. package/dist/esm/resolveCommandTags.js +47 -44
  101. package/dist/esm/resolveReleaseNotesConfig.d.ts +1 -1
  102. package/dist/esm/resolveReleaseNotesConfig.js +39 -41
  103. package/dist/esm/resolveReleaseTags.d.ts +1 -1
  104. package/dist/esm/resolveReleaseTags.js +39 -40
  105. package/dist/esm/runGitCliff.js +27 -30
  106. package/dist/esm/showTagPrefixesCommand.js +48 -70
  107. package/dist/esm/stripEmojiPrefix.js +2 -5
  108. package/dist/esm/stripScope.js +18 -21
  109. package/dist/esm/sync-labels/generateCommand.d.ts +1 -1
  110. package/dist/esm/sync-labels/generateCommand.js +51 -52
  111. package/dist/esm/sync-labels/initCommand.js +46 -47
  112. package/dist/esm/sync-labels/loadSyncLabelsConfig.d.ts +1 -1
  113. package/dist/esm/sync-labels/loadSyncLabelsConfig.js +46 -52
  114. package/dist/esm/sync-labels/presets.d.ts +1 -1
  115. package/dist/esm/sync-labels/presets.js +40 -43
  116. package/dist/esm/sync-labels/resolveLabels.d.ts +1 -1
  117. package/dist/esm/sync-labels/resolveLabels.js +28 -35
  118. package/dist/esm/sync-labels/syncCommand.js +30 -30
  119. package/dist/esm/sync-labels/templates.d.ts +1 -1
  120. package/dist/esm/sync-labels/templates.js +23 -26
  121. package/dist/esm/sync-labels/types.js +1 -0
  122. package/dist/esm/syncWorkTypes.js +83 -81
  123. package/dist/esm/tagCommand.js +12 -21
  124. package/dist/esm/typeGuards.js +4 -8
  125. package/dist/esm/types.js +66 -60
  126. package/dist/esm/validateConfig.d.ts +1 -1
  127. package/dist/esm/validateConfig.js +109 -115
  128. package/dist/esm/validateOnlyExcludesStrandedDependents.d.ts +2 -2
  129. package/dist/esm/validateOnlyExcludesStrandedDependents.js +97 -91
  130. package/dist/esm/validateOverridesCommand.d.ts +2 -2
  131. package/dist/esm/validateOverridesCommand.js +111 -111
  132. package/dist/esm/workTypesData.js +57 -60
  133. package/dist/esm/workTypesUtils.js +16 -21
  134. package/dist/esm/writeReleaseNotesPreviews.js +55 -57
  135. package/package.json +2 -6
@@ -1,47 +1,40 @@
1
- import { parseArgs, translateParseError } from "@williamthorsen/nmr-core";
1
+ import { parseArgsOrExit, reportError } from '@williamthorsen/nmr-core';
2
2
  import { parseRequestedTags } from "./parseRequestedTags.js";
3
3
  import { pushRelease } from "./pushRelease.js";
4
4
  import { resolveCommandTags } from "./resolveCommandTags.js";
5
5
  const pushFlagSchema = {
6
- dryRun: { long: "--dry-run", type: "boolean" },
7
- tags: { long: "--tags", type: "string" },
8
- tagsOnly: { long: "--tags-only", type: "boolean" }
6
+ dryRun: { long: '--dry-run', type: 'boolean' },
7
+ tags: { long: '--tags', type: 'string' },
8
+ tagsOnly: { long: '--tags-only', type: 'boolean' },
9
9
  };
10
- async function pushCommand(argv) {
11
- let parsed;
12
- try {
13
- parsed = parseArgs(argv, pushFlagSchema);
14
- } catch (error) {
15
- console.error(`Error: ${translateParseError(error)}`);
16
- process.exit(1);
17
- }
18
- const { dryRun, tagsOnly } = parsed.flags;
19
- const requestedTags = parseRequestedTags(parsed.flags.tags);
20
- const resolvedTags = await resolveCommandTags(requestedTags);
21
- if (resolvedTags.length === 0) {
22
- return;
23
- }
24
- const prefix = dryRun ? "[dry-run] Would push" : "Pushing";
25
- if (!tagsOnly) {
26
- console.info(`${prefix} branch and ${resolvedTags.length} tag(s):`);
27
- } else {
28
- console.info(`${prefix} ${resolvedTags.length} tag(s):`);
29
- }
30
- for (const { tag } of resolvedTags) {
31
- console.info(` ${tag}`);
32
- }
33
- try {
34
- const steps = pushRelease(resolvedTags, { dryRun, tagsOnly });
35
- if (dryRun) {
36
- for (const step of steps) {
37
- console.info(`[dry-run] ${step.command.join(" ")}`);
38
- }
10
+ export async function pushCommand(argv) {
11
+ const parsed = parseArgsOrExit(argv, pushFlagSchema);
12
+ const { dryRun, tagsOnly } = parsed.flags;
13
+ const requestedTags = parseRequestedTags(parsed.flags.tags);
14
+ const resolvedTags = await resolveCommandTags(requestedTags);
15
+ if (resolvedTags.length === 0) {
16
+ return;
17
+ }
18
+ const prefix = dryRun ? '[dry-run] Would push' : 'Pushing';
19
+ if (!tagsOnly) {
20
+ console.info(`${prefix} branch and ${resolvedTags.length} tag(s):`);
21
+ }
22
+ else {
23
+ console.info(`${prefix} ${resolvedTags.length} tag(s):`);
24
+ }
25
+ for (const { tag } of resolvedTags) {
26
+ console.info(` ${tag}`);
27
+ }
28
+ try {
29
+ const steps = pushRelease(resolvedTags, { dryRun, tagsOnly });
30
+ if (dryRun) {
31
+ for (const step of steps) {
32
+ console.info(`[dry-run] ${step.command.join(' ')}`);
33
+ }
34
+ }
35
+ }
36
+ catch (error) {
37
+ reportError(error instanceof Error ? error.message : String(error));
38
+ process.exit(1);
39
39
  }
40
- } catch (error) {
41
- console.error(error instanceof Error ? error.message : String(error));
42
- process.exit(1);
43
- }
44
40
  }
45
- export {
46
- pushCommand
47
- };
@@ -1,4 +1,4 @@
1
- import type { ResolvedTag } from './resolveReleaseTags.ts';
1
+ import type { ResolvedTag } from './resolveReleaseTags.js';
2
2
  export interface PushReleaseOptions {
3
3
  dryRun?: boolean;
4
4
  tagsOnly?: boolean;
@@ -1,26 +1,23 @@
1
- import { execFileSync } from "node:child_process";
2
- function pushRelease(resolvedTags, options = {}) {
3
- const { dryRun = false, tagsOnly = false } = options;
4
- const steps = [];
5
- if (!tagsOnly) {
6
- const branch = execFileSync("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
7
- encoding: "utf8",
8
- stdio: ["pipe", "pipe", "pipe"]
9
- }).trim();
10
- const command = ["git", "push", "origin", branch];
11
- steps.push({ type: "branch", ref: branch, command });
12
- }
13
- for (const { tag } of resolvedTags) {
14
- const command = ["git", "push", "--no-follow-tags", "origin", tag];
15
- steps.push({ type: "tag", ref: tag, command });
16
- }
17
- if (!dryRun) {
18
- for (const step of steps) {
19
- execFileSync(step.command[0], step.command.slice(1), { stdio: "inherit" });
1
+ import { execFileSync } from 'node:child_process';
2
+ export function pushRelease(resolvedTags, options = {}) {
3
+ const { dryRun = false, tagsOnly = false } = options;
4
+ const steps = [];
5
+ if (!tagsOnly) {
6
+ const branch = execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
7
+ encoding: 'utf8',
8
+ stdio: ['pipe', 'pipe', 'pipe'],
9
+ }).trim();
10
+ const command = ['git', 'push', 'origin', branch];
11
+ steps.push({ type: 'branch', ref: branch, command });
20
12
  }
21
- }
22
- return steps;
13
+ for (const { tag } of resolvedTags) {
14
+ const command = ['git', 'push', '--no-follow-tags', 'origin', tag];
15
+ steps.push({ type: 'tag', ref: tag, command });
16
+ }
17
+ if (!dryRun) {
18
+ for (const step of steps) {
19
+ execFileSync(step.command[0], step.command.slice(1), { stdio: 'inherit' });
20
+ }
21
+ }
22
+ return steps;
23
23
  }
24
- export {
25
- pushRelease
26
- };
@@ -1,21 +1,17 @@
1
- import { readFileSync } from "node:fs";
1
+ import { readFileSync } from 'node:fs';
2
2
  function hasVersionField(value) {
3
- return typeof value === "object" && value !== null && "version" in value && typeof value.version === "string";
3
+ return typeof value === 'object' && value !== null && 'version' in value && typeof value.version === 'string';
4
4
  }
5
- function readCurrentVersion(filePath) {
6
- try {
7
- const content = readFileSync(filePath, "utf8");
8
- const parsed = JSON.parse(content);
9
- if (hasVersionField(parsed)) {
10
- return parsed.version;
5
+ export function readCurrentVersion(filePath) {
6
+ try {
7
+ const content = readFileSync(filePath, 'utf8');
8
+ const parsed = JSON.parse(content);
9
+ if (hasVersionField(parsed)) {
10
+ return parsed.version;
11
+ }
11
12
  }
12
- } catch (error) {
13
- console.warn(
14
- `Failed to read current version from ${filePath}: ${error instanceof Error ? error.message : String(error)}`
15
- );
16
- }
17
- return void 0;
13
+ catch (error) {
14
+ console.warn(`Failed to read current version from ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
15
+ }
16
+ return undefined;
18
17
  }
19
- export {
20
- readCurrentVersion
21
- };
@@ -1,4 +1,4 @@
1
- import type { PrepareResult, ReleaseConfig, ReleaseType } from './types.ts';
1
+ import type { PrepareResult, ReleaseConfig, ReleaseType } from './types.js';
2
2
  export interface ReleasePrepareOptions {
3
3
  dryRun: boolean;
4
4
  force?: boolean;
@@ -1,17 +1,9 @@
1
- import { execSync } from "node:child_process";
1
+ import { execSync } from 'node:child_process';
2
2
  import { buildChangelogEntries } from "./buildChangelogEntries.js";
3
3
  import { buildEmptyReleaseEntry } from "./buildEmptyReleaseEntry.js";
4
4
  import { bumpAllVersions, setAllVersions } from "./bumpAllVersions.js";
5
- import {
6
- mergeChangelogEntriesWithDisk,
7
- resolveChangelogJsonPath,
8
- upsertChangelogJsonAndReturn
9
- } from "./changelogJsonFile.js";
10
- import {
11
- applyChangelogOverrides,
12
- formatStaleOverrideKeyWarning,
13
- loadOverridesForScopes
14
- } from "./changelogOverrides.js";
5
+ import { mergeChangelogEntriesWithDisk, resolveChangelogJsonPath, upsertChangelogJsonAndReturn, } from "./changelogJsonFile.js";
6
+ import { applyChangelogOverrides, formatStaleOverrideKeyWarning, loadOverridesForScopes, } from "./changelogOverrides.js";
15
7
  import { createPolicyViolationCollector } from "./collectPolicyViolations.js";
16
8
  import { isForwardVersion } from "./compareVersions.js";
17
9
  import { DEFAULT_BREAKING_POLICIES, DEFAULT_VERSION_PATTERNS, DEFAULT_WORK_TYPES } from "./defaults.js";
@@ -24,242 +16,232 @@ import { writeChangelogMarkdown } from "./renderChangelogMarkdown.js";
24
16
  import { deriveSectionOrder } from "./resolveReleaseNotesConfig.js";
25
17
  import { refreshGitCliffCache } from "./runGitCliff.js";
26
18
  import { writeReleaseNotesPreviews } from "./writeReleaseNotesPreviews.js";
27
- function releasePrepare(config, options) {
28
- const { dryRun, bumpOverride, setVersion, withReleaseNotes } = options;
29
- const workTypes = config.workTypes ?? { ...DEFAULT_WORK_TYPES };
30
- const versionPatterns = config.versionPatterns ?? { ...DEFAULT_VERSION_PATTERNS };
31
- const breakingPolicies = config.breakingPolicies ?? DEFAULT_BREAKING_POLICIES;
32
- const overridesResult = loadOverridesForScopes({ project: "." });
33
- if (overridesResult.errors.length > 0) {
34
- throw new Error(`Failed to load changelog overrides:
35
- - ${overridesResult.errors.join("\n - ")}`);
36
- }
37
- const overrides = overridesResult.project;
38
- const { tag, commits } = getCommitsSinceTarget([config.tagPrefix]);
39
- let releaseType;
40
- let parsedCommitCount;
41
- let unparseableCommits;
42
- const collector = createPolicyViolationCollector();
43
- let bump;
44
- if (setVersion !== void 0) {
45
- const primaryPackageFile = config.packageFiles[0];
46
- if (primaryPackageFile === void 0) {
47
- throw new Error("No package files specified");
19
+ export function releasePrepare(config, options) {
20
+ const { dryRun, bumpOverride, setVersion, withReleaseNotes } = options;
21
+ const workTypes = config.workTypes ?? { ...DEFAULT_WORK_TYPES };
22
+ const versionPatterns = config.versionPatterns ?? { ...DEFAULT_VERSION_PATTERNS };
23
+ const breakingPolicies = config.breakingPolicies ?? DEFAULT_BREAKING_POLICIES;
24
+ const overridesResult = loadOverridesForScopes({ project: '.' });
25
+ if (overridesResult.errors.length > 0) {
26
+ throw new Error(`Failed to load changelog overrides:\n - ${overridesResult.errors.join('\n - ')}`);
48
27
  }
49
- const currentVersion = readCurrentVersion(primaryPackageFile);
50
- if (currentVersion === void 0) {
51
- throw new Error(`Cannot validate --set-version: failed to read current version from ${primaryPackageFile}`);
28
+ const overrides = overridesResult.project;
29
+ const { tag, commits } = getCommitsSinceTarget([config.tagPrefix]);
30
+ let releaseType;
31
+ let parsedCommitCount;
32
+ let unparseableCommits;
33
+ const collector = createPolicyViolationCollector();
34
+ let bump;
35
+ if (setVersion !== undefined) {
36
+ const primaryPackageFile = config.packageFiles[0];
37
+ if (primaryPackageFile === undefined) {
38
+ throw new Error('No package files specified');
39
+ }
40
+ const currentVersion = readCurrentVersion(primaryPackageFile);
41
+ if (currentVersion === undefined) {
42
+ throw new Error(`Cannot validate --set-version: failed to read current version from ${primaryPackageFile}`);
43
+ }
44
+ if (!isForwardVersion(currentVersion, setVersion)) {
45
+ throw new Error(`--set-version ${setVersion} is not greater than current version ${currentVersion}`);
46
+ }
47
+ refreshGitCliffCache();
48
+ bump = setAllVersions(config.packageFiles, setVersion, dryRun);
52
49
  }
53
- if (!isForwardVersion(currentVersion, setVersion)) {
54
- throw new Error(`--set-version ${setVersion} is not greater than current version ${currentVersion}`);
50
+ else {
51
+ if (bumpOverride === undefined) {
52
+ const determination = determineBumpFromCommits(commits, workTypes, versionPatterns, config.scopeAliases, {
53
+ breakingPolicies,
54
+ onPolicyViolation: collector.onPolicyViolation,
55
+ });
56
+ parsedCommitCount = determination.parsedCommitCount;
57
+ unparseableCommits = determination.unparseableCommits;
58
+ releaseType = determination.releaseType;
59
+ }
60
+ else {
61
+ releaseType = bumpOverride;
62
+ }
63
+ if (releaseType === undefined) {
64
+ const skipped = buildSkippedSinglePackage({
65
+ commitCount: commits.length,
66
+ previousTag: tag,
67
+ parsedCommitCount,
68
+ unparseableCommits,
69
+ policyViolations: collector.violations.length > 0 ? collector.violations : undefined,
70
+ });
71
+ return {
72
+ workspaces: [skipped],
73
+ tags: [],
74
+ dryRun,
75
+ };
76
+ }
77
+ refreshGitCliffCache();
78
+ bump = bumpAllVersions(config.packageFiles, releaseType, dryRun);
55
79
  }
56
- refreshGitCliffCache();
57
- bump = setAllVersions(config.packageFiles, setVersion, dryRun);
58
- } else {
59
- if (bumpOverride === void 0) {
60
- const determination = determineBumpFromCommits(commits, workTypes, versionPatterns, config.scopeAliases, {
61
- breakingPolicies,
62
- onPolicyViolation: collector.onPolicyViolation
63
- });
64
- parsedCommitCount = determination.parsedCommitCount;
65
- unparseableCommits = determination.unparseableCommits;
66
- releaseType = determination.releaseType;
67
- } else {
68
- releaseType = bumpOverride;
80
+ const newTag = `${config.tagPrefix}${bump.newVersion}`;
81
+ const overrideWarnings = [];
82
+ const { changelogFiles, changelogJsonFiles } = writeSinglePackageChangelogs({
83
+ config,
84
+ commits,
85
+ newTag,
86
+ newVersion: bump.newVersion,
87
+ dryRun,
88
+ overrides,
89
+ overrideWarnings,
90
+ });
91
+ maybeWriteSinglePackagePreviews(withReleaseNotes === true, config, newTag, changelogJsonFiles[0], dryRun);
92
+ const formatCommandStr = config.formatCommand ?? (hasPrettierConfig() ? 'npx prettier --write' : undefined);
93
+ let formatCommand;
94
+ if (formatCommandStr !== undefined) {
95
+ const modifiedFiles = [
96
+ ...config.packageFiles,
97
+ ...config.changelogPaths.map((p) => `${p}/CHANGELOG.md`),
98
+ ...changelogJsonFiles,
99
+ ];
100
+ const fullCommand = `${formatCommandStr} ${modifiedFiles.join(' ')}`;
101
+ if (dryRun) {
102
+ formatCommand = { command: fullCommand, executed: false, files: modifiedFiles };
103
+ }
104
+ else {
105
+ try {
106
+ execSync(fullCommand, { stdio: 'inherit' });
107
+ }
108
+ catch (error) {
109
+ const baseMessage = error instanceof Error ? error.message : String(error);
110
+ throw new Error(`format stage: ${baseMessage} (command: '${fullCommand}')`, { cause: error });
111
+ }
112
+ formatCommand = { command: fullCommand, executed: true, files: modifiedFiles };
113
+ }
69
114
  }
70
- if (releaseType === void 0) {
71
- const skipped = buildSkippedSinglePackage({
72
- commitCount: commits.length,
115
+ const released = buildReleasedSinglePackage({
116
+ commits,
117
+ bump,
118
+ newTag,
119
+ changelogFiles,
73
120
  previousTag: tag,
74
121
  parsedCommitCount,
122
+ releaseType,
75
123
  unparseableCommits,
76
- policyViolations: collector.violations.length > 0 ? collector.violations : void 0
77
- });
78
- return {
79
- workspaces: [skipped],
80
- tags: [],
81
- dryRun
82
- };
83
- }
84
- refreshGitCliffCache();
85
- bump = bumpAllVersions(config.packageFiles, releaseType, dryRun);
86
- }
87
- const newTag = `${config.tagPrefix}${bump.newVersion}`;
88
- const overrideWarnings = [];
89
- const { changelogFiles, changelogJsonFiles } = writeSinglePackageChangelogs({
90
- config,
91
- commits,
92
- newTag,
93
- newVersion: bump.newVersion,
94
- dryRun,
95
- overrides,
96
- overrideWarnings
97
- });
98
- maybeWriteSinglePackagePreviews(withReleaseNotes === true, config, newTag, changelogJsonFiles[0], dryRun);
99
- const formatCommandStr = config.formatCommand ?? (hasPrettierConfig() ? "npx prettier --write" : void 0);
100
- let formatCommand;
101
- if (formatCommandStr !== void 0) {
102
- const modifiedFiles = [
103
- ...config.packageFiles,
104
- ...config.changelogPaths.map((p) => `${p}/CHANGELOG.md`),
105
- ...changelogJsonFiles
106
- ];
107
- const fullCommand = `${formatCommandStr} ${modifiedFiles.join(" ")}`;
108
- if (dryRun) {
109
- formatCommand = { command: fullCommand, executed: false, files: modifiedFiles };
110
- } else {
111
- try {
112
- execSync(fullCommand, { stdio: "inherit" });
113
- } catch (error) {
114
- const baseMessage = error instanceof Error ? error.message : String(error);
115
- throw new Error(`format stage: ${baseMessage} (command: '${fullCommand}')`, { cause: error });
116
- }
117
- formatCommand = { command: fullCommand, executed: true, files: modifiedFiles };
124
+ policyViolations: collector.violations.length > 0 ? collector.violations : undefined,
125
+ setVersion,
126
+ });
127
+ const result = {
128
+ workspaces: [released],
129
+ tags: [newTag],
130
+ formatCommand,
131
+ dryRun,
132
+ };
133
+ if (overrideWarnings.length > 0) {
134
+ result.warnings = overrideWarnings;
118
135
  }
119
- }
120
- const released = buildReleasedSinglePackage({
121
- commits,
122
- bump,
123
- newTag,
124
- changelogFiles,
125
- previousTag: tag,
126
- parsedCommitCount,
127
- releaseType,
128
- unparseableCommits,
129
- policyViolations: collector.violations.length > 0 ? collector.violations : void 0,
130
- setVersion
131
- });
132
- const result = {
133
- workspaces: [released],
134
- tags: [newTag],
135
- formatCommand,
136
- dryRun
137
- };
138
- if (overrideWarnings.length > 0) {
139
- result.warnings = overrideWarnings;
140
- }
141
- return result;
136
+ return result;
142
137
  }
143
138
  function buildSkippedSinglePackage(args) {
144
- const skipped = {
145
- status: "skipped",
146
- commitCount: args.commitCount,
147
- skipReason: "No release-worthy changes found. Skipping."
148
- };
149
- if (args.previousTag !== void 0) {
150
- skipped.previousTag = args.previousTag;
151
- }
152
- if (args.parsedCommitCount !== void 0) {
153
- skipped.parsedCommitCount = args.parsedCommitCount;
154
- }
155
- if (args.unparseableCommits !== void 0) {
156
- skipped.unparseableCommits = args.unparseableCommits;
157
- }
158
- if (args.policyViolations !== void 0) {
159
- skipped.policyViolations = args.policyViolations;
160
- }
161
- return skipped;
139
+ const skipped = {
140
+ status: 'skipped',
141
+ commitCount: args.commitCount,
142
+ skipReason: 'No release-worthy changes found. Skipping.',
143
+ };
144
+ if (args.previousTag !== undefined) {
145
+ skipped.previousTag = args.previousTag;
146
+ }
147
+ if (args.parsedCommitCount !== undefined) {
148
+ skipped.parsedCommitCount = args.parsedCommitCount;
149
+ }
150
+ if (args.unparseableCommits !== undefined) {
151
+ skipped.unparseableCommits = args.unparseableCommits;
152
+ }
153
+ if (args.policyViolations !== undefined) {
154
+ skipped.policyViolations = args.policyViolations;
155
+ }
156
+ return skipped;
162
157
  }
163
158
  function buildReleasedSinglePackage(args) {
164
- const {
165
- commits,
166
- bump,
167
- newTag,
168
- changelogFiles,
169
- previousTag,
170
- parsedCommitCount,
171
- releaseType,
172
- unparseableCommits,
173
- policyViolations,
174
- setVersion
175
- } = args;
176
- const released = {
177
- status: "released",
178
- commitCount: commits.length,
179
- currentVersion: bump.currentVersion,
180
- newVersion: bump.newVersion,
181
- tag: newTag,
182
- bumpedFiles: bump.files,
183
- changelogFiles,
184
- commits
185
- };
186
- if (previousTag !== void 0) {
187
- released.previousTag = previousTag;
188
- }
189
- if (parsedCommitCount !== void 0) {
190
- released.parsedCommitCount = parsedCommitCount;
191
- }
192
- if (releaseType !== void 0) {
193
- released.releaseType = releaseType;
194
- }
195
- if (unparseableCommits !== void 0) {
196
- released.unparseableCommits = unparseableCommits;
197
- }
198
- if (policyViolations !== void 0) {
199
- released.policyViolations = policyViolations;
200
- }
201
- if (setVersion !== void 0) {
202
- released.setVersion = setVersion;
203
- }
204
- return released;
159
+ const { commits, bump, newTag, changelogFiles, previousTag, parsedCommitCount, releaseType, unparseableCommits, policyViolations, setVersion, } = args;
160
+ const released = {
161
+ status: 'released',
162
+ commitCount: commits.length,
163
+ currentVersion: bump.currentVersion,
164
+ newVersion: bump.newVersion,
165
+ tag: newTag,
166
+ bumpedFiles: bump.files,
167
+ changelogFiles,
168
+ commits,
169
+ };
170
+ if (previousTag !== undefined) {
171
+ released.previousTag = previousTag;
172
+ }
173
+ if (parsedCommitCount !== undefined) {
174
+ released.parsedCommitCount = parsedCommitCount;
175
+ }
176
+ if (releaseType !== undefined) {
177
+ released.releaseType = releaseType;
178
+ }
179
+ if (unparseableCommits !== undefined) {
180
+ released.unparseableCommits = unparseableCommits;
181
+ }
182
+ if (policyViolations !== undefined) {
183
+ released.policyViolations = policyViolations;
184
+ }
185
+ if (setVersion !== undefined) {
186
+ released.setVersion = setVersion;
187
+ }
188
+ return released;
205
189
  }
206
190
  function writeSinglePackageChangelogs(args) {
207
- const { config, commits, newTag, newVersion, dryRun, overrides, overrideWarnings } = args;
208
- const isEmptyRange = commits.length === 0;
209
- const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
210
- const baseEntries = isEmptyRange ? [buildEmptyReleaseEntry(newVersion, today)] : buildChangelogEntries(config, newTag);
211
- const applied = applyChangelogOverrides(baseEntries, overrides);
212
- if (applied.errors.length > 0) {
213
- throw new Error(`Changelog override application failed:
214
- - ${applied.errors.join("\n - ")}`);
215
- }
216
- overrideWarnings.push(...applied.warnings);
217
- const matchedSet = new Set(applied.matchedKeys);
218
- for (const overrideKey of overrides.keys()) {
219
- if (!matchedSet.has(overrideKey)) {
220
- overrideWarnings.push(formatStaleOverrideKeyWarning(overrideKey));
191
+ const { config, commits, newTag, newVersion, dryRun, overrides, overrideWarnings } = args;
192
+ const isEmptyRange = commits.length === 0;
193
+ const today = new Date().toISOString().slice(0, 10);
194
+ const baseEntries = isEmptyRange
195
+ ? [buildEmptyReleaseEntry(newVersion, today)]
196
+ : buildChangelogEntries(config, newTag);
197
+ const applied = applyChangelogOverrides(baseEntries, overrides);
198
+ if (applied.errors.length > 0) {
199
+ throw new Error(`Changelog override application failed:\n - ${applied.errors.join('\n - ')}`);
221
200
  }
222
- }
223
- const sectionOrder = deriveSectionOrder(resolveWorkTypes(config.workTypes));
224
- const changelogFiles = [];
225
- const changelogJsonFiles = [];
226
- for (const changelogPath of config.changelogPaths) {
227
- const jsonPath = resolveChangelogJsonPath(config, changelogPath);
228
- const shouldWriteJson = config.changelogJson.enabled && !dryRun;
229
- const mergedEntries = shouldWriteJson ? upsertChangelogJsonAndReturn(jsonPath, applied.entries) : mergeChangelogEntriesWithDisk(jsonPath, applied.entries);
230
- if (config.changelogJson.enabled) {
231
- changelogJsonFiles.push(jsonPath);
201
+ overrideWarnings.push(...applied.warnings);
202
+ const matchedSet = new Set(applied.matchedKeys);
203
+ for (const overrideKey of overrides.keys()) {
204
+ if (!matchedSet.has(overrideKey)) {
205
+ overrideWarnings.push(formatStaleOverrideKeyWarning(overrideKey));
206
+ }
232
207
  }
233
- changelogFiles.push(
234
- writeChangelogMarkdown({
235
- changelogPath,
236
- entries: mergedEntries,
237
- sectionOrder,
238
- dryRun
239
- })
240
- );
241
- }
242
- return { changelogFiles, changelogJsonFiles };
208
+ const sectionOrder = deriveSectionOrder(resolveWorkTypes(config.workTypes));
209
+ const changelogFiles = [];
210
+ const changelogJsonFiles = [];
211
+ for (const changelogPath of config.changelogPaths) {
212
+ const jsonPath = resolveChangelogJsonPath(config, changelogPath);
213
+ const shouldWriteJson = config.changelogJson.enabled && !dryRun;
214
+ const mergedEntries = shouldWriteJson
215
+ ? upsertChangelogJsonAndReturn(jsonPath, applied.entries)
216
+ : mergeChangelogEntriesWithDisk(jsonPath, applied.entries);
217
+ if (config.changelogJson.enabled) {
218
+ changelogJsonFiles.push(jsonPath);
219
+ }
220
+ changelogFiles.push(writeChangelogMarkdown({
221
+ changelogPath,
222
+ entries: mergedEntries,
223
+ sectionOrder,
224
+ dryRun,
225
+ }));
226
+ }
227
+ return { changelogFiles, changelogJsonFiles };
243
228
  }
244
229
  function maybeWriteSinglePackagePreviews(withReleaseNotes, config, newTag, changelogJsonPath, dryRun) {
245
- if (!withReleaseNotes) {
246
- return;
247
- }
248
- if (!config.changelogJson.enabled) {
249
- console.warn("Warning: --with-release-notes requires changelogJson.enabled; skipping preview generation");
250
- return;
251
- }
252
- if (changelogJsonPath === void 0) {
253
- return;
254
- }
255
- writeReleaseNotesPreviews({
256
- workspacePath: process.cwd(),
257
- tag: newTag,
258
- changelogJsonPath,
259
- sectionOrder: deriveSectionOrder(resolveWorkTypes(config.workTypes)),
260
- dryRun
261
- });
230
+ if (!withReleaseNotes) {
231
+ return;
232
+ }
233
+ if (!config.changelogJson.enabled) {
234
+ console.warn('Warning: --with-release-notes requires changelogJson.enabled; skipping preview generation');
235
+ return;
236
+ }
237
+ if (changelogJsonPath === undefined) {
238
+ return;
239
+ }
240
+ writeReleaseNotesPreviews({
241
+ workspacePath: process.cwd(),
242
+ tag: newTag,
243
+ changelogJsonPath,
244
+ sectionOrder: deriveSectionOrder(resolveWorkTypes(config.workTypes)),
245
+ dryRun,
246
+ });
262
247
  }
263
- export {
264
- releasePrepare
265
- };