@williamthorsen/release-kit 10.2.0 → 10.2.2
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/.readyup/kits/default.js +1 -1
- package/.readyup/kits/npm-auto-publish.js +135 -23
- package/.readyup/manifest.json +3 -3
- package/CHANGELOG.md +30 -0
- package/README.md +12 -8
- package/dist/esm/assertCleanWorkingTree.js +2 -0
- package/dist/esm/buildChangelogEntries.js +2 -2
- package/dist/esm/buildReleaseSummary.d.ts +1 -1
- package/dist/esm/changelogJsonFile.d.ts +1 -3
- package/dist/esm/changelogJsonFile.js +4 -18
- package/dist/esm/commitCommand.js +10 -17
- package/dist/esm/createTags.js +6 -16
- package/dist/esm/detectUndeclaredTagPrefixes.js +2 -0
- package/dist/esm/getCommitsSinceTarget.js +3 -0
- package/dist/esm/init/checks.js +2 -1
- package/dist/esm/injectReleaseNotesIntoReadme.d.ts +2 -0
- package/dist/esm/injectReleaseNotesIntoReadme.js +13 -10
- package/dist/esm/planReleaseNotesPreviews.d.ts +13 -0
- package/dist/esm/planReleaseNotesPreviews.js +43 -0
- package/dist/esm/planVersionBump.d.ts +9 -0
- package/dist/esm/{bumpAllVersions.js → planVersionBump.js} +15 -26
- package/dist/esm/prepareCommand.d.ts +0 -4
- package/dist/esm/prepareCommand.js +51 -45
- package/dist/esm/previewTagPrefixes.js +2 -0
- package/dist/esm/pushRelease.js +2 -0
- package/dist/esm/releaseFiles.d.ts +4 -0
- package/dist/esm/releaseFiles.js +34 -0
- package/dist/esm/releasePlan.d.ts +10 -0
- package/dist/esm/releasePlan.js +53 -0
- package/dist/esm/releasePrepare.d.ts +3 -3
- package/dist/esm/releasePrepare.js +53 -54
- package/dist/esm/releasePrepareMono.d.ts +3 -2
- package/dist/esm/releasePrepareMono.js +48 -52
- package/dist/esm/releasePrepareProject.d.ts +3 -0
- package/dist/esm/releasePrepareProject.js +33 -37
- package/dist/esm/renderChangelogMarkdown.d.ts +0 -7
- package/dist/esm/renderChangelogMarkdown.js +0 -13
- package/dist/esm/reportPrepare.d.ts +5 -1
- package/dist/esm/reportPrepare.js +36 -17
- package/dist/esm/resolveReleaseTags.js +5 -1
- package/dist/esm/runGitCliff.d.ts +1 -2
- package/dist/esm/runGitCliff.js +11 -11
- package/dist/esm/sync-labels/syncCommand.js +2 -2
- package/dist/esm/types.d.ts +4 -9
- package/dist/esm/workTypesData.d.ts +1 -1
- package/package.json +2 -2
- package/dist/esm/bumpAllVersions.d.ts +0 -3
- package/dist/esm/writeReleaseNotesPreviews.d.ts +0 -18
- package/dist/esm/writeReleaseNotesPreviews.js +0 -63
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { join as joinPath } from 'node:path';
|
|
2
2
|
import { buildChangelogEntries } from "./buildChangelogEntries.js";
|
|
3
3
|
import { buildDependencyGraph } from "./buildDependencyGraph.js";
|
|
4
4
|
import { buildEmptyReleaseEntry } from "./buildEmptyReleaseEntry.js";
|
|
5
|
+
import { buildReleaseSummary } from "./buildReleaseSummary.js";
|
|
5
6
|
import { buildSyntheticChangelogEntry } from "./buildSyntheticChangelogEntry.js";
|
|
6
|
-
import {
|
|
7
|
-
import { mergeChangelogEntriesWithDisk, resolveChangelogJsonPath, upsertChangelogJsonAndReturn, } from "./changelogJsonFile.js";
|
|
7
|
+
import { mergeChangelogEntriesWithDisk, renderChangelogJson, resolveChangelogJsonPath } from "./changelogJsonFile.js";
|
|
8
8
|
import { applyWorkspaceOverrides, createOverrideContext, formatStaleOverrideKeyWarning, } from "./changelogOverrides.js";
|
|
9
9
|
import { createPolicyViolationCollector } from "./collectPolicyViolations.js";
|
|
10
10
|
import { isForwardVersion } from "./compareVersions.js";
|
|
@@ -15,15 +15,17 @@ import { buildTagPattern, getAllTagPrefixes } from "./generateChangelogs.js";
|
|
|
15
15
|
import { getCommitsSinceTarget } from "./getCommitsSinceTarget.js";
|
|
16
16
|
import { hasPrettierConfig } from "./hasPrettierConfig.js";
|
|
17
17
|
import { resolveWorkTypes } from "./loadConfig.js";
|
|
18
|
+
import { planReleaseNotesPreviews } from "./planReleaseNotesPreviews.js";
|
|
19
|
+
import { planVersionBump, planVersionSet } from "./planVersionBump.js";
|
|
18
20
|
import { propagateBumps } from "./propagateBumps.js";
|
|
19
21
|
import { readCurrentVersion } from "./readCurrentVersion.js";
|
|
20
22
|
import { releasePrepareProject } from "./releasePrepareProject.js";
|
|
21
|
-
import {
|
|
23
|
+
import { renderChangelogMarkdown } from "./renderChangelogMarkdown.js";
|
|
22
24
|
import { deriveSectionOrder } from "./resolveReleaseNotesConfig.js";
|
|
23
25
|
import { refreshGitCliffCache } from "./runGitCliff.js";
|
|
24
|
-
import { writeReleaseNotesPreviews } from "./writeReleaseNotesPreviews.js";
|
|
25
26
|
export function releasePrepareMono(config, options) {
|
|
26
|
-
const {
|
|
27
|
+
const { withReleaseNotes } = options;
|
|
28
|
+
const writes = [];
|
|
27
29
|
if (withReleaseNotes === true && !config.changelogJson.enabled) {
|
|
28
30
|
console.warn('Warning: --with-release-notes requires changelogJson.enabled; skipping preview generation');
|
|
29
31
|
}
|
|
@@ -59,7 +61,8 @@ export function releasePrepareMono(config, options) {
|
|
|
59
61
|
config,
|
|
60
62
|
directResults,
|
|
61
63
|
previousTags,
|
|
62
|
-
|
|
64
|
+
writes,
|
|
65
|
+
warnings,
|
|
63
66
|
workspaces,
|
|
64
67
|
previewOptions,
|
|
65
68
|
overrideContext,
|
|
@@ -77,13 +80,15 @@ export function releasePrepareMono(config, options) {
|
|
|
77
80
|
config,
|
|
78
81
|
options,
|
|
79
82
|
modifiedFiles,
|
|
83
|
+
writes,
|
|
80
84
|
tags,
|
|
85
|
+
warnings,
|
|
81
86
|
rootOverrides: overrideContext.project,
|
|
82
87
|
overrideWarnings: overrideContext.overrideWarnings,
|
|
83
88
|
globalMatchedRootKeys: overrideContext.globalMatchedRootKeys,
|
|
84
89
|
}));
|
|
85
90
|
}
|
|
86
|
-
const formatCommand =
|
|
91
|
+
const formatCommand = planFormatCommand(config, tags, modifiedFiles);
|
|
87
92
|
for (const overrideKey of overrideContext.project.keys()) {
|
|
88
93
|
if (!overrideContext.globalMatchedRootKeys.has(overrideKey)) {
|
|
89
94
|
overrideContext.overrideWarnings.push(formatStaleOverrideKeyWarning(overrideKey));
|
|
@@ -93,8 +98,9 @@ export function releasePrepareMono(config, options) {
|
|
|
93
98
|
return {
|
|
94
99
|
workspaces,
|
|
95
100
|
tags,
|
|
101
|
+
writes,
|
|
102
|
+
summary: buildReleaseSummary({ workspaces, ...(project !== undefined && { project }) }),
|
|
96
103
|
formatCommand,
|
|
97
|
-
dryRun,
|
|
98
104
|
...(allWarnings.length > 0 && { warnings: allWarnings }),
|
|
99
105
|
...(project !== undefined && { project }),
|
|
100
106
|
};
|
|
@@ -221,7 +227,7 @@ function collectSkippedWorkspaces(skippedResults, fullReleaseSet) {
|
|
|
221
227
|
return workspaces;
|
|
222
228
|
}
|
|
223
229
|
function executeReleaseSet(args) {
|
|
224
|
-
const { sortedDirs, fullReleaseSet, config, directResults, previousTags,
|
|
230
|
+
const { sortedDirs, fullReleaseSet, config, directResults, previousTags, writes, warnings, workspaces, previewOptions, overrideContext, sectionOrder, } = args;
|
|
225
231
|
const tags = [];
|
|
226
232
|
const modifiedFiles = [];
|
|
227
233
|
const today = new Date().toISOString().slice(0, 10);
|
|
@@ -241,10 +247,11 @@ function executeReleaseSet(args) {
|
|
|
241
247
|
directResult: directResults.get(dir),
|
|
242
248
|
previousTags,
|
|
243
249
|
config,
|
|
244
|
-
dryRun,
|
|
245
250
|
today,
|
|
246
251
|
tags,
|
|
247
252
|
modifiedFiles,
|
|
253
|
+
writes,
|
|
254
|
+
warnings,
|
|
248
255
|
workspaces,
|
|
249
256
|
previewOptions,
|
|
250
257
|
overrideContext,
|
|
@@ -254,17 +261,18 @@ function executeReleaseSet(args) {
|
|
|
254
261
|
return { tags, modifiedFiles };
|
|
255
262
|
}
|
|
256
263
|
function executeWorkspaceRelease(args) {
|
|
257
|
-
const { dir, workspace, releaseEntry, directResult, previousTags, config,
|
|
264
|
+
const { dir, workspace, releaseEntry, directResult, previousTags, config, today, tags, modifiedFiles, writes, warnings, workspaces, previewOptions, overrideContext, sectionOrder, } = args;
|
|
258
265
|
const setVersionTarget = directResult?.setVersion;
|
|
259
266
|
const bump = setVersionTarget === undefined
|
|
260
|
-
?
|
|
261
|
-
:
|
|
267
|
+
? planVersionBump(workspace.packageFiles, releaseEntry.releaseType)
|
|
268
|
+
: planVersionSet(workspace.packageFiles, setVersionTarget);
|
|
262
269
|
const newTag = `${workspace.tagPrefix}${bump.newVersion}`;
|
|
263
270
|
tags.push(newTag);
|
|
264
|
-
|
|
271
|
+
writes.push(...bump.writes);
|
|
272
|
+
modifiedFiles.push(...workspace.packageFiles, ...workspace.changelogPaths.map((changelogPath) => joinPath(changelogPath, 'CHANGELOG.md')));
|
|
265
273
|
const isPropagationOnly = directResult === undefined;
|
|
266
274
|
const isEmptyRange = directResult !== undefined && directResult.commits.length === 0;
|
|
267
|
-
const changelogFiles = generateWorkspaceChangelogs({
|
|
275
|
+
const { changelogFiles, previewFiles } = generateWorkspaceChangelogs({
|
|
268
276
|
workspace,
|
|
269
277
|
releaseEntry,
|
|
270
278
|
newTag,
|
|
@@ -272,9 +280,10 @@ function executeWorkspaceRelease(args) {
|
|
|
272
280
|
isPropagationOnly,
|
|
273
281
|
isEmptyRange,
|
|
274
282
|
config,
|
|
275
|
-
dryRun,
|
|
276
283
|
today,
|
|
277
284
|
modifiedFiles,
|
|
285
|
+
writes,
|
|
286
|
+
warnings,
|
|
278
287
|
previewOptions,
|
|
279
288
|
overrideContext,
|
|
280
289
|
sectionOrder,
|
|
@@ -286,8 +295,9 @@ function executeWorkspaceRelease(args) {
|
|
|
286
295
|
currentVersion: bump.currentVersion,
|
|
287
296
|
newVersion: bump.newVersion,
|
|
288
297
|
tag: newTag,
|
|
289
|
-
bumpedFiles: bump.
|
|
298
|
+
bumpedFiles: bump.writes.map((write) => write.path),
|
|
290
299
|
changelogFiles,
|
|
300
|
+
...(previewFiles.length > 0 && { previewFiles }),
|
|
291
301
|
};
|
|
292
302
|
attachReleasedWorkspaceOptionals(released, {
|
|
293
303
|
previousTag: directResult?.tag ?? previousTags.get(dir),
|
|
@@ -328,7 +338,7 @@ function attachReleasedWorkspaceOptionals(released, args) {
|
|
|
328
338
|
}
|
|
329
339
|
}
|
|
330
340
|
function generateWorkspaceChangelogs(args) {
|
|
331
|
-
const { workspace, releaseEntry, newTag, newVersion, isPropagationOnly, isEmptyRange, config,
|
|
341
|
+
const { workspace, releaseEntry, newTag, newVersion, isPropagationOnly, isEmptyRange, config, today, modifiedFiles, writes, warnings, previewOptions, overrideContext, sectionOrder, } = args;
|
|
332
342
|
const newEntries = buildWorkspaceEntries({
|
|
333
343
|
workspace,
|
|
334
344
|
releaseEntry,
|
|
@@ -341,26 +351,22 @@ function generateWorkspaceChangelogs(args) {
|
|
|
341
351
|
});
|
|
342
352
|
const applied = applyWorkspaceOverrides(newEntries, workspace.workspacePath, overrideContext);
|
|
343
353
|
const changelogFiles = [];
|
|
344
|
-
let
|
|
354
|
+
let firstMergedEntries;
|
|
345
355
|
for (const changelogPath of workspace.changelogPaths) {
|
|
346
356
|
const jsonPath = resolveChangelogJsonPath(config, changelogPath);
|
|
347
|
-
const
|
|
348
|
-
const mergedEntries = shouldWriteJson
|
|
349
|
-
? upsertChangelogJsonAndReturn(jsonPath, applied.entries)
|
|
350
|
-
: mergeChangelogEntriesWithDisk(jsonPath, applied.entries);
|
|
357
|
+
const mergedEntries = mergeChangelogEntriesWithDisk(jsonPath, applied.entries);
|
|
351
358
|
if (config.changelogJson.enabled) {
|
|
359
|
+
writes.push({ path: jsonPath, content: renderChangelogJson(mergedEntries) });
|
|
352
360
|
modifiedFiles.push(jsonPath);
|
|
353
|
-
|
|
361
|
+
firstMergedEntries ??= mergedEntries;
|
|
354
362
|
}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
sectionOrder,
|
|
359
|
-
dryRun,
|
|
360
|
-
}));
|
|
363
|
+
const changelogFile = joinPath(changelogPath, 'CHANGELOG.md');
|
|
364
|
+
writes.push({ path: changelogFile, content: renderChangelogMarkdown(mergedEntries, { sectionOrder }) });
|
|
365
|
+
changelogFiles.push(changelogFile);
|
|
361
366
|
}
|
|
362
|
-
|
|
363
|
-
|
|
367
|
+
const previews = planPreviews(workspace, newTag, firstMergedEntries, previewOptions, warnings);
|
|
368
|
+
writes.push(...previews);
|
|
369
|
+
return { changelogFiles, previewFiles: previews.map((write) => write.path) };
|
|
364
370
|
}
|
|
365
371
|
function buildWorkspaceEntries(args) {
|
|
366
372
|
const { workspace, releaseEntry, newTag, newVersion, isPropagationOnly, isEmptyRange, config, today } = args;
|
|
@@ -373,35 +379,25 @@ function buildWorkspaceEntries(args) {
|
|
|
373
379
|
const tagPattern = buildTagPattern(getAllTagPrefixes(workspace));
|
|
374
380
|
return buildChangelogEntries(config, newTag, { tagPattern, includePaths: workspace.paths });
|
|
375
381
|
}
|
|
376
|
-
function
|
|
377
|
-
if (!previewOptions.enabled ||
|
|
378
|
-
return;
|
|
382
|
+
function planPreviews(workspace, newTag, entries, previewOptions, warnings) {
|
|
383
|
+
if (!previewOptions.enabled || entries === undefined) {
|
|
384
|
+
return [];
|
|
379
385
|
}
|
|
380
|
-
|
|
386
|
+
const previews = planReleaseNotesPreviews({
|
|
381
387
|
workspacePath: workspace.workspacePath,
|
|
382
388
|
tag: newTag,
|
|
383
|
-
|
|
389
|
+
entries,
|
|
384
390
|
sectionOrder: previewOptions.sectionOrder,
|
|
385
|
-
dryRun,
|
|
386
391
|
});
|
|
392
|
+
warnings.push(...previews.warnings);
|
|
393
|
+
return previews.writes;
|
|
387
394
|
}
|
|
388
|
-
function
|
|
395
|
+
function planFormatCommand(config, tags, modifiedFiles) {
|
|
389
396
|
const formatCommandStr = config.formatCommand ?? (hasPrettierConfig() ? 'npx prettier --write' : undefined);
|
|
390
397
|
if (tags.length === 0 || formatCommandStr === undefined) {
|
|
391
398
|
return undefined;
|
|
392
399
|
}
|
|
393
|
-
|
|
394
|
-
if (dryRun) {
|
|
395
|
-
return { command: fullCommand, executed: false, files: modifiedFiles };
|
|
396
|
-
}
|
|
397
|
-
try {
|
|
398
|
-
execSync(fullCommand, { stdio: 'inherit' });
|
|
399
|
-
}
|
|
400
|
-
catch (error) {
|
|
401
|
-
const baseMessage = error instanceof Error ? error.message : String(error);
|
|
402
|
-
throw new Error(`format stage: ${baseMessage} (command: '${fullCommand}')`, { cause: error });
|
|
403
|
-
}
|
|
404
|
-
return { command: fullCommand, executed: true, files: modifiedFiles };
|
|
400
|
+
return { command: `${formatCommandStr} ${modifiedFiles.join(' ')}`, files: modifiedFiles };
|
|
405
401
|
}
|
|
406
402
|
function findWorkspace(workspaces, dir) {
|
|
407
403
|
return workspaces.find((w) => w.dir === dir);
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
import type { PlannedWrite } from './releasePlan.js';
|
|
1
2
|
import type { ReleasePrepareOptions } from './releasePrepare.js';
|
|
2
3
|
import type { ChangelogOverride, MonorepoReleaseConfig, ProjectPrepareResult } from './types.js';
|
|
3
4
|
export interface ReleasePrepareProjectArgs {
|
|
4
5
|
config: MonorepoReleaseConfig;
|
|
5
6
|
options: ReleasePrepareOptions;
|
|
6
7
|
modifiedFiles: string[];
|
|
8
|
+
writes: PlannedWrite[];
|
|
7
9
|
tags: string[];
|
|
10
|
+
warnings?: string[];
|
|
8
11
|
rootOverrides?: Map<string, ChangelogOverride>;
|
|
9
12
|
overrideWarnings?: string[];
|
|
10
13
|
globalMatchedRootKeys?: Set<string>;
|
|
@@ -1,22 +1,23 @@
|
|
|
1
|
+
import { join as joinPath } from 'node:path';
|
|
1
2
|
import { buildChangelogEntries } from "./buildChangelogEntries.js";
|
|
2
3
|
import { buildEmptyReleaseEntry } from "./buildEmptyReleaseEntry.js";
|
|
3
|
-
import {
|
|
4
|
-
import { mergeChangelogEntriesWithDisk, resolveChangelogJsonPath, writeChangelogJson } from "./changelogJsonFile.js";
|
|
4
|
+
import { mergeChangelogEntriesWithDisk, renderChangelogJson, resolveChangelogJsonPath } from "./changelogJsonFile.js";
|
|
5
5
|
import { applyChangelogOverrides } from "./changelogOverrides.js";
|
|
6
6
|
import { createPolicyViolationCollector } from "./collectPolicyViolations.js";
|
|
7
7
|
import { decideRelease } from "./decideRelease.js";
|
|
8
8
|
import { DEFAULT_BREAKING_POLICIES, DEFAULT_VERSION_PATTERNS, DEFAULT_WORK_TYPES } from "./defaults.js";
|
|
9
9
|
import { buildTagPattern } from "./generateChangelogs.js";
|
|
10
10
|
import { getCommitsSinceTarget } from "./getCommitsSinceTarget.js";
|
|
11
|
-
import {
|
|
11
|
+
import { planReleaseNotesPreviews } from "./planReleaseNotesPreviews.js";
|
|
12
|
+
import { planVersionBump } from "./planVersionBump.js";
|
|
13
|
+
import { renderChangelogMarkdown } from "./renderChangelogMarkdown.js";
|
|
12
14
|
import { deriveSectionOrder } from "./resolveReleaseNotesConfig.js";
|
|
13
|
-
import { writeReleaseNotesPreviews } from "./writeReleaseNotesPreviews.js";
|
|
14
15
|
const ROOT_PACKAGE_FILE = './package.json';
|
|
15
16
|
const ROOT_CHANGELOG_PATH = '.';
|
|
16
17
|
export function releasePrepareProject(args) {
|
|
17
|
-
const { config, options, modifiedFiles, tags } = args;
|
|
18
|
-
const { rootOverrides, overrideWarnings, globalMatchedRootKeys } = resolveOptionalOverrideArgs(args);
|
|
19
|
-
const {
|
|
18
|
+
const { config, options, modifiedFiles, writes, tags } = args;
|
|
19
|
+
const { rootOverrides, overrideWarnings, globalMatchedRootKeys, warnings } = resolveOptionalOverrideArgs(args);
|
|
20
|
+
const { bumpOverride, withReleaseNotes, force } = options;
|
|
20
21
|
const project = config.project;
|
|
21
22
|
if (project === undefined) {
|
|
22
23
|
throw new Error('releasePrepareProject called without a configured project block');
|
|
@@ -62,30 +63,33 @@ export function releasePrepareProject(args) {
|
|
|
62
63
|
return skipped;
|
|
63
64
|
}
|
|
64
65
|
const { releaseType, parsedCommitCount, unparseableCommits } = decision;
|
|
65
|
-
const bump =
|
|
66
|
+
const bump = planVersionBump([ROOT_PACKAGE_FILE], releaseType);
|
|
67
|
+
writes.push(...bump.writes);
|
|
66
68
|
const newTag = `${project.tagPrefix}${bump.newVersion}`;
|
|
67
|
-
const
|
|
69
|
+
const changelogs = planProjectChangelogs({
|
|
68
70
|
config,
|
|
69
71
|
project,
|
|
70
72
|
commits,
|
|
71
73
|
contributingPaths,
|
|
72
74
|
newTag,
|
|
73
75
|
newVersion: bump.newVersion,
|
|
74
|
-
dryRun,
|
|
75
76
|
rootOverrides,
|
|
76
77
|
overrideWarnings,
|
|
77
78
|
globalMatchedRootKeys,
|
|
78
79
|
});
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
const { changelogFiles, changelogJsonFiles } = changelogs;
|
|
81
|
+
writes.push(...changelogs.writes);
|
|
82
|
+
const previewFiles = [];
|
|
83
|
+
if (withReleaseNotes === true && config.changelogJson.enabled && changelogJsonFiles.length > 0) {
|
|
84
|
+
const previews = planReleaseNotesPreviews({
|
|
83
85
|
workspacePath: ROOT_CHANGELOG_PATH,
|
|
84
86
|
tag: newTag,
|
|
85
|
-
|
|
86
|
-
sectionOrder,
|
|
87
|
-
dryRun,
|
|
87
|
+
entries: changelogs.entries,
|
|
88
|
+
sectionOrder: deriveSectionOrder(workTypes),
|
|
88
89
|
});
|
|
90
|
+
writes.push(...previews.writes);
|
|
91
|
+
warnings.push(...previews.warnings);
|
|
92
|
+
previewFiles.push(...previews.writes.map((write) => write.path));
|
|
89
93
|
}
|
|
90
94
|
tags.push(newTag);
|
|
91
95
|
modifiedFiles.push(ROOT_PACKAGE_FILE, ...changelogFiles, ...changelogJsonFiles);
|
|
@@ -97,10 +101,13 @@ export function releasePrepareProject(args) {
|
|
|
97
101
|
currentVersion: bump.currentVersion,
|
|
98
102
|
newVersion: bump.newVersion,
|
|
99
103
|
tag: newTag,
|
|
100
|
-
bumpedFiles: bump.
|
|
104
|
+
bumpedFiles: bump.writes.map((write) => write.path),
|
|
101
105
|
changelogFiles,
|
|
102
106
|
commits,
|
|
103
107
|
};
|
|
108
|
+
if (previewFiles.length > 0) {
|
|
109
|
+
result.previewFiles = previewFiles;
|
|
110
|
+
}
|
|
104
111
|
if (tag !== undefined) {
|
|
105
112
|
result.previousTag = tag;
|
|
106
113
|
}
|
|
@@ -120,10 +127,11 @@ function resolveOptionalOverrideArgs(args) {
|
|
|
120
127
|
rootOverrides: args.rootOverrides ?? new Map(),
|
|
121
128
|
overrideWarnings: args.overrideWarnings ?? [],
|
|
122
129
|
globalMatchedRootKeys: args.globalMatchedRootKeys ?? new Set(),
|
|
130
|
+
warnings: args.warnings ?? [],
|
|
123
131
|
};
|
|
124
132
|
}
|
|
125
|
-
function
|
|
126
|
-
const { config, project, commits, contributingPaths, newTag, newVersion,
|
|
133
|
+
function planProjectChangelogs(args) {
|
|
134
|
+
const { config, project, commits, contributingPaths, newTag, newVersion, rootOverrides, overrideWarnings, globalMatchedRootKeys, } = args;
|
|
127
135
|
const isEmptyRange = commits.length === 0;
|
|
128
136
|
const today = new Date().toISOString().slice(0, 10);
|
|
129
137
|
const tagPattern = buildTagPattern([project.tagPrefix]);
|
|
@@ -143,25 +151,13 @@ function writeProjectChangelogs(args) {
|
|
|
143
151
|
const renderEntries = isEmptyRange
|
|
144
152
|
? mergeChangelogEntriesWithDisk(changelogJsonPath, applied.entries)
|
|
145
153
|
: applied.entries;
|
|
146
|
-
|
|
147
|
-
if (isEmptyRange) {
|
|
148
|
-
writeChangelogJson(changelogJsonPath, renderEntries);
|
|
149
|
-
}
|
|
150
|
-
else {
|
|
151
|
-
writeChangelogJson(changelogJsonPath, applied.entries);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
const changelogFiles = [
|
|
155
|
-
writeChangelogMarkdown({
|
|
156
|
-
changelogPath: ROOT_CHANGELOG_PATH,
|
|
157
|
-
entries: renderEntries,
|
|
158
|
-
sectionOrder,
|
|
159
|
-
dryRun,
|
|
160
|
-
}),
|
|
161
|
-
];
|
|
154
|
+
const writes = [];
|
|
162
155
|
const changelogJsonFiles = [];
|
|
163
156
|
if (config.changelogJson.enabled) {
|
|
157
|
+
writes.push({ path: changelogJsonPath, content: renderChangelogJson(renderEntries) });
|
|
164
158
|
changelogJsonFiles.push(changelogJsonPath);
|
|
165
159
|
}
|
|
166
|
-
|
|
160
|
+
const changelogFile = joinPath(ROOT_CHANGELOG_PATH, 'CHANGELOG.md');
|
|
161
|
+
writes.push({ path: changelogFile, content: renderChangelogMarkdown(renderEntries, { sectionOrder }) });
|
|
162
|
+
return { changelogFiles: [changelogFile], changelogJsonFiles, entries: renderEntries, writes };
|
|
167
163
|
}
|
|
@@ -3,10 +3,3 @@ export interface RenderChangelogMarkdownOptions {
|
|
|
3
3
|
sectionOrder?: string[];
|
|
4
4
|
}
|
|
5
5
|
export declare function renderChangelogMarkdown(entries: ChangelogEntry[], options?: RenderChangelogMarkdownOptions): string;
|
|
6
|
-
export interface WriteChangelogMarkdownParams {
|
|
7
|
-
changelogPath: string;
|
|
8
|
-
entries: ChangelogEntry[];
|
|
9
|
-
sectionOrder?: string[];
|
|
10
|
-
dryRun?: boolean;
|
|
11
|
-
}
|
|
12
|
-
export declare function writeChangelogMarkdown(params: WriteChangelogMarkdownParams): string;
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
-
import { dirname, join as joinPath } from 'node:path';
|
|
3
1
|
import { renderReleaseNotesMulti } from "./renderReleaseNotes.js";
|
|
4
2
|
const CHANGELOG_HEADER = `# Changelog
|
|
5
3
|
|
|
@@ -15,14 +13,3 @@ export function renderChangelogMarkdown(entries, options) {
|
|
|
15
13
|
parts.push(CHANGELOG_FOOTER);
|
|
16
14
|
return parts.join('\n\n') + '\n';
|
|
17
15
|
}
|
|
18
|
-
export function writeChangelogMarkdown(params) {
|
|
19
|
-
const { changelogPath, entries, sectionOrder, dryRun = false } = params;
|
|
20
|
-
const filePath = joinPath(changelogPath, 'CHANGELOG.md');
|
|
21
|
-
if (dryRun) {
|
|
22
|
-
return filePath;
|
|
23
|
-
}
|
|
24
|
-
const rendered = renderChangelogMarkdown(entries, sectionOrder !== undefined ? { sectionOrder } : undefined);
|
|
25
|
-
mkdirSync(dirname(filePath), { recursive: true });
|
|
26
|
-
writeFileSync(filePath, rendered, 'utf8');
|
|
27
|
-
return filePath;
|
|
28
|
-
}
|
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
import type { PrepareResult } from './types.js';
|
|
2
|
-
export
|
|
2
|
+
export interface ReportPrepareOptions {
|
|
3
|
+
applied: boolean;
|
|
4
|
+
formatError?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function reportPrepare(plan: PrepareResult, options: ReportPrepareOptions): string;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { bold, dim, sectionHeader } from "./format.js";
|
|
2
|
-
export function reportPrepare(
|
|
3
|
-
const isMultiWorkspace =
|
|
2
|
+
export function reportPrepare(plan, options) {
|
|
3
|
+
const isMultiWorkspace = plan.workspaces.some((w) => w.name !== undefined) || plan.project !== undefined;
|
|
4
4
|
if (isMultiWorkspace) {
|
|
5
|
-
return formatMultiWorkspace(
|
|
5
|
+
return formatMultiWorkspace(plan, options);
|
|
6
6
|
}
|
|
7
|
-
return formatSingleWorkspace(
|
|
7
|
+
return formatSingleWorkspace(plan, options);
|
|
8
8
|
}
|
|
9
|
-
function formatSingleWorkspace(result) {
|
|
9
|
+
function formatSingleWorkspace(result, options) {
|
|
10
|
+
const dryRun = !options.applied;
|
|
10
11
|
const lines = [];
|
|
11
12
|
const workspace = result.workspaces[0];
|
|
12
13
|
if (workspace === undefined) {
|
|
@@ -41,22 +42,25 @@ function formatSingleWorkspace(result) {
|
|
|
41
42
|
else if (workspace.releaseType !== undefined) {
|
|
42
43
|
lines.push(`📦 ${workspace.currentVersion} → ${bold(workspace.newVersion)} (${workspace.releaseType})`);
|
|
43
44
|
}
|
|
44
|
-
formatBumpFiles(lines, workspace,
|
|
45
|
+
formatBumpFiles(lines, workspace, dryRun);
|
|
45
46
|
lines.push(dim('Generating changelogs...'));
|
|
46
|
-
formatChangelogFiles(lines, workspace,
|
|
47
|
-
|
|
47
|
+
formatChangelogFiles(lines, workspace, dryRun);
|
|
48
|
+
formatPreviewFiles(lines, workspace, dryRun);
|
|
49
|
+
formatFormatCommand(lines, result, options);
|
|
50
|
+
formatWarnings(lines, result);
|
|
48
51
|
lines.push(`✅ Release preparation complete.`, ` 🏷️ ${bold(workspace.tag)}`);
|
|
49
52
|
return lines.join('\n');
|
|
50
53
|
}
|
|
51
|
-
function formatMultiWorkspace(result) {
|
|
54
|
+
function formatMultiWorkspace(result, options) {
|
|
55
|
+
const dryRun = !options.applied;
|
|
52
56
|
const lines = [];
|
|
53
57
|
for (const workspace of result.workspaces) {
|
|
54
|
-
formatWorkspaceSection(lines, workspace,
|
|
58
|
+
formatWorkspaceSection(lines, workspace, dryRun);
|
|
55
59
|
}
|
|
56
60
|
if (result.project !== undefined) {
|
|
57
|
-
formatProjectSection(lines, result.project,
|
|
61
|
+
formatProjectSection(lines, result.project, dryRun);
|
|
58
62
|
}
|
|
59
|
-
formatFormatCommand(lines, result);
|
|
63
|
+
formatFormatCommand(lines, result, options);
|
|
60
64
|
formatWarnings(lines, result);
|
|
61
65
|
if (result.tags.length > 0) {
|
|
62
66
|
lines.push(`\n✅ Release preparation complete.`);
|
|
@@ -104,6 +108,7 @@ function formatProjectSection(lines, project, dryRun) {
|
|
|
104
108
|
lines.push(dim(` Generating changelog: ${file}`));
|
|
105
109
|
}
|
|
106
110
|
}
|
|
111
|
+
formatPreviewFiles(lines, project, dryRun, ' ');
|
|
107
112
|
lines.push(` 🏷️ ${bold(tag)}`);
|
|
108
113
|
}
|
|
109
114
|
function formatProjectUnparseable(lines, project) {
|
|
@@ -141,6 +146,7 @@ function formatWorkspaceSection(lines, workspace, dryRun) {
|
|
|
141
146
|
formatBumpFiles(lines, workspace, dryRun, ' ');
|
|
142
147
|
lines.push(dim(' Generating changelogs...'));
|
|
143
148
|
formatChangelogFiles(lines, workspace, dryRun, ' ');
|
|
149
|
+
formatPreviewFiles(lines, workspace, dryRun, ' ');
|
|
144
150
|
lines.push(` 🏷️ ${bold(workspace.tag)}`);
|
|
145
151
|
}
|
|
146
152
|
function formatCommitSummary(lines, workspace, propagatedFrom, isPropagatedOnly) {
|
|
@@ -195,6 +201,16 @@ function formatChangelogFiles(lines, workspace, dryRun, indent = '') {
|
|
|
195
201
|
}
|
|
196
202
|
}
|
|
197
203
|
}
|
|
204
|
+
function formatPreviewFiles(lines, release, dryRun, indent = '') {
|
|
205
|
+
for (const file of release.previewFiles ?? []) {
|
|
206
|
+
if (dryRun) {
|
|
207
|
+
lines.push(dim(`${indent} [dry-run] Would write ${file}`));
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
lines.push(dim(`${indent} Wrote ${file}`));
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
198
214
|
function formatUnparseableWarning(lines, workspace, indent = '') {
|
|
199
215
|
const unparseable = workspace.unparseableCommits;
|
|
200
216
|
if (unparseable === undefined || unparseable.length === 0) {
|
|
@@ -240,14 +256,17 @@ function formatWarnings(lines, result) {
|
|
|
240
256
|
lines.push(`⚠️ ${warning}`);
|
|
241
257
|
}
|
|
242
258
|
}
|
|
243
|
-
function formatFormatCommand(lines, result) {
|
|
259
|
+
function formatFormatCommand(lines, result, options) {
|
|
244
260
|
if (result.formatCommand === undefined) {
|
|
245
261
|
return;
|
|
246
262
|
}
|
|
247
|
-
if (
|
|
248
|
-
lines.push(dim(`\n Running format command: ${result.formatCommand.command}`));
|
|
249
|
-
}
|
|
250
|
-
else {
|
|
263
|
+
if (!options.applied) {
|
|
251
264
|
lines.push(dim(`\n [dry-run] Would run format command: ${result.formatCommand.command}`));
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
if (options.formatError === undefined) {
|
|
268
|
+
lines.push(dim(`\n Running format command: ${result.formatCommand.command}`));
|
|
269
|
+
return;
|
|
252
270
|
}
|
|
271
|
+
lines.push(`\n ⚠️ Format command failed: ${result.formatCommand.command}`, ` ${options.formatError}`);
|
|
253
272
|
}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import { GIT_OUTPUT_LIMIT } from '@williamthorsen/nmr-core';
|
|
2
3
|
const VERSION_PATTERN = /^v\d+\.\d+\.\d+/;
|
|
3
4
|
const SEMVER_SUFFIX_PATTERN = /^\d+\.\d+\.\d+/;
|
|
4
5
|
export function resolveReleaseTags(args) {
|
|
5
|
-
const output = execFileSync('git', ['tag', '--points-at', 'HEAD'], {
|
|
6
|
+
const output = execFileSync('git', ['tag', '--points-at', 'HEAD'], {
|
|
7
|
+
encoding: 'utf8',
|
|
8
|
+
maxBuffer: GIT_OUTPUT_LIMIT,
|
|
9
|
+
});
|
|
6
10
|
const tags = output
|
|
7
11
|
.split('\n')
|
|
8
12
|
.map((line) => line.trim())
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export declare function runGitCliff(cliffConfigPath: string, cliffArgs: readonly string[], stdio: StdioOptions): string;
|
|
1
|
+
export declare function runGitCliff(cliffConfigPath: string, cliffArgs: readonly string[]): string;
|
|
3
2
|
export declare function refreshGitCliffCache(): void;
|
package/dist/esm/runGitCliff.js
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
import { execFileSync } from 'node:child_process';
|
|
2
|
-
import { copyFileSync, mkdtempSync, rmSync } from 'node:fs';
|
|
2
|
+
import { copyFileSync, mkdtempSync, readFileSync, rmSync } from 'node:fs';
|
|
3
3
|
import { tmpdir } from 'node:os';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
import { GIT_OUTPUT_LIMIT } from '@williamthorsen/nmr-core';
|
|
6
|
+
export function runGitCliff(cliffConfigPath, cliffArgs) {
|
|
7
|
+
const tempDir = mkdtempSync(join(tmpdir(), 'cliff-'));
|
|
8
8
|
try {
|
|
9
|
+
let configPath = cliffConfigPath;
|
|
9
10
|
if (cliffConfigPath.endsWith('.template')) {
|
|
10
|
-
tempDir = mkdtempSync(join(tmpdir(), 'cliff-'));
|
|
11
11
|
configPath = join(tempDir, 'cliff.toml');
|
|
12
12
|
copyFileSync(cliffConfigPath, configPath);
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
stdio,
|
|
14
|
+
const outputPath = join(tempDir, 'output.json');
|
|
15
|
+
execFileSync('npx', ['--prefer-offline', '--yes', 'git-cliff', '--config', configPath, ...cliffArgs, '--output', outputPath], {
|
|
16
|
+
stdio: ['ignore', 'ignore', 'inherit'],
|
|
17
17
|
env: { ...process.env, npm_config_progress: 'false' },
|
|
18
18
|
});
|
|
19
|
+
return readFileSync(outputPath, 'utf8');
|
|
19
20
|
}
|
|
20
21
|
finally {
|
|
21
|
-
|
|
22
|
-
rmSync(tempDir, { recursive: true, force: true });
|
|
23
|
-
}
|
|
22
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
24
23
|
}
|
|
25
24
|
}
|
|
26
25
|
export function refreshGitCliffCache() {
|
|
27
26
|
execFileSync('npx', ['--yes', 'git-cliff', '--version'], {
|
|
27
|
+
maxBuffer: GIT_OUTPUT_LIMIT,
|
|
28
28
|
stdio: ['ignore', 'pipe', 'inherit'],
|
|
29
29
|
env: { ...process.env, npm_config_progress: 'false' },
|
|
30
30
|
});
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { execSync } from 'node:child_process';
|
|
2
2
|
import { existsSync } from 'node:fs';
|
|
3
|
-
import { reportError } from '@williamthorsen/nmr-core';
|
|
3
|
+
import { GIT_OUTPUT_LIMIT, reportError } from '@williamthorsen/nmr-core';
|
|
4
4
|
import { checkRetiredSyncLabelsConfig } from "./retiredConfig.js";
|
|
5
5
|
const WORKFLOW_FILE = '.github/workflows/sync-labels.yaml';
|
|
6
6
|
function checkGhAvailable() {
|
|
7
7
|
try {
|
|
8
|
-
execSync('gh --version', { stdio: 'pipe' });
|
|
8
|
+
execSync('gh --version', { maxBuffer: GIT_OUTPUT_LIMIT, stdio: 'pipe' });
|
|
9
9
|
return true;
|
|
10
10
|
}
|
|
11
11
|
catch {
|