@williamthorsen/release-kit 4.8.0 → 5.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 (82) hide show
  1. package/CHANGELOG.md +74 -4
  2. package/README.md +310 -40
  3. package/cliff.toml.template +2 -1
  4. package/dist/esm/.cache +1 -1
  5. package/dist/esm/bin/release-kit.js +44 -13
  6. package/dist/esm/buildDependencyGraph.d.ts +3 -3
  7. package/dist/esm/buildDependencyGraph.js +10 -10
  8. package/dist/esm/buildReleaseSummary.js +4 -4
  9. package/dist/esm/bumpAllVersions.d.ts +1 -0
  10. package/dist/esm/bumpAllVersions.js +16 -2
  11. package/dist/esm/bumpVersion.js +3 -0
  12. package/dist/esm/commitCommand.js +1 -1
  13. package/dist/esm/compareVersions.d.ts +1 -0
  14. package/dist/esm/compareVersions.js +27 -0
  15. package/dist/esm/createGithubRelease.d.ts +6 -2
  16. package/dist/esm/createGithubRelease.js +17 -17
  17. package/dist/esm/createGithubReleaseCommand.d.ts +1 -0
  18. package/dist/esm/createGithubReleaseCommand.js +41 -0
  19. package/dist/esm/defaults.js +5 -3
  20. package/dist/esm/deriveWorkspaceConfig.d.ts +2 -0
  21. package/dist/esm/deriveWorkspaceConfig.js +37 -0
  22. package/dist/esm/detectUndeclaredTagPrefixes.d.ts +7 -0
  23. package/dist/esm/detectUndeclaredTagPrefixes.js +46 -0
  24. package/dist/esm/generateChangelogJson.js +37 -1
  25. package/dist/esm/generateChangelogs.d.ts +1 -1
  26. package/dist/esm/generateChangelogs.js +14 -3
  27. package/dist/esm/getCommitsSinceTarget.d.ts +1 -1
  28. package/dist/esm/getCommitsSinceTarget.js +8 -4
  29. package/dist/esm/index.d.ts +7 -3
  30. package/dist/esm/index.js +10 -3
  31. package/dist/esm/init/initCommand.js +1 -1
  32. package/dist/esm/init/scaffold.d.ts +1 -1
  33. package/dist/esm/init/scaffold.js +8 -5
  34. package/dist/esm/init/templates.d.ts +1 -0
  35. package/dist/esm/init/templates.js +33 -3
  36. package/dist/esm/injectReleaseNotesIntoReadme.d.ts +6 -1
  37. package/dist/esm/injectReleaseNotesIntoReadme.js +20 -7
  38. package/dist/esm/loadConfig.d.ts +2 -1
  39. package/dist/esm/loadConfig.js +65 -12
  40. package/dist/esm/parseRequestedTags.d.ts +1 -0
  41. package/dist/esm/parseRequestedTags.js +10 -0
  42. package/dist/esm/prepareCommand.d.ts +3 -1
  43. package/dist/esm/prepareCommand.js +74 -26
  44. package/dist/esm/previewTagPrefixes.d.ts +30 -0
  45. package/dist/esm/previewTagPrefixes.js +120 -0
  46. package/dist/esm/propagateBumps.d.ts +1 -0
  47. package/dist/esm/propagateBumps.js +1 -1
  48. package/dist/esm/publishCommand.js +8 -13
  49. package/dist/esm/pushCommand.js +5 -4
  50. package/dist/esm/readCurrentVersion.d.ts +1 -0
  51. package/dist/esm/readCurrentVersion.js +21 -0
  52. package/dist/esm/releasePrepare.d.ts +2 -0
  53. package/dist/esm/releasePrepare.js +72 -30
  54. package/dist/esm/releasePrepareMono.js +235 -112
  55. package/dist/esm/renderReleaseNotes.d.ts +1 -0
  56. package/dist/esm/renderReleaseNotes.js +29 -2
  57. package/dist/esm/reportPrepare.js +100 -73
  58. package/dist/esm/resolveCliffConfigPath.js +1 -1
  59. package/dist/esm/resolveCommandTags.d.ts +1 -1
  60. package/dist/esm/resolveCommandTags.js +17 -13
  61. package/dist/esm/resolveReleaseNotesConfig.d.ts +8 -1
  62. package/dist/esm/resolveReleaseNotesConfig.js +17 -7
  63. package/dist/esm/resolveReleaseTags.d.ts +2 -1
  64. package/dist/esm/resolveReleaseTags.js +19 -14
  65. package/dist/esm/showTagPrefixesCommand.d.ts +1 -0
  66. package/dist/esm/showTagPrefixesCommand.js +84 -0
  67. package/dist/esm/sync-labels/initCommand.js +1 -1
  68. package/dist/esm/sync-labels/presets.js +1 -1
  69. package/dist/esm/tagCommand.js +1 -1
  70. package/dist/esm/types.d.ts +22 -7
  71. package/dist/esm/validateConfig.js +179 -36
  72. package/dist/esm/version.d.ts +1 -1
  73. package/dist/esm/version.js +1 -1
  74. package/dist/esm/writeReleaseNotesPreviews.d.ts +18 -0
  75. package/dist/esm/writeReleaseNotesPreviews.js +65 -0
  76. package/package.json +2 -2
  77. package/dist/esm/component.d.ts +0 -2
  78. package/dist/esm/component.js +0 -14
  79. package/dist/esm/findPackageRoot.d.ts +0 -1
  80. package/dist/esm/findPackageRoot.js +0 -17
  81. package/dist/esm/githubReleaseCommand.d.ts +0 -1
  82. package/dist/esm/githubReleaseCommand.js +0 -35
@@ -0,0 +1,30 @@
1
+ import type { UndeclaredTagPrefix } from './detectUndeclaredTagPrefixes.ts';
2
+ export interface TagPrefixPreviewRow {
3
+ workspacePath: string;
4
+ dir: string;
5
+ derivedPrefix: string | null;
6
+ derivationError: string | null;
7
+ derivedTagCount: number;
8
+ legacyEntries: LegacyTagPrefixEntry[];
9
+ }
10
+ export interface LegacyTagPrefixEntry {
11
+ prefix: string;
12
+ tagCount: number;
13
+ }
14
+ export interface RetiredPackagePreviewEntry {
15
+ name: string;
16
+ tagPrefix: string;
17
+ successor?: string;
18
+ tagCount: number;
19
+ }
20
+ export interface TagPrefixCollision {
21
+ tagPrefix: string;
22
+ workspacePaths: string[];
23
+ }
24
+ export interface TagPrefixPreview {
25
+ workspaces: TagPrefixPreviewRow[];
26
+ collisions: TagPrefixCollision[];
27
+ undeclaredCandidates: UndeclaredTagPrefix[];
28
+ retiredPackages: RetiredPackagePreviewEntry[];
29
+ }
30
+ export declare function previewTagPrefixes(): Promise<TagPrefixPreview>;
@@ -0,0 +1,120 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { basename } from "node:path";
3
+ import { deriveWorkspaceConfig } from "./deriveWorkspaceConfig.js";
4
+ import { detectUndeclaredTagPrefixes } from "./detectUndeclaredTagPrefixes.js";
5
+ import { discoverWorkspaces } from "./discoverWorkspaces.js";
6
+ import { loadConfig } from "./loadConfig.js";
7
+ import { validateConfig } from "./validateConfig.js";
8
+ async function previewTagPrefixes() {
9
+ const workspacePaths = await discoverWorkspaces() ?? [];
10
+ const userConfig = await loadUserConfig();
11
+ const overridesByDir = buildOverrideMap(userConfig);
12
+ const workspaces = [];
13
+ for (const workspacePath of workspacePaths) {
14
+ workspaces.push(buildPreviewRow(workspacePath, overridesByDir));
15
+ }
16
+ const retiredPackages = buildRetiredPreviewEntries(userConfig?.retiredPackages ?? []);
17
+ const collisions = detectCollisions(workspaces);
18
+ const knownPrefixes = collectKnownPrefixes(workspaces, retiredPackages);
19
+ const undeclaredCandidates = detectUndeclaredTagPrefixes(knownPrefixes);
20
+ return { workspaces, collisions, undeclaredCandidates, retiredPackages };
21
+ }
22
+ async function loadUserConfig() {
23
+ let raw;
24
+ try {
25
+ raw = await loadConfig();
26
+ } catch {
27
+ return void 0;
28
+ }
29
+ if (raw === void 0) return void 0;
30
+ const { config, errors } = validateConfig(raw);
31
+ return errors.length === 0 ? config : void 0;
32
+ }
33
+ function buildOverrideMap(userConfig) {
34
+ const map = /* @__PURE__ */ new Map();
35
+ if (userConfig?.workspaces === void 0) return map;
36
+ for (const entry of userConfig.workspaces) {
37
+ if (entry.legacyIdentities !== void 0) {
38
+ map.set(entry.dir, entry.legacyIdentities);
39
+ }
40
+ }
41
+ return map;
42
+ }
43
+ function buildPreviewRow(workspacePath, overridesByDir) {
44
+ const dir = basename(workspacePath);
45
+ let derivedPrefix = null;
46
+ let derivationError = null;
47
+ try {
48
+ derivedPrefix = deriveWorkspaceConfig(workspacePath).tagPrefix;
49
+ } catch (error) {
50
+ derivationError = error instanceof Error ? error.message : String(error);
51
+ }
52
+ const derivedTagCount = derivedPrefix === null ? 0 : countTagsMatching(derivedPrefix);
53
+ const declaredIdentities = overridesByDir.get(dir) ?? [];
54
+ const legacyEntries = declaredIdentities.map((identity) => ({
55
+ prefix: identity.tagPrefix,
56
+ tagCount: countTagsMatching(identity.tagPrefix)
57
+ }));
58
+ return {
59
+ workspacePath,
60
+ dir,
61
+ derivedPrefix,
62
+ derivationError,
63
+ derivedTagCount,
64
+ legacyEntries
65
+ };
66
+ }
67
+ function countTagsMatching(prefix) {
68
+ try {
69
+ const output = execFileSync("git", ["tag", "--list", `${prefix}*`], {
70
+ encoding: "utf8",
71
+ stdio: ["pipe", "pipe", "pipe"]
72
+ });
73
+ return output.split("\n").filter((line) => line.trim() !== "").length;
74
+ } catch {
75
+ return 0;
76
+ }
77
+ }
78
+ function detectCollisions(rows) {
79
+ const pathsByPrefix = /* @__PURE__ */ new Map();
80
+ for (const row of rows) {
81
+ if (row.derivedPrefix === null) continue;
82
+ const existing = pathsByPrefix.get(row.derivedPrefix);
83
+ if (existing === void 0) {
84
+ pathsByPrefix.set(row.derivedPrefix, [row.workspacePath]);
85
+ } else {
86
+ existing.push(row.workspacePath);
87
+ }
88
+ }
89
+ const collisions = [];
90
+ for (const [tagPrefix, workspacePaths] of pathsByPrefix) {
91
+ if (workspacePaths.length > 1) {
92
+ collisions.push({ tagPrefix, workspacePaths });
93
+ }
94
+ }
95
+ return collisions;
96
+ }
97
+ function collectKnownPrefixes(rows, retiredPackages) {
98
+ const known = /* @__PURE__ */ new Set();
99
+ for (const row of rows) {
100
+ if (row.derivedPrefix !== null) known.add(row.derivedPrefix);
101
+ for (const entry of row.legacyEntries) {
102
+ known.add(entry.prefix);
103
+ }
104
+ }
105
+ for (const retired of retiredPackages) {
106
+ known.add(retired.tagPrefix);
107
+ }
108
+ return [...known];
109
+ }
110
+ function buildRetiredPreviewEntries(retiredPackages) {
111
+ return retiredPackages.map((retired) => ({
112
+ name: retired.name,
113
+ tagPrefix: retired.tagPrefix,
114
+ tagCount: countTagsMatching(retired.tagPrefix),
115
+ ...retired.successor !== void 0 ? { successor: retired.successor } : {}
116
+ }));
117
+ }
118
+ export {
119
+ previewTagPrefixes
120
+ };
@@ -3,6 +3,7 @@ import type { PropagationSource, ReleaseType } from './types.ts';
3
3
  export interface ReleaseEntry {
4
4
  releaseType: ReleaseType;
5
5
  propagatedFrom?: PropagationSource[];
6
+ newVersionOverride?: string;
6
7
  }
7
8
  export type CurrentVersions = Map<string, string>;
8
9
  export declare function propagateBumps(directBumps: Map<string, ReleaseEntry>, graph: DependencyGraph, currentVersions: CurrentVersions): Map<string, ReleaseEntry>;
@@ -24,7 +24,7 @@ function propagateBumps(directBumps, graph, currentVersions) {
24
24
  if (currentVersion === void 0 || entry === void 0) {
25
25
  continue;
26
26
  }
27
- const newVersion = bumpVersion(currentVersion, entry.releaseType);
27
+ const newVersion = entry.newVersionOverride ?? bumpVersion(currentVersion, entry.releaseType);
28
28
  const dependents = graph.dependentsOf.get(packageName);
29
29
  if (dependents === void 0) {
30
30
  continue;
@@ -1,9 +1,9 @@
1
1
  import { writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
- import { parseArgs, translateParseError } from "@williamthorsen/node-monorepo-core";
4
- import { createGithubReleases } from "./createGithubRelease.js";
3
+ import { parseArgs, translateParseError } from "@williamthorsen/nmr-core";
5
4
  import { detectPackageManager } from "./detectPackageManager.js";
6
5
  import { injectReleaseNotesIntoReadme, resolveReadmePath } from "./injectReleaseNotesIntoReadme.js";
6
+ import { parseRequestedTags } from "./parseRequestedTags.js";
7
7
  import { publishPackage } from "./publish.js";
8
8
  import { resolveCommandTags } from "./resolveCommandTags.js";
9
9
  import { resolveReleaseNotesConfig } from "./resolveReleaseNotesConfig.js";
@@ -11,7 +11,7 @@ const publishFlagSchema = {
11
11
  dryRun: { long: "--dry-run", type: "boolean" },
12
12
  noGitChecks: { long: "--no-git-checks", type: "boolean" },
13
13
  provenance: { long: "--provenance", type: "boolean" },
14
- only: { long: "--only", type: "string" }
14
+ tags: { long: "--tags", type: "string" }
15
15
  };
16
16
  async function publishCommand(argv) {
17
17
  let parsed;
@@ -22,13 +22,13 @@ async function publishCommand(argv) {
22
22
  process.exit(1);
23
23
  }
24
24
  const { dryRun, noGitChecks, provenance } = parsed.flags;
25
- const only = parsed.flags.only?.split(",");
26
- const resolvedTags = await resolveCommandTags(only);
25
+ const requestedTags = parseRequestedTags(parsed.flags.tags);
26
+ const resolvedTags = await resolveCommandTags(requestedTags);
27
27
  if (resolvedTags.length === 0) {
28
28
  return;
29
29
  }
30
30
  const packageManager = detectPackageManager();
31
- const { releaseNotes, changelogJsonOutputPath } = await resolveReleaseNotesConfig();
31
+ const { releaseNotes, changelogJsonOutputPath, sectionOrder } = await resolveReleaseNotesConfig();
32
32
  const shouldInject = releaseNotes.shouldInjectIntoReadme;
33
33
  console.info(dryRun ? "[dry-run] Would publish:" : "Publishing:");
34
34
  for (const { tag, workspacePath } of resolvedTags) {
@@ -45,7 +45,8 @@ async function publishCommand(argv) {
45
45
  originalReadme = injectReleaseNotesIntoReadme(
46
46
  readmePath,
47
47
  join(resolvedTag.workspacePath, changelogJsonOutputPath),
48
- resolvedTag.tag
48
+ resolvedTag.tag,
49
+ sectionOrder
49
50
  );
50
51
  }
51
52
  }
@@ -68,12 +69,6 @@ async function publishCommand(argv) {
68
69
  console.error(error instanceof Error ? error.message : String(error));
69
70
  process.exit(1);
70
71
  }
71
- try {
72
- createGithubReleases(resolvedTags, releaseNotes, changelogJsonOutputPath, dryRun);
73
- } catch (error) {
74
- console.error(`Error creating GitHub Releases: ${error instanceof Error ? error.message : String(error)}`);
75
- process.exit(1);
76
- }
77
72
  }
78
73
  export {
79
74
  publishCommand
@@ -1,9 +1,10 @@
1
- import { parseArgs, translateParseError } from "@williamthorsen/node-monorepo-core";
1
+ import { parseArgs, translateParseError } from "@williamthorsen/nmr-core";
2
+ import { parseRequestedTags } from "./parseRequestedTags.js";
2
3
  import { pushRelease } from "./pushRelease.js";
3
4
  import { resolveCommandTags } from "./resolveCommandTags.js";
4
5
  const pushFlagSchema = {
5
6
  dryRun: { long: "--dry-run", type: "boolean" },
6
- only: { long: "--only", type: "string" },
7
+ tags: { long: "--tags", type: "string" },
7
8
  tagsOnly: { long: "--tags-only", type: "boolean" }
8
9
  };
9
10
  async function pushCommand(argv) {
@@ -15,8 +16,8 @@ async function pushCommand(argv) {
15
16
  process.exit(1);
16
17
  }
17
18
  const { dryRun, tagsOnly } = parsed.flags;
18
- const only = parsed.flags.only?.split(",");
19
- const resolvedTags = await resolveCommandTags(only);
19
+ const requestedTags = parseRequestedTags(parsed.flags.tags);
20
+ const resolvedTags = await resolveCommandTags(requestedTags);
20
21
  if (resolvedTags.length === 0) {
21
22
  return;
22
23
  }
@@ -0,0 +1 @@
1
+ export declare function readCurrentVersion(filePath: string): string | undefined;
@@ -0,0 +1,21 @@
1
+ import { readFileSync } from "node:fs";
2
+ function hasVersionField(value) {
3
+ return typeof value === "object" && value !== null && "version" in value && typeof value.version === "string";
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;
11
+ }
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;
18
+ }
19
+ export {
20
+ readCurrentVersion
21
+ };
@@ -3,5 +3,7 @@ export interface ReleasePrepareOptions {
3
3
  dryRun: boolean;
4
4
  force?: boolean;
5
5
  bumpOverride?: ReleaseType;
6
+ setVersion?: string;
7
+ withReleaseNotes?: boolean;
6
8
  }
7
9
  export declare function releasePrepare(config: ReleaseConfig, options: ReleasePrepareOptions): PrepareResult;
@@ -1,46 +1,67 @@
1
1
  import { execSync } from "node:child_process";
2
- import { bumpAllVersions } from "./bumpAllVersions.js";
2
+ import { bumpAllVersions, setAllVersions } from "./bumpAllVersions.js";
3
+ import { isForwardVersion } from "./compareVersions.js";
3
4
  import { DEFAULT_VERSION_PATTERNS, DEFAULT_WORK_TYPES } from "./defaults.js";
4
5
  import { determineBumpFromCommits } from "./determineBumpFromCommits.js";
5
6
  import { generateChangelogJson } from "./generateChangelogJson.js";
6
7
  import { generateChangelogs } from "./generateChangelogs.js";
7
8
  import { getCommitsSinceTarget } from "./getCommitsSinceTarget.js";
8
9
  import { hasPrettierConfig } from "./hasPrettierConfig.js";
10
+ import { resolveWorkTypes } from "./loadConfig.js";
11
+ import { readCurrentVersion } from "./readCurrentVersion.js";
12
+ import { deriveSectionOrder } from "./resolveReleaseNotesConfig.js";
13
+ import { writeReleaseNotesPreviews } from "./writeReleaseNotesPreviews.js";
9
14
  function releasePrepare(config, options) {
10
- const { dryRun, bumpOverride } = options;
15
+ const { dryRun, bumpOverride, setVersion, withReleaseNotes } = options;
11
16
  const workTypes = config.workTypes ?? { ...DEFAULT_WORK_TYPES };
12
17
  const versionPatterns = config.versionPatterns ?? { ...DEFAULT_VERSION_PATTERNS };
13
- const { tag, commits } = getCommitsSinceTarget(config.tagPrefix);
18
+ const { tag, commits } = getCommitsSinceTarget([config.tagPrefix]);
14
19
  let releaseType;
15
20
  let parsedCommitCount;
16
21
  let unparseableCommits;
17
- if (bumpOverride === void 0) {
18
- const determination = determineBumpFromCommits(commits, workTypes, versionPatterns, config.scopeAliases);
19
- parsedCommitCount = determination.parsedCommitCount;
20
- unparseableCommits = determination.unparseableCommits;
21
- releaseType = determination.releaseType;
22
+ let bump;
23
+ if (setVersion !== void 0) {
24
+ const primaryPackageFile = config.packageFiles[0];
25
+ if (primaryPackageFile === void 0) {
26
+ throw new Error("No package files specified");
27
+ }
28
+ const currentVersion = readCurrentVersion(primaryPackageFile);
29
+ if (currentVersion === void 0) {
30
+ throw new Error(`Cannot validate --set-version: failed to read current version from ${primaryPackageFile}`);
31
+ }
32
+ if (!isForwardVersion(currentVersion, setVersion)) {
33
+ throw new Error(`--set-version ${setVersion} is not greater than current version ${currentVersion}`);
34
+ }
35
+ bump = setAllVersions(config.packageFiles, setVersion, dryRun);
22
36
  } else {
23
- releaseType = bumpOverride;
24
- }
25
- if (releaseType === void 0) {
26
- return {
27
- components: [
28
- {
29
- status: "skipped",
30
- previousTag: tag,
31
- commitCount: commits.length,
32
- parsedCommitCount,
33
- unparseableCommits,
34
- bumpedFiles: [],
35
- changelogFiles: [],
36
- skipReason: "No release-worthy changes found. Skipping."
37
- }
38
- ],
39
- tags: [],
40
- dryRun
41
- };
37
+ if (bumpOverride === void 0) {
38
+ const determination = determineBumpFromCommits(commits, workTypes, versionPatterns, config.scopeAliases);
39
+ parsedCommitCount = determination.parsedCommitCount;
40
+ unparseableCommits = determination.unparseableCommits;
41
+ releaseType = determination.releaseType;
42
+ } else {
43
+ releaseType = bumpOverride;
44
+ }
45
+ if (releaseType === void 0) {
46
+ return {
47
+ workspaces: [
48
+ {
49
+ status: "skipped",
50
+ previousTag: tag,
51
+ commitCount: commits.length,
52
+ parsedCommitCount,
53
+ unparseableCommits,
54
+ bumpedFiles: [],
55
+ changelogFiles: [],
56
+ skipReason: "No release-worthy changes found. Skipping."
57
+ }
58
+ ],
59
+ tags: [],
60
+ dryRun
61
+ };
62
+ }
63
+ bump = bumpAllVersions(config.packageFiles, releaseType, dryRun);
42
64
  }
43
- const bump = bumpAllVersions(config.packageFiles, releaseType, dryRun);
44
65
  const newTag = `${config.tagPrefix}${bump.newVersion}`;
45
66
  const changelogFiles = generateChangelogs(config, newTag, dryRun);
46
67
  const changelogJsonFiles = [];
@@ -49,6 +70,7 @@ function releasePrepare(config, options) {
49
70
  changelogJsonFiles.push(...generateChangelogJson(config, changelogPath, newTag, dryRun));
50
71
  }
51
72
  }
73
+ maybeWriteSinglePackagePreviews(withReleaseNotes === true, config, newTag, changelogJsonFiles[0], dryRun);
52
74
  const formatCommandStr = config.formatCommand ?? (hasPrettierConfig() ? "npx prettier --write" : void 0);
53
75
  let formatCommand;
54
76
  if (formatCommandStr !== void 0) {
@@ -72,7 +94,7 @@ function releasePrepare(config, options) {
72
94
  }
73
95
  }
74
96
  return {
75
- components: [
97
+ workspaces: [
76
98
  {
77
99
  status: "released",
78
100
  previousTag: tag,
@@ -85,7 +107,8 @@ function releasePrepare(config, options) {
85
107
  bumpedFiles: bump.files,
86
108
  changelogFiles,
87
109
  commits,
88
- unparseableCommits
110
+ unparseableCommits,
111
+ ...setVersion === void 0 ? {} : { setVersion }
89
112
  }
90
113
  ],
91
114
  tags: [newTag],
@@ -93,6 +116,25 @@ function releasePrepare(config, options) {
93
116
  dryRun
94
117
  };
95
118
  }
119
+ function maybeWriteSinglePackagePreviews(withReleaseNotes, config, newTag, changelogJsonPath, dryRun) {
120
+ if (!withReleaseNotes) {
121
+ return;
122
+ }
123
+ if (!config.changelogJson.enabled) {
124
+ console.warn("Warning: --with-release-notes requires changelogJson.enabled; skipping preview generation");
125
+ return;
126
+ }
127
+ if (changelogJsonPath === void 0) {
128
+ return;
129
+ }
130
+ writeReleaseNotesPreviews({
131
+ workspacePath: process.cwd(),
132
+ tag: newTag,
133
+ changelogJsonPath,
134
+ sectionOrder: deriveSectionOrder(resolveWorkTypes(config.workTypes)),
135
+ dryRun
136
+ });
137
+ }
96
138
  export {
97
139
  releasePrepare
98
140
  };