@williamthorsen/release-kit 15.0.2 → 16.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 (138) hide show
  1. package/.meta/changelog.json +88 -0
  2. package/.readyup/kits/default.js +14 -14
  3. package/.readyup/kits/npm-auto-publish.js +5 -5
  4. package/.readyup/manifest.json +14 -14
  5. package/CHANGELOG.md +28 -0
  6. package/README.md +3 -3
  7. package/dist/esm/applyChangelogOverrides.js +6 -6
  8. package/dist/esm/assertCleanWorkingTree.js +2 -2
  9. package/dist/esm/assertReleasesOnNpm.js +11 -11
  10. package/dist/esm/assertTaggedBaseline.js +5 -5
  11. package/dist/esm/bin/release-kit.js +16 -16
  12. package/dist/esm/buildChangelogEntries.d.ts +19 -19
  13. package/dist/esm/buildChangelogEntries.js +40 -36
  14. package/dist/esm/buildChangelogItem.js +24 -24
  15. package/dist/esm/buildDependencyGraph.js +23 -23
  16. package/dist/esm/buildReleasedResult.js +21 -19
  17. package/dist/esm/buildSyntheticChangelogEntry.js +2 -2
  18. package/dist/esm/bumpVersion.js +8 -8
  19. package/dist/esm/changelogArchive.d.ts +1 -1
  20. package/dist/esm/changelogArchive.js +2 -2
  21. package/dist/esm/changelogJsonFile.js +5 -5
  22. package/dist/esm/changelogJsonUtils.js +3 -3
  23. package/dist/esm/changelogOverrides.d.ts +5 -5
  24. package/dist/esm/changelogOverrides.js +23 -23
  25. package/dist/esm/classifyChangelogCommit.js +4 -4
  26. package/dist/esm/commitCommand.js +7 -7
  27. package/dist/esm/compareVersions.js +13 -13
  28. package/dist/esm/configSchema.d.ts +2 -2
  29. package/dist/esm/configSchema.js +1 -1
  30. package/dist/esm/createGithubRelease.d.ts +4 -4
  31. package/dist/esm/createGithubRelease.js +10 -10
  32. package/dist/esm/createGithubReleaseCommand.js +9 -9
  33. package/dist/esm/createTags.d.ts +2 -2
  34. package/dist/esm/createTags.js +12 -12
  35. package/dist/esm/decideDirectReleases.d.ts +5 -5
  36. package/dist/esm/decideDirectReleases.js +25 -25
  37. package/dist/esm/decideRelease.d.ts +1 -1
  38. package/dist/esm/decideRelease.js +2 -2
  39. package/dist/esm/deriveDirectoryConfig.d.ts +1 -1
  40. package/dist/esm/deriveDirectoryConfig.js +18 -18
  41. package/dist/esm/deriveWorkspaceConfig.js +4 -4
  42. package/dist/esm/detectPackageManager.js +5 -5
  43. package/dist/esm/detectUndeclaredTagPrefixes.js +8 -8
  44. package/dist/esm/enumerateReleaseWindows.d.ts +1 -1
  45. package/dist/esm/enumerateReleaseWindows.js +9 -9
  46. package/dist/esm/findTransitiveDependents.js +5 -5
  47. package/dist/esm/findUnroutedEntryScopes.js +11 -11
  48. package/dist/esm/format.d.ts +1 -1
  49. package/dist/esm/format.js +1 -1
  50. package/dist/esm/formatPrepareFiles.d.ts +3 -3
  51. package/dist/esm/formatPrepareFiles.js +10 -10
  52. package/dist/esm/formatPrepareWarnings.js +6 -6
  53. package/dist/esm/hasPrettierConfig.js +2 -2
  54. package/dist/esm/init/checks.js +7 -5
  55. package/dist/esm/init/detectRepoType.js +3 -3
  56. package/dist/esm/init/initCommand.d.ts +4 -4
  57. package/dist/esm/init/initCommand.js +7 -7
  58. package/dist/esm/init/parseJsonRecord.d.ts +1 -1
  59. package/dist/esm/init/parseJsonRecord.js +4 -4
  60. package/dist/esm/init/scaffold.d.ts +4 -4
  61. package/dist/esm/init/scaffold.js +18 -9
  62. package/dist/esm/init/templates.d.ts +10 -10
  63. package/dist/esm/init/templates.js +5 -5
  64. package/dist/esm/init/updateTemplatesCommand.d.ts +2 -2
  65. package/dist/esm/init/updateTemplatesCommand.js +16 -14
  66. package/dist/esm/injectReleaseNotesIntoReadme.d.ts +1 -1
  67. package/dist/esm/injectReleaseNotesIntoReadme.js +6 -6
  68. package/dist/esm/injectSection.js +8 -8
  69. package/dist/esm/loadChangelogOverrides.d.ts +1 -1
  70. package/dist/esm/loadChangelogOverrides.js +9 -9
  71. package/dist/esm/loadConfig.d.ts +3 -3
  72. package/dist/esm/loadConfig.js +10 -10
  73. package/dist/esm/loadValidatedConfig.js +4 -4
  74. package/dist/esm/mergeConfig.d.ts +1 -1
  75. package/dist/esm/mergeConfig.js +27 -27
  76. package/dist/esm/monorepoConfigAssertions.js +15 -15
  77. package/dist/esm/npmRegistry.js +4 -4
  78. package/dist/esm/packsPath.js +3 -3
  79. package/dist/esm/parseChangeRecordBlock.js +33 -33
  80. package/dist/esm/parseCommitMessage.js +5 -5
  81. package/dist/esm/planChangelogFiles.js +8 -8
  82. package/dist/esm/planReleaseNotesPreviews.js +10 -10
  83. package/dist/esm/planVersionBump.js +24 -16
  84. package/dist/esm/prepareArgs.d.ts +9 -9
  85. package/dist/esm/prepareArgs.js +11 -11
  86. package/dist/esm/prepareCommand.js +23 -23
  87. package/dist/esm/prepareComposite.d.ts +4 -4
  88. package/dist/esm/prepareComposite.js +16 -16
  89. package/dist/esm/{releasePrepareTargets.d.ts → prepareReleaseTargets.d.ts} +9 -9
  90. package/dist/esm/{releasePrepareTargets.js → prepareReleaseTargets.js} +40 -40
  91. package/dist/esm/prepareRunContext.d.ts +1 -1
  92. package/dist/esm/prepareRunContext.js +5 -5
  93. package/dist/esm/prepareTarget.d.ts +3 -3
  94. package/dist/esm/prepareTarget.js +41 -39
  95. package/dist/esm/previewTagPrefixes.js +21 -21
  96. package/dist/esm/propagateBumps.js +8 -8
  97. package/dist/esm/publish.d.ts +2 -2
  98. package/dist/esm/publish.js +5 -5
  99. package/dist/esm/publishCommand.js +20 -20
  100. package/dist/esm/pushCommand.js +8 -8
  101. package/dist/esm/pushRelease.d.ts +1 -1
  102. package/dist/esm/pushRelease.js +4 -4
  103. package/dist/esm/readChangelogSections.d.ts +1 -1
  104. package/dist/esm/readChangelogSections.js +16 -16
  105. package/dist/esm/releasePlan.js +26 -26
  106. package/dist/esm/renderChangelogMarkdown.d.ts +4 -4
  107. package/dist/esm/renderChangelogMarkdown.js +18 -15
  108. package/dist/esm/renderReleaseNotes.d.ts +1 -1
  109. package/dist/esm/renderReleaseNotes.js +16 -16
  110. package/dist/esm/reportPrepare.js +34 -34
  111. package/dist/esm/resolveCommandTags.js +9 -9
  112. package/dist/esm/resolveReleaseDeclaration.d.ts +2 -2
  113. package/dist/esm/resolveReleaseDeclaration.js +22 -22
  114. package/dist/esm/resolveReleaseTags.js +19 -17
  115. package/dist/esm/resolveReleaseTargets.js +2 -2
  116. package/dist/esm/showTagPrefixesCommand.js +4 -4
  117. package/dist/esm/sync-labels/generateCommand.d.ts +3 -3
  118. package/dist/esm/sync-labels/generateCommand.js +10 -10
  119. package/dist/esm/sync-labels/initCommand.d.ts +3 -3
  120. package/dist/esm/sync-labels/initCommand.js +23 -15
  121. package/dist/esm/sync-labels/presets.js +3 -3
  122. package/dist/esm/sync-labels/resolveLabels.js +13 -13
  123. package/dist/esm/sync-labels/syncCommand.js +2 -2
  124. package/dist/esm/sync-labels/templates.d.ts +4 -4
  125. package/dist/esm/sync-labels/templates.js +13 -40
  126. package/dist/esm/tagCommand.js +4 -4
  127. package/dist/esm/topologicalSort.d.ts +2 -2
  128. package/dist/esm/topologicalSort.js +7 -7
  129. package/dist/esm/types.d.ts +3 -3
  130. package/dist/esm/validateAllChangelogOverrides.js +9 -9
  131. package/dist/esm/validateConfig.d.ts +1 -1
  132. package/dist/esm/validateConfig.js +60 -50
  133. package/dist/esm/validateOverridesCommand.js +2 -2
  134. package/docs/changelogs.md +5 -5
  135. package/docs/configuration.md +1 -1
  136. package/docs/work-types.md +1 -1
  137. package/package.json +9 -8
  138. package/templates/sync-labels.yaml.template +36 -0
@@ -12,7 +12,23 @@ const UNRELEASED_TAG = 'unreleased';
12
12
  const CANONICAL_SECTION_ORDER = new Map(Object.values(DEFAULT_WORK_TYPES).map((config, index) => [stripGroupDecorations(config.header), index]));
13
13
  export function buildChangelogEntries(config, tag, options) {
14
14
  const history = readReleaseHistory(config, options);
15
- return { entries: toChangelogEntries(history, tag), diagnostics: history.unreleased.diagnostics };
15
+ return { entries: convertToChangelogEntries(history, tag), diagnostics: history.unreleasedReading.diagnostics };
16
+ }
17
+ export function convertToChangelogEntries(history, tag) {
18
+ const { unreleasedReading } = history;
19
+ if (unreleasedReading.sections.length === 0) {
20
+ return [...history.releasedEntries];
21
+ }
22
+ return [
23
+ { version: extractVersion(tag), date: unreleasedReading.date, sections: unreleasedReading.sections },
24
+ ...history.releasedEntries,
25
+ ];
26
+ }
27
+ export function convertToReleaseEntries(history, tag, today) {
28
+ if (history.unreleasedReading.sections.length === 0) {
29
+ return [buildEmptyReleaseEntry(extractVersion(tag), today), ...history.releasedEntries];
30
+ }
31
+ return convertToChangelogEntries(history, tag);
16
32
  }
17
33
  export function readReleaseHistory(config, options) {
18
34
  try {
@@ -39,22 +55,6 @@ export function readReleaseHistory(config, options) {
39
55
  export function stripGroupDecorations(group) {
40
56
  return stripEmojiPrefix(group);
41
57
  }
42
- export function toChangelogEntries(history, tag) {
43
- const { unreleased } = history;
44
- if (unreleased.sections.length === 0) {
45
- return [...history.releasedEntries];
46
- }
47
- return [
48
- { version: extractVersion(tag), date: unreleased.date, sections: unreleased.sections },
49
- ...history.releasedEntries,
50
- ];
51
- }
52
- export function toReleaseEntries(history, tag, today) {
53
- if (history.unreleased.sections.length === 0) {
54
- return [buildEmptyReleaseEntry(extractVersion(tag), today), ...history.releasedEntries];
55
- }
56
- return toChangelogEntries(history, tag);
57
- }
58
58
  function appendItem(sectionMap, header, item) {
59
59
  let items = sectionMap.get(header);
60
60
  if (items === undefined) {
@@ -72,15 +72,15 @@ function buildSections(sectionMap, devOnlySections) {
72
72
  items,
73
73
  });
74
74
  }
75
- return sections.toSorted((a, b) => canonicalSectionPriority(a.title) - canonicalSectionPriority(b.title));
75
+ return sections.toSorted((a, b) => getCanonicalSectionPriority(a.title) - getCanonicalSectionPriority(b.title));
76
76
  }
77
- function canonicalSectionPriority(title) {
77
+ function formatDate(timestampSec) {
78
+ return new Date(timestampSec * 1_000).toISOString().slice(0, 10);
79
+ }
80
+ function getCanonicalSectionPriority(title) {
78
81
  const index = CANONICAL_SECTION_ORDER.get(stripGroupDecorations(title));
79
82
  return index ?? Infinity;
80
83
  }
81
- function formatDate(timestamp) {
82
- return new Date(timestamp * 1_000).toISOString().slice(0, 10);
83
- }
84
84
  function readCommit(commit, context, diagnostics) {
85
85
  if (isNonChangeSubject(commit.subject)) {
86
86
  return { items: [], isUnparseable: false };
@@ -100,10 +100,10 @@ function readCommit(commit, context, diagnostics) {
100
100
  const classification = classifyChangelogCommit(commit, context.workTypes, {
101
101
  breakingPolicies: context.breakingPolicies,
102
102
  ...(diagnostics !== undefined && {
103
- onPolicyViolation: (violating, type, surface) => {
103
+ onPolicyViolation: (violatingCommit, type, surface) => {
104
104
  diagnostics.policyViolations.push({
105
- commitHash: violating.hash,
106
- commitSubject: violating.subject,
105
+ commitHash: violatingCommit.hash,
106
+ commitSubject: violatingCommit.subject,
107
107
  type,
108
108
  surface,
109
109
  });
@@ -130,47 +130,51 @@ function transformReleases(windows, context) {
130
130
  unroutedEntryScopes: [],
131
131
  };
132
132
  const signals = [];
133
- const unparseable = [];
133
+ const unparseableCommits = [];
134
134
  let parsedCommitCount = 0;
135
135
  const sectionMap = new Map();
136
136
  const unreleasedCommits = unreleasedWindow?.commits ?? [];
137
137
  for (const commit of unreleasedCommits) {
138
138
  const reading = readCommit(commit, context, diagnostics);
139
- for (const derived of reading.items) {
140
- appendItem(sectionMap, derived.header, derived.item);
141
- signals.push(derived.signal);
139
+ for (const derivedItem of reading.items) {
140
+ appendItem(sectionMap, derivedItem.header, derivedItem.item);
141
+ signals.push(derivedItem.signal);
142
142
  }
143
143
  if (reading.items.length > 0) {
144
144
  parsedCommitCount += 1;
145
145
  }
146
146
  else if (reading.isUnparseable) {
147
- unparseable.push(commit);
147
+ unparseableCommits.push(commit);
148
148
  }
149
149
  }
150
150
  const releasedEntries = [];
151
151
  for (const release of windows.slice(1)) {
152
152
  const releaseSections = new Map();
153
153
  for (const commit of release.commits) {
154
- for (const derived of readCommit(commit, context, undefined).items) {
155
- appendItem(releaseSections, derived.header, derived.item);
154
+ for (const derivedItem of readCommit(commit, context, undefined).items) {
155
+ appendItem(releaseSections, derivedItem.header, derivedItem.item);
156
156
  }
157
157
  }
158
158
  const sections = buildSections(releaseSections, context.devOnlySections);
159
159
  if (sections.length > 0) {
160
- releasedEntries.push({ version: extractVersion(release.version), date: formatDate(release.timestamp), sections });
160
+ releasedEntries.push({
161
+ version: extractVersion(release.version),
162
+ date: formatDate(release.timestampSec),
163
+ sections,
164
+ });
161
165
  }
162
166
  }
163
167
  return {
164
168
  previousTag: baselineWindow?.version,
165
169
  releasedEntries,
166
- unreleased: {
170
+ unreleasedReading: {
167
171
  bump: determineBumpType(signals, context.workTypes, context.versionPatterns),
168
172
  commits: unreleasedCommits.filter((commit) => !isReleaseSubject(commit.subject)).toReversed(),
169
- date: formatDate(unreleasedWindow?.timestamp ?? Math.floor(Date.now() / 1_000)),
173
+ date: formatDate(unreleasedWindow?.timestampSec ?? Math.floor(Date.now() / 1_000)),
170
174
  diagnostics,
171
175
  parsedCommitCount,
172
176
  sections: buildSections(sectionMap, context.devOnlySections),
173
- unparseableCommits: unparseable.length > 0 ? unparseable.toReversed() : undefined,
177
+ unparseableCommits: unparseableCommits.length > 0 ? unparseableCommits.toReversed() : undefined,
174
178
  },
175
179
  };
176
180
  }
@@ -36,10 +36,10 @@ export function buildEntryItem(commit, entry, position, prNumber, context, diagn
36
36
  prefixSurface: 'entry',
37
37
  onPolicyViolation: diagnostics === undefined
38
38
  ? undefined
39
- : (violating, violatedType, surface) => {
39
+ : (violatingCommit, violatedType, surface) => {
40
40
  diagnostics.policyViolations.push({
41
- commitHash: violating.hash,
42
- commitSubject: violating.subject,
41
+ commitHash: violatingCommit.hash,
42
+ commitSubject: violatingCommit.subject,
43
43
  type: violatedType,
44
44
  surface,
45
45
  entryPosition: position,
@@ -65,7 +65,7 @@ export function buildTitleItem(commit, isParsedBreaking, workTypes) {
65
65
  if (body !== undefined) {
66
66
  item.body = body;
67
67
  }
68
- if (isParsedBreaking && subjectHasBreakingMarker(commit.message, workTypes)) {
68
+ if (isParsedBreaking && hasBreakingMarkerInSubject(commit.message, workTypes)) {
69
69
  item.breaking = true;
70
70
  }
71
71
  const migration = extractMigration(body);
@@ -80,43 +80,43 @@ export function hasRoutedEntry(entries, routing) {
80
80
  }
81
81
  function extractBody(message) {
82
82
  const lines = message.split('\n').slice(1);
83
- let start = 0;
84
- while (start < lines.length && (lines[start] ?? '').trim() === '') {
85
- start += 1;
83
+ let startIndex = 0;
84
+ while (startIndex < lines.length && (lines[startIndex] ?? '').trim() === '') {
85
+ startIndex += 1;
86
86
  }
87
- let end = lines.length;
88
- while (end > start) {
89
- const line = lines[end - 1] ?? '';
90
- const trimmed = line.trim();
91
- if (trimmed === '') {
92
- end -= 1;
87
+ let endIndex = lines.length;
88
+ while (endIndex > startIndex) {
89
+ const line = lines[endIndex - 1] ?? '';
90
+ const trimmedLine = line.trim();
91
+ if (trimmedLine === '') {
92
+ endIndex -= 1;
93
93
  continue;
94
94
  }
95
- if (TRAILER_PATTERNS.some((pattern) => pattern.test(trimmed))) {
96
- end -= 1;
95
+ if (TRAILER_PATTERNS.some((pattern) => pattern.test(trimmedLine))) {
96
+ endIndex -= 1;
97
97
  continue;
98
98
  }
99
99
  break;
100
100
  }
101
- if (end <= start) {
101
+ if (endIndex <= startIndex) {
102
102
  return undefined;
103
103
  }
104
- return lines.slice(start, end).join('\n').trim();
104
+ return lines.slice(startIndex, endIndex).join('\n').trim();
105
105
  }
106
106
  function extractDescription(message) {
107
107
  const firstLine = message.split('\n', 1)[0] ?? message;
108
- const afterColon = firstLine.split(': ').slice(1).join(': ');
109
- return afterColon.charAt(0).toUpperCase() + afterColon.slice(1);
108
+ const descriptionText = firstLine.split(': ').slice(1).join(': ');
109
+ return descriptionText.charAt(0).toUpperCase() + descriptionText.slice(1);
110
+ }
111
+ function hasBreakingMarkerInSubject(message, workTypes) {
112
+ return parseSubject(message.split('\n', 1)[0] ?? '', workTypes)?.breaking === true;
110
113
  }
111
114
  function isRoutedTo(scopes, routing) {
112
115
  if (scopes.length === 0) {
113
116
  return true;
114
117
  }
115
118
  return scopes.some((scope) => {
116
- const resolved = routing.scopeAliases[scope] ?? scope;
117
- return resolved === '*' || resolved === routing.scope;
119
+ const resolvedScope = routing.scopeAliases[scope] ?? scope;
120
+ return resolvedScope === '*' || resolvedScope === routing.scope;
118
121
  });
119
122
  }
120
- function subjectHasBreakingMarker(message, workTypes) {
121
- return parseSubject(message.split('\n', 1)[0] ?? '', workTypes)?.breaking === true;
122
- }
@@ -15,36 +15,36 @@ export function buildDependencyGraph(targets) {
15
15
  if (primaryPackageFile === undefined) {
16
16
  continue;
17
17
  }
18
- const pkg = readPackageJsonSubset(primaryPackageFile);
19
- targetPackages.set(target, pkg);
20
- if (typeof pkg.version === 'string') {
21
- dirToVersion.set(target.id, pkg.version);
18
+ const packageJson = readPackageJsonSubset(primaryPackageFile);
19
+ targetPackages.set(target, packageJson);
20
+ if (typeof packageJson.version === 'string') {
21
+ dirToVersion.set(target.id, packageJson.version);
22
22
  }
23
- if (pkg.name === undefined) {
23
+ if (packageJson.name === undefined) {
24
24
  continue;
25
25
  }
26
- packageNameToDir.set(pkg.name, target.id);
27
- dirToPackageName.set(target.id, pkg.name);
26
+ packageNameToDir.set(packageJson.name, target.id);
27
+ dirToPackageName.set(target.id, packageJson.name);
28
28
  }
29
- for (const [target, pkg] of targetPackages) {
30
- const allDeps = { ...pkg.dependencies, ...pkg.peerDependencies };
31
- for (const [depName, depVersion] of Object.entries(allDeps)) {
32
- if (typeof depVersion !== 'string' || !depVersion.startsWith('workspace:')) {
29
+ for (const [target, packageJson] of targetPackages) {
30
+ const allDependencies = { ...packageJson.dependencies, ...packageJson.peerDependencies };
31
+ for (const [dependencyName, dependencyVersion] of Object.entries(allDependencies)) {
32
+ if (typeof dependencyVersion !== 'string' || !dependencyVersion.startsWith('workspace:')) {
33
33
  continue;
34
34
  }
35
- const existing = dependentsOf.get(depName);
36
- if (existing === undefined) {
37
- dependentsOf.set(depName, [target]);
35
+ const existingDependents = dependentsOf.get(dependencyName);
36
+ if (existingDependents === undefined) {
37
+ dependentsOf.set(dependencyName, [target]);
38
38
  }
39
39
  else {
40
- existing.push(target);
40
+ existingDependents.push(target);
41
41
  }
42
- const forward = dependenciesOf.get(target.id);
43
- if (forward === undefined) {
44
- dependenciesOf.set(target.id, new Set([depName]));
42
+ const forwardDependencies = dependenciesOf.get(target.id);
43
+ if (forwardDependencies === undefined) {
44
+ dependenciesOf.set(target.id, new Set([dependencyName]));
45
45
  }
46
46
  else {
47
- forward.add(depName);
47
+ forwardDependencies.add(dependencyName);
48
48
  }
49
49
  }
50
50
  }
@@ -58,15 +58,15 @@ function readPackageJsonSubset(filePath) {
58
58
  catch (error) {
59
59
  throw chainError(`Failed to read ${filePath}`, error);
60
60
  }
61
- let parsed;
61
+ let parsedJson;
62
62
  try {
63
- parsed = JSON.parse(content);
63
+ parsedJson = JSON.parse(content);
64
64
  }
65
65
  catch (error) {
66
66
  throw chainError(`Failed to parse JSON in ${filePath}`, error);
67
67
  }
68
- if (!isPackageJsonSubset(parsed)) {
68
+ if (!isPackageJsonSubset(parsedJson)) {
69
69
  throw new Error(`Invalid package.json at ${filePath}`);
70
70
  }
71
- return parsed;
71
+ return parsedJson;
72
72
  }
@@ -17,62 +17,64 @@ export function buildReleasedResult(target, fields, release, decision, history)
17
17
  }
18
18
  }
19
19
  function buildReleasedComposite(fields, release, decision, history) {
20
- const { unreleased } = history;
20
+ const { unreleasedReading } = history;
21
21
  const result = {
22
22
  ...fields,
23
23
  status: 'released',
24
24
  kind: 'composite',
25
- parsedCommitCount: unreleased.parsedCommitCount,
25
+ parsedCommitCount: unreleasedReading.parsedCommitCount,
26
26
  releaseType: release.releaseType,
27
- commits: unreleased.commits,
28
- ...(unreleased.unparseableCommits !== undefined && { unparseableCommits: unreleased.unparseableCommits }),
27
+ commits: unreleasedReading.commits,
28
+ ...(unreleasedReading.unparseableCommits !== undefined && {
29
+ unparseableCommits: unreleasedReading.unparseableCommits,
30
+ }),
29
31
  ...(decision?.bumpOverride !== undefined && { bumpOverride: decision.bumpOverride }),
30
32
  };
31
- attachChangelogDiagnostics(result, unreleased.diagnostics);
33
+ attachChangelogDiagnostics(result, unreleasedReading.diagnostics);
32
34
  return result;
33
35
  }
34
36
  function buildReleasedDirectory(target, fields, release, decision, history) {
35
- const { unreleased } = history;
37
+ const { unreleasedReading } = history;
36
38
  const setVersion = decision?.setVersion;
37
39
  const result = {
38
40
  ...fields,
39
41
  status: 'released',
40
42
  kind: 'directory',
41
43
  name: target.id,
42
- commits: unreleased.commits,
44
+ commits: unreleasedReading.commits,
43
45
  ...(setVersion === undefined && {
44
46
  releaseType: release.releaseType,
45
- parsedCommitCount: unreleased.parsedCommitCount,
47
+ parsedCommitCount: unreleasedReading.parsedCommitCount,
46
48
  }),
47
49
  ...(decision?.bumpOverride !== undefined && { bumpOverride: decision.bumpOverride }),
48
- ...(setVersion !== undefined && { setVersion }),
50
+ ...(setVersion !== undefined && { versionOverride: setVersion }),
49
51
  };
50
- if (setVersion === undefined && unreleased.unparseableCommits !== undefined) {
51
- result.unparseableCommits = unreleased.unparseableCommits;
52
+ if (setVersion === undefined && unreleasedReading.unparseableCommits !== undefined) {
53
+ result.unparseableCommits = unreleasedReading.unparseableCommits;
52
54
  }
53
- attachChangelogDiagnostics(result, unreleased.diagnostics);
55
+ attachChangelogDiagnostics(result, unreleasedReading.diagnostics);
54
56
  return result;
55
57
  }
56
58
  function buildReleasedPackage(target, fields, release, decision, history) {
57
- const { unreleased } = history;
59
+ const { unreleasedReading } = history;
58
60
  const setVersion = decision?.setVersion;
59
61
  const hasParseCounts = decision !== undefined && setVersion === undefined;
60
62
  const result = {
61
63
  ...fields,
62
64
  status: 'released',
63
65
  kind: 'package',
64
- commits: unreleased.commits,
66
+ commits: unreleasedReading.commits,
65
67
  ...(target.isWorkspace && { name: target.id }),
66
68
  ...(setVersion === undefined && { releaseType: release.releaseType }),
67
- ...(hasParseCounts && { parsedCommitCount: unreleased.parsedCommitCount }),
69
+ ...(hasParseCounts && { parsedCommitCount: unreleasedReading.parsedCommitCount }),
68
70
  ...(decision === undefined && { propagatedOnly: true }),
69
71
  ...(release.propagatedFrom !== undefined && { propagatedFrom: release.propagatedFrom }),
70
72
  ...(decision?.bumpOverride !== undefined && { bumpOverride: decision.bumpOverride }),
71
- ...(setVersion !== undefined && { setVersion }),
73
+ ...(setVersion !== undefined && { versionOverride: setVersion }),
72
74
  };
73
- if (setVersion === undefined && unreleased.unparseableCommits !== undefined) {
74
- result.unparseableCommits = unreleased.unparseableCommits;
75
+ if (setVersion === undefined && unreleasedReading.unparseableCommits !== undefined) {
76
+ result.unparseableCommits = unreleasedReading.unparseableCommits;
75
77
  }
76
- attachChangelogDiagnostics(result, unreleased.diagnostics);
78
+ attachChangelogDiagnostics(result, unreleasedReading.diagnostics);
77
79
  return result;
78
80
  }
@@ -1,6 +1,6 @@
1
1
  export function buildSyntheticChangelogEntry(propagatedFrom, version, date, sectionTitle) {
2
- const items = propagatedFrom.map((dep) => ({
3
- description: `Bumped \`${dep.packageName}\` to ${dep.newVersion}`,
2
+ const items = propagatedFrom.map((dependency) => ({
3
+ description: `Bumped \`${dependency.packageName}\` to ${dependency.newVersion}`,
4
4
  }));
5
5
  return {
6
6
  version,
@@ -9,18 +9,18 @@ export function bumpVersion(version, releaseType) {
9
9
  if (major === undefined || minor === undefined || patch === undefined) {
10
10
  throw new Error(`Invalid semver version: '${version}'`);
11
11
  }
12
- const majorNum = Number.parseInt(major, 10);
13
- const minorNum = Number.parseInt(minor, 10);
14
- const patchNum = Number.parseInt(patch, 10);
12
+ const majorNumber = Number.parseInt(major, 10);
13
+ const minorNumber = Number.parseInt(minor, 10);
14
+ const patchNumber = Number.parseInt(patch, 10);
15
15
  switch (releaseType) {
16
16
  case 'major':
17
- if (majorNum === 0) {
18
- return `0.${minorNum + 1}.0`;
17
+ if (majorNumber === 0) {
18
+ return `0.${minorNumber + 1}.0`;
19
19
  }
20
- return `${majorNum + 1}.0.0`;
20
+ return `${majorNumber + 1}.0.0`;
21
21
  case 'minor':
22
- return `${majorNum}.${minorNum + 1}.0`;
22
+ return `${majorNumber}.${minorNumber + 1}.0`;
23
23
  case 'patch':
24
- return `${majorNum}.${minorNum}.${patchNum + 1}`;
24
+ return `${majorNumber}.${minorNumber}.${patchNumber + 1}`;
25
25
  }
26
26
  }
@@ -2,7 +2,7 @@
2
2
  export declare const CHANGELOG_ARCHIVE_DIRECTORY = "changelogs";
3
3
  /** An archive file that exists on disk. */
4
4
  export interface ChangelogArchivePath {
5
- major: number;
5
+ majorVersion: number;
6
6
  path: string;
7
7
  }
8
8
  /** Returns the path, relative to the changelog directory, of the archive file for a major version. */
@@ -13,9 +13,9 @@ export function listArchiveFiles(changelogDir) {
13
13
  for (const name of readdirSync(archiveDir)) {
14
14
  const match = ARCHIVE_FILE_PATTERN.exec(name);
15
15
  if (match?.[1] !== undefined) {
16
- archives.push({ major: Number(match[1]), path: join(archiveDir, name) });
16
+ archives.push({ majorVersion: Number(match[1]), path: join(archiveDir, name) });
17
17
  }
18
18
  }
19
- return archives.toSorted((a, b) => b.major - a.major);
19
+ return archives.toSorted((a, b) => b.majorVersion - a.majorVersion);
20
20
  }
21
21
  const ARCHIVE_FILE_PATTERN = /^CHANGELOG-v(\d+)\.md$/;
@@ -12,8 +12,8 @@ export function renderChangelogJson(entries) {
12
12
  return stringify(sortNewestFirst(entries), { maxLength: 100 }) + '\n';
13
13
  }
14
14
  export function mergeChangelogEntriesWithDisk(filePath, entries) {
15
- const existing = readExistingEntries(filePath);
16
- return mergeEntries(entries, existing);
15
+ const existingEntries = readExistingEntries(filePath);
16
+ return mergeEntries(entries, existingEntries);
17
17
  }
18
18
  function sortNewestFirst(entries) {
19
19
  return [...entries].toSorted((a, b) => compareVersionsDescending(a.version, b.version));
@@ -24,11 +24,11 @@ function readExistingEntries(filePath) {
24
24
  }
25
25
  try {
26
26
  const content = readFileSync(filePath, 'utf8');
27
- const parsed = JSON.parse(content);
28
- if (!isUnknownArray(parsed)) {
27
+ const parsedJson = JSON.parse(content);
28
+ if (!isUnknownArray(parsedJson)) {
29
29
  return [];
30
30
  }
31
- return parsed.filter(isChangelogEntry);
31
+ return parsedJson.filter(isChangelogEntry);
32
32
  }
33
33
  catch (error) {
34
34
  console.warn(`Warning: could not parse existing ${filePath}: ${describeError(error)}; treating as empty`);
@@ -16,11 +16,11 @@ export function readChangelogEntries(filePath) {
16
16
  }
17
17
  try {
18
18
  const content = readFileSync(filePath, 'utf8');
19
- const parsed = JSON.parse(content);
20
- if (!isUnknownArray(parsed)) {
19
+ const parsedJson = JSON.parse(content);
20
+ if (!isUnknownArray(parsedJson)) {
21
21
  return undefined;
22
22
  }
23
- return parsed.filter(isChangelogEntry);
23
+ return parsedJson.filter(isChangelogEntry);
24
24
  }
25
25
  catch {
26
26
  return undefined;
@@ -31,15 +31,15 @@ export declare function createOverrideContext(workspacePaths: readonly string[])
31
31
  * yields an empty map.
32
32
  */
33
33
  export declare function loadOverridesForScopes(scopes: {
34
- project?: string;
34
+ projectPath?: string;
35
35
  workspaces?: string[];
36
36
  }): LoadOverridesForScopesResult;
37
37
  /** Result of {@link loadOverridesForScopes}: per-scope maps plus accumulated load/validation errors. */
38
38
  export interface LoadOverridesForScopesResult {
39
39
  /** Project-tier (root) overrides. Empty map when the project file is absent. */
40
- project: Map<string, ChangelogOverride>;
40
+ projectOverrides: Map<string, ChangelogOverride>;
41
41
  /** Workspace-tier overrides keyed by `workspacePath` (e.g., `'packages/foo'`). Empty map when absent. */
42
- perWorkspace: Map<string, Map<string, ChangelogOverride>>;
42
+ overridesByWorkspace: Map<string, Map<string, ChangelogOverride>>;
43
43
  /** All load and validation errors across every requested scope, prefixed with the offending file path. */
44
44
  errors: string[];
45
45
  }
@@ -50,8 +50,8 @@ export interface LoadOverridesForScopesResult {
50
50
  * that matches nothing in its own workspace is stale, and it is warned about at once rather than at the end of the run.
51
51
  */
52
52
  export interface OverrideContext {
53
- project: Map<string, ChangelogOverride>;
54
- perWorkspace: Map<string, Map<string, ChangelogOverride>>;
53
+ projectOverrides: Map<string, ChangelogOverride>;
54
+ overridesByWorkspace: Map<string, Map<string, ChangelogOverride>>;
55
55
  overrideWarnings: string[];
56
56
  globalMatchedRootKeys: Set<string>;
57
57
  }
@@ -3,15 +3,15 @@ import { applyChangelogOverrides, formatStaleOverrideKeyWarning } from "./applyC
3
3
  import { loadChangelogOverrides } from "./loadChangelogOverrides.js";
4
4
  const OVERRIDES_FILENAME = '.meta/changelog-overrides.json';
5
5
  export function applyWorkspaceOverrides(newEntries, workspacePath, overrideContext) {
6
- const { project, perWorkspace, overrideWarnings, globalMatchedRootKeys } = overrideContext;
7
- const workspaceOverrides = workspacePath === undefined ? undefined : perWorkspace.get(workspacePath);
8
- const composed = composeOverrides(project, workspaceOverrides);
9
- const applied = applyChangelogOverrides(newEntries, composed);
10
- if (applied.errors.length > 0) {
11
- throw new Error(`Changelog override application failed:\n - ${applied.errors.join('\n - ')}`);
6
+ const { projectOverrides, overridesByWorkspace, overrideWarnings, globalMatchedRootKeys } = overrideContext;
7
+ const workspaceOverrides = workspacePath === undefined ? undefined : overridesByWorkspace.get(workspacePath);
8
+ const composedOverrides = composeOverrides(projectOverrides, workspaceOverrides);
9
+ const appliedResult = applyChangelogOverrides(newEntries, composedOverrides);
10
+ if (appliedResult.errors.length > 0) {
11
+ throw new Error(`Changelog override application failed:\n - ${appliedResult.errors.join('\n - ')}`);
12
12
  }
13
- overrideWarnings.push(...applied.warnings);
14
- const matchedSet = new Set(applied.matchedKeys);
13
+ overrideWarnings.push(...appliedResult.warnings);
14
+ const matchedSet = new Set(appliedResult.matchedKeys);
15
15
  if (workspaceOverrides !== undefined) {
16
16
  for (const key of workspaceOverrides.keys()) {
17
17
  if (!matchedSet.has(key)) {
@@ -19,45 +19,45 @@ export function applyWorkspaceOverrides(newEntries, workspacePath, overrideConte
19
19
  }
20
20
  }
21
21
  }
22
- for (const key of applied.matchedKeys) {
22
+ for (const key of appliedResult.matchedKeys) {
23
23
  if (workspaceOverrides?.has(key))
24
24
  continue;
25
25
  globalMatchedRootKeys.add(key);
26
26
  }
27
- return applied;
27
+ return appliedResult;
28
28
  }
29
29
  export function composeOverrides(rootEntries, workspaceEntries) {
30
- const composed = new Map(rootEntries);
30
+ const composedOverrides = new Map(rootEntries);
31
31
  if (workspaceEntries !== undefined) {
32
32
  for (const [key, value] of workspaceEntries) {
33
- composed.set(key, value);
33
+ composedOverrides.set(key, value);
34
34
  }
35
35
  }
36
- return composed;
36
+ return composedOverrides;
37
37
  }
38
38
  export function createOverrideContext(workspacePaths) {
39
- const result = loadOverridesForScopes({ project: '.', workspaces: [...workspacePaths] });
39
+ const result = loadOverridesForScopes({ projectPath: '.', workspaces: [...workspacePaths] });
40
40
  if (result.errors.length > 0) {
41
41
  throw new Error(`Failed to load changelog overrides:\n - ${result.errors.join('\n - ')}`);
42
42
  }
43
43
  return {
44
- project: result.project,
45
- perWorkspace: result.perWorkspace,
44
+ projectOverrides: result.projectOverrides,
45
+ overridesByWorkspace: result.overridesByWorkspace,
46
46
  overrideWarnings: [],
47
47
  globalMatchedRootKeys: new Set(),
48
48
  };
49
49
  }
50
50
  export function loadOverridesForScopes(scopes) {
51
51
  const errors = [];
52
- let project = new Map();
53
- const perWorkspace = new Map();
54
- if (scopes.project !== undefined) {
55
- const result = loadChangelogOverrides(resolveOverridePath(scopes.project));
52
+ let projectOverrides = new Map();
53
+ const overridesByWorkspace = new Map();
54
+ if (scopes.projectPath !== undefined) {
55
+ const result = loadChangelogOverrides(resolveOverridePath(scopes.projectPath));
56
56
  if ('errors' in result) {
57
57
  errors.push(...result.errors);
58
58
  }
59
59
  else {
60
- project = result.overrides;
60
+ projectOverrides = result.overrides;
61
61
  }
62
62
  }
63
63
  const workspacePaths = scopes.workspaces ?? [];
@@ -67,10 +67,10 @@ export function loadOverridesForScopes(scopes) {
67
67
  errors.push(...result.errors);
68
68
  }
69
69
  else if (result.overrides.size > 0) {
70
- perWorkspace.set(workspacePath, result.overrides);
70
+ overridesByWorkspace.set(workspacePath, result.overrides);
71
71
  }
72
72
  }
73
- return { project, perWorkspace, errors };
73
+ return { projectOverrides, overridesByWorkspace, errors };
74
74
  }
75
75
  export function resolveOverridePath(scopeRoot) {
76
76
  return path.posix.join(scopeRoot, OVERRIDES_FILENAME);
@@ -10,18 +10,18 @@ export function classifyChangelogCommit(commit, workTypes, options) {
10
10
  if (!hasTicketPrefix(subject)) {
11
11
  return { kind: 'unparseable' };
12
12
  }
13
- const parsed = parseCommitMessage(commit.message, commit.hash, workTypes, undefined, options);
14
- if (parsed === undefined) {
13
+ const parsedCommit = parseCommitMessage(commit.message, commit.hash, workTypes, undefined, options);
14
+ if (parsedCommit === undefined) {
15
15
  return { kind: 'unparseable' };
16
16
  }
17
- const config = workTypes[parsed.type];
17
+ const config = workTypes[parsedCommit.type];
18
18
  if (config === undefined) {
19
19
  return { kind: 'unparseable' };
20
20
  }
21
21
  if (config.excludedFromChangelog === true) {
22
22
  return { kind: 'excluded' };
23
23
  }
24
- return { kind: 'header', header: config.header, type: parsed.type, breaking: parsed.breaking };
24
+ return { kind: 'header', header: config.header, type: parsedCommit.type, breaking: parsedCommit.breaking };
25
25
  }
26
26
  export function isNonChangeSubject(subject) {
27
27
  return isReleaseSubject(subject) || MERGE_SUBJECT_PATTERN.test(subject);