@williamthorsen/release-kit 10.7.0 → 10.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.meta/changelog.json +71 -3
- package/.readyup/kits/default.js +3 -3
- package/.readyup/kits/npm-auto-publish.js +1 -1
- package/.readyup/manifest.json +9 -9
- package/CHANGELOG.md +49 -3
- package/README.md +21 -15
- package/dist/esm/bin/release-kit.js +20 -102
- package/dist/esm/buildChangelogEntries.d.ts +1 -1
- package/dist/esm/buildChangelogEntries.js +14 -5
- package/dist/esm/createGithubReleaseCommand.d.ts +2 -1
- package/dist/esm/createGithubReleaseCommand.js +4 -2
- package/dist/esm/createTags.d.ts +2 -0
- package/dist/esm/createTags.js +5 -4
- package/dist/esm/format.d.ts +5 -5
- package/dist/esm/format.js +5 -4
- package/dist/esm/glyphs.d.ts +3 -0
- package/dist/esm/glyphs.js +6 -0
- package/dist/esm/init/initCommand.d.ts +3 -1
- package/dist/esm/init/initCommand.js +15 -15
- package/dist/esm/loadValidatedConfig.d.ts +2 -1
- package/dist/esm/loadValidatedConfig.js +3 -3
- package/dist/esm/parseCommitMessage.d.ts +4 -5
- package/dist/esm/prepareCommand.d.ts +2 -1
- package/dist/esm/prepareCommand.js +17 -16
- package/dist/esm/publishCommand.d.ts +2 -1
- package/dist/esm/publishCommand.js +2 -2
- package/dist/esm/reportPrepare.d.ts +2 -0
- package/dist/esm/reportPrepare.js +44 -38
- package/dist/esm/resolveReleaseNotesConfig.d.ts +2 -1
- package/dist/esm/resolveReleaseNotesConfig.js +4 -4
- package/dist/esm/resolveStylesOrExit.d.ts +10 -0
- package/dist/esm/resolveStylesOrExit.js +10 -0
- package/dist/esm/showTagPrefixesCommand.d.ts +2 -1
- package/dist/esm/showTagPrefixesCommand.js +16 -10
- package/dist/esm/sync-labels/generateCommand.d.ts +4 -2
- package/dist/esm/sync-labels/generateCommand.js +4 -4
- package/dist/esm/sync-labels/initCommand.d.ts +3 -1
- package/dist/esm/sync-labels/initCommand.js +7 -7
- package/dist/esm/tagCommand.d.ts +2 -1
- package/dist/esm/tagCommand.js +2 -2
- package/dist/esm/types.d.ts +8 -7
- package/dist/esm/validateOverridesCommand.d.ts +4 -4
- package/dist/esm/validateOverridesCommand.js +6 -6
- package/dist/esm/workTypesData.d.ts +10 -9
- package/dist/esm/workTypesData.js +97 -11
- package/docs/changelogs.md +8 -8
- package/docs/configuration.md +23 -1
- package/docs/work-types.md +28 -30
- package/package.json +11 -11
- package/presets/labels/common.yaml +2 -2
- package/dist/esm/checkWorkTypesDrift.d.ts +0 -36
- package/dist/esm/checkWorkTypesDrift.js +0 -117
- package/dist/esm/syncWorkTypes.d.ts +0 -28
- package/dist/esm/syncWorkTypes.js +0 -94
- package/dist/esm/work-types.json +0 -133
- package/dist/esm/work-types.schema.json +0 -100
- package/dist/esm/workTypesUtils.d.ts +0 -22
- package/dist/esm/workTypesUtils.js +0 -16
|
@@ -9,7 +9,7 @@ const createGithubReleaseFlagSchema = {
|
|
|
9
9
|
dryRun: { long: '--dry-run', type: 'boolean' },
|
|
10
10
|
tags: { long: '--tags', type: 'string' },
|
|
11
11
|
};
|
|
12
|
-
export async function createGithubReleaseCommand(argv) {
|
|
12
|
+
export async function createGithubReleaseCommand(argv, styles) {
|
|
13
13
|
const parsed = parseArgsOrExit(argv, createGithubReleaseFlagSchema);
|
|
14
14
|
const { dryRun } = parsed.flags;
|
|
15
15
|
const requestedTags = parseRequestedTags(parsed.flags.tags);
|
|
@@ -23,7 +23,9 @@ export async function createGithubReleaseCommand(argv) {
|
|
|
23
23
|
if (publishableTags.length === 0) {
|
|
24
24
|
return;
|
|
25
25
|
}
|
|
26
|
-
const { changelogJsonOutputPath, sectionOrder } = await resolveReleaseNotesConfig({
|
|
26
|
+
const { changelogJsonOutputPath, sectionOrder } = await resolveReleaseNotesConfig(styles.stderr, {
|
|
27
|
+
strictLoad: true,
|
|
28
|
+
});
|
|
27
29
|
let outcome;
|
|
28
30
|
try {
|
|
29
31
|
outcome = createGithubReleases(publishableTags, changelogJsonOutputPath, dryRun, sectionOrder);
|
package/dist/esm/createTags.d.ts
CHANGED
package/dist/esm/createTags.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { execFileSync } from 'node:child_process';
|
|
2
|
-
import { GIT_OUTPUT_LIMIT, hasErrnoCode } from '@williamthorsen/nmr-core';
|
|
2
|
+
import { formatGlyphLine, GIT_OUTPUT_LIMIT, hasErrnoCode } from '@williamthorsen/nmr-core';
|
|
3
3
|
import { deleteFileIfExists } from "./deleteFileIfExists.js";
|
|
4
|
+
import { RELEASE_GLYPHS } from "./glyphs.js";
|
|
4
5
|
import { readReleaseTags, RELEASE_SUMMARY_FILE, RELEASE_TAGS_FILE } from "./releaseFiles.js";
|
|
5
6
|
export function createTags(options) {
|
|
6
|
-
const { dryRun, noGitChecks } = options;
|
|
7
|
+
const { dryRun, noGitChecks, style } = options;
|
|
7
8
|
const tags = readReleaseTags();
|
|
8
9
|
if (tags.length === 0) {
|
|
9
10
|
return [];
|
|
@@ -14,7 +15,7 @@ export function createTags(options) {
|
|
|
14
15
|
if (dryRun) {
|
|
15
16
|
console.info('[dry-run] Would create tags:');
|
|
16
17
|
for (const tag of tags) {
|
|
17
|
-
console.info(
|
|
18
|
+
console.info(formatGlyphLine(RELEASE_GLYPHS, style, 'tag', tag));
|
|
18
19
|
}
|
|
19
20
|
return tags;
|
|
20
21
|
}
|
|
@@ -36,7 +37,7 @@ export function createTags(options) {
|
|
|
36
37
|
}
|
|
37
38
|
console.info('Created tags:');
|
|
38
39
|
for (const tag of tags) {
|
|
39
|
-
console.info(
|
|
40
|
+
console.info(formatGlyphLine(RELEASE_GLYPHS, style, 'tag', tag));
|
|
40
41
|
}
|
|
41
42
|
deleteFileIfExists(RELEASE_TAGS_FILE);
|
|
42
43
|
deleteFileIfExists(RELEASE_SUMMARY_FILE);
|
package/dist/esm/format.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/**
|
|
2
|
-
export declare function bold(text: string): string;
|
|
3
|
-
/**
|
|
4
|
-
export declare function dim(text: string): string;
|
|
5
|
-
/**
|
|
1
|
+
/** Styles text bold, returning it unstyled for a stream that cannot render color. */
|
|
2
|
+
export declare function bold(text: string, stream?: NodeJS.WritableStream): string;
|
|
3
|
+
/** Styles text dim, returning it unstyled for a stream that cannot render color. */
|
|
4
|
+
export declare function dim(text: string, stream?: NodeJS.WritableStream): string;
|
|
5
|
+
/** Renders a section header for separating workspaces in CLI output. */
|
|
6
6
|
export declare function sectionHeader(name: string): string;
|
package/dist/esm/format.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { styleText } from 'node:util';
|
|
2
|
+
export function bold(text, stream = process.stdout) {
|
|
3
|
+
return styleText('bold', text, { stream });
|
|
3
4
|
}
|
|
4
|
-
export function dim(text) {
|
|
5
|
-
return
|
|
5
|
+
export function dim(text, stream = process.stdout) {
|
|
6
|
+
return styleText('dim', text, { stream });
|
|
6
7
|
}
|
|
7
8
|
export function sectionHeader(name) {
|
|
8
9
|
return `━━━ ${name} ━━━`;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/** Glyphs that name no status; a status marker comes from nmr-core's `STATUS_GLYPHS`. */
|
|
2
|
+
export declare const RELEASE_GLYPHS: Readonly<Record<"plain" | "rich", Readonly<Record<"bump" | "dryRun" | "tag", import("@williamthorsen/toolbelt.terminal/candidate").Glyph>>>>;
|
|
3
|
+
export type ReleaseGlyphName = keyof (typeof RELEASE_GLYPHS)['rich'];
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { type StreamStyles } from '@williamthorsen/nmr-core';
|
|
1
2
|
interface InitOptions {
|
|
2
3
|
dryRun: boolean;
|
|
3
4
|
force: boolean;
|
|
5
|
+
styles: StreamStyles;
|
|
4
6
|
withConfig: boolean;
|
|
5
7
|
}
|
|
6
8
|
/**
|
|
@@ -9,5 +11,5 @@ interface InitOptions {
|
|
|
9
11
|
* Checks eligibility, detects repo type, scaffolds files, and prints next steps.
|
|
10
12
|
* Returns the process exit code (0 for success, 1 for failure).
|
|
11
13
|
*/
|
|
12
|
-
export declare function initCommand({ dryRun, force, withConfig }: InitOptions): number;
|
|
14
|
+
export declare function initCommand({ dryRun, force, styles, withConfig }: InitOptions): number;
|
|
13
15
|
export {};
|
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
import { printError, printStep, printSuccess, reportWriteResult } from '@williamthorsen/nmr-core';
|
|
1
|
+
import { printError, printStep, printSuccess, reportWriteResult, } from '@williamthorsen/nmr-core';
|
|
2
2
|
import { describeError } from '@williamthorsen/toolbelt.errors';
|
|
3
3
|
import { hasPackageJson, isGitRepo, usesPnpm } from "./checks.js";
|
|
4
4
|
import { detectRepoType } from "./detectRepoType.js";
|
|
5
5
|
import { scaffoldFiles } from "./scaffold.js";
|
|
6
|
-
function runRequiredCheck(label, result) {
|
|
6
|
+
function runRequiredCheck(label, result, styles) {
|
|
7
7
|
if (result.ok) {
|
|
8
|
-
printSuccess(label);
|
|
8
|
+
printSuccess(label, styles.stdout);
|
|
9
9
|
return true;
|
|
10
10
|
}
|
|
11
|
-
printError(result.message ?? `${label} failed
|
|
11
|
+
printError(result.message ?? `${label} failed`, styles.stderr);
|
|
12
12
|
return false;
|
|
13
13
|
}
|
|
14
|
-
function checkEligibility() {
|
|
14
|
+
function checkEligibility(styles) {
|
|
15
15
|
printStep('Checking eligibility');
|
|
16
|
-
if (!runRequiredCheck('Git repository detected', isGitRepo()))
|
|
16
|
+
if (!runRequiredCheck('Git repository detected', isGitRepo(), styles))
|
|
17
17
|
return false;
|
|
18
|
-
if (!runRequiredCheck('package.json found', hasPackageJson()))
|
|
18
|
+
if (!runRequiredCheck('package.json found', hasPackageJson(), styles))
|
|
19
19
|
return false;
|
|
20
|
-
if (!runRequiredCheck('pnpm detected', usesPnpm()))
|
|
20
|
+
if (!runRequiredCheck('pnpm detected', usesPnpm(), styles))
|
|
21
21
|
return false;
|
|
22
22
|
return true;
|
|
23
23
|
}
|
|
24
|
-
export function initCommand({ dryRun, force, withConfig }) {
|
|
24
|
+
export function initCommand({ dryRun, force, styles, withConfig }) {
|
|
25
25
|
if (dryRun) {
|
|
26
26
|
console.info('[dry-run mode]');
|
|
27
27
|
}
|
|
28
28
|
let eligible;
|
|
29
29
|
try {
|
|
30
|
-
eligible = checkEligibility();
|
|
30
|
+
eligible = checkEligibility(styles);
|
|
31
31
|
}
|
|
32
32
|
catch (error) {
|
|
33
|
-
printError(`Eligibility check failed: ${describeError(error)}
|
|
33
|
+
printError(`Eligibility check failed: ${describeError(error)}`, styles.stderr);
|
|
34
34
|
return 1;
|
|
35
35
|
}
|
|
36
36
|
if (!eligible)
|
|
@@ -41,21 +41,21 @@ export function initCommand({ dryRun, force, withConfig }) {
|
|
|
41
41
|
repoType = detectRepoType();
|
|
42
42
|
}
|
|
43
43
|
catch (error) {
|
|
44
|
-
printError(`Failed to detect repo type: ${describeError(error)}
|
|
44
|
+
printError(`Failed to detect repo type: ${describeError(error)}`, styles.stderr);
|
|
45
45
|
return 1;
|
|
46
46
|
}
|
|
47
|
-
printSuccess(`Detected: ${repoType}
|
|
47
|
+
printSuccess(`Detected: ${repoType}`, styles.stdout);
|
|
48
48
|
printStep('Scaffolding files');
|
|
49
49
|
let results;
|
|
50
50
|
try {
|
|
51
51
|
results = scaffoldFiles({ repoType, dryRun, overwrite: force, withConfig });
|
|
52
52
|
}
|
|
53
53
|
catch (error) {
|
|
54
|
-
printError(`Failed to scaffold files: ${describeError(error)}
|
|
54
|
+
printError(`Failed to scaffold files: ${describeError(error)}`, styles.stderr);
|
|
55
55
|
return 1;
|
|
56
56
|
}
|
|
57
57
|
for (const result of results) {
|
|
58
|
-
reportWriteResult(result, dryRun);
|
|
58
|
+
reportWriteResult(result, dryRun, styles);
|
|
59
59
|
}
|
|
60
60
|
if (results.some((r) => r.outcome === 'failed')) {
|
|
61
61
|
return 1;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type OutputStyle } from '@williamthorsen/nmr-core';
|
|
1
2
|
import type { ReleaseKitConfig } from './types.js';
|
|
2
3
|
/**
|
|
3
4
|
* Outcome of loading and validating the consumer config file. `missing` is not reported
|
|
@@ -15,4 +16,4 @@ export type LoadValidatedConfigResult = {
|
|
|
15
16
|
* Load `.config/release-kit.config.ts` and validate it against the shared schema,
|
|
16
17
|
* reporting load failures and validation errors to stderr.
|
|
17
18
|
*/
|
|
18
|
-
export declare function loadValidatedConfig(): Promise<LoadValidatedConfigResult>;
|
|
19
|
+
export declare function loadValidatedConfig(stderrStyle: OutputStyle): Promise<LoadValidatedConfigResult>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { reportError } from '@williamthorsen/nmr-core';
|
|
1
|
+
import { printError, reportError } from '@williamthorsen/nmr-core';
|
|
2
2
|
import { describeError } from '@williamthorsen/toolbelt.errors';
|
|
3
3
|
import { loadConfig } from "./loadConfig.js";
|
|
4
4
|
import { validateConfig } from "./validateConfig.js";
|
|
5
|
-
export async function loadValidatedConfig() {
|
|
5
|
+
export async function loadValidatedConfig(stderrStyle) {
|
|
6
6
|
let raw;
|
|
7
7
|
try {
|
|
8
8
|
raw = await loadConfig();
|
|
@@ -19,7 +19,7 @@ export async function loadValidatedConfig() {
|
|
|
19
19
|
if (errors.length > 0) {
|
|
20
20
|
process.stderr.write('Invalid config:\n');
|
|
21
21
|
for (const err of errors) {
|
|
22
|
-
|
|
22
|
+
printError(err, stderrStyle);
|
|
23
23
|
}
|
|
24
24
|
return { status: 'invalid' };
|
|
25
25
|
}
|
|
@@ -15,10 +15,9 @@ export type PolicyViolationSurface = 'prefix' | 'body';
|
|
|
15
15
|
/**
|
|
16
16
|
* Callback invoked when `parseCommitMessage` detects a `!`-policy violation.
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* etc.) collect callback invocations and surface them in the release report.
|
|
18
|
+
* The parser warns and continues on a violation, so legacy log entries don't block releases.
|
|
19
|
+
* Callers (`decideRelease`, `releasePrepareMono`, etc.) collect callback invocations and
|
|
20
|
+
* surface them in the release report.
|
|
22
21
|
*/
|
|
23
22
|
export type PolicyViolationHandler = (commit: Commit, type: string, surface: PolicyViolationSurface) => void;
|
|
24
23
|
/** Optional configuration for `parseCommitMessage` beyond the core inputs. */
|
|
@@ -47,6 +46,6 @@ export interface ParseCommitMessageOptions {
|
|
|
47
46
|
* `!`-policy enforcement is **release-time tolerant**: when the resolved type's policy
|
|
48
47
|
* forbids `!`, the marker is dropped from the parse (`breaking: false`) and
|
|
49
48
|
* `onPolicyViolation` is invoked. When the policy requires `!`, a bare type triggers the
|
|
50
|
-
* same warning path.
|
|
49
|
+
* same warning path.
|
|
51
50
|
*/
|
|
52
51
|
export declare function parseCommitMessage(message: string, hash: string, workTypes: Record<string, WorkTypeConfig>, scopeAliases?: Record<string, string>, options?: ParseCommitMessageOptions): ParsedCommit | undefined;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type StreamStyles } from '@williamthorsen/nmr-core';
|
|
1
2
|
import type { ReleaseType } from './types.js';
|
|
2
3
|
export declare const prepareFlagSchema: {
|
|
3
4
|
dryRun: {
|
|
@@ -49,4 +50,4 @@ export declare function parseArgs(argv: string[]): {
|
|
|
49
50
|
* 4. Delegates to `releasePrepare` or `releasePrepareMono` to compute the release plan.
|
|
50
51
|
* 5. Applies the plan, runs the format command, and prints the result via `reportPrepare`.
|
|
51
52
|
*/
|
|
52
|
-
export declare function prepareCommand(argv: string[]): Promise<void>;
|
|
53
|
+
export declare function prepareCommand(argv: string[], styles: StreamStyles): Promise<void>;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { execSync } from 'node:child_process';
|
|
2
|
-
import { parseArgsOrExit, reportError } from '@williamthorsen/nmr-core';
|
|
2
|
+
import { formatGlyphLine, formatStatusLine, parseArgsOrExit, printError, reportError, } from '@williamthorsen/nmr-core';
|
|
3
3
|
import { describeError } from '@williamthorsen/toolbelt.errors';
|
|
4
4
|
import { assertCleanWorkingTree } from "./assertCleanWorkingTree.js";
|
|
5
5
|
import { buildDependencyGraph } from "./buildDependencyGraph.js";
|
|
6
6
|
import { discoverWorkspaces } from "./discoverWorkspaces.js";
|
|
7
7
|
import { dim } from "./format.js";
|
|
8
8
|
import { getCommitsSinceTarget } from "./getCommitsSinceTarget.js";
|
|
9
|
+
import { RELEASE_GLYPHS } from "./glyphs.js";
|
|
9
10
|
import { loadConfig, mergeMonorepoConfig, mergeSinglePackageConfig, readRootPackageVersion } from "./loadConfig.js";
|
|
10
11
|
import { RELEASE_SUMMARY_FILE, RELEASE_TAGS_FILE } from "./releaseFiles.js";
|
|
11
12
|
import { applyReleasePlan } from "./releasePlan.js";
|
|
@@ -72,7 +73,7 @@ export function parseArgs(argv) {
|
|
|
72
73
|
withReleaseNotes: flags.withReleaseNotes,
|
|
73
74
|
};
|
|
74
75
|
}
|
|
75
|
-
export async function prepareCommand(argv) {
|
|
76
|
+
export async function prepareCommand(argv, styles) {
|
|
76
77
|
const { dryRun, force, noGitChecks, bumpOverride, only, setVersion, withReleaseNotes } = parseArgs(argv);
|
|
77
78
|
const options = {
|
|
78
79
|
force,
|
|
@@ -81,7 +82,7 @@ export async function prepareCommand(argv) {
|
|
|
81
82
|
...(withReleaseNotes && { withReleaseNotes: true }),
|
|
82
83
|
};
|
|
83
84
|
if (dryRun) {
|
|
84
|
-
console.info(
|
|
85
|
+
console.info(`\n${formatGlyphLine(RELEASE_GLYPHS, styles.stdout, 'dryRun', 'DRY RUN — no files will be modified')}\n`);
|
|
85
86
|
}
|
|
86
87
|
if (!dryRun && !noGitChecks) {
|
|
87
88
|
try {
|
|
@@ -92,7 +93,7 @@ export async function prepareCommand(argv) {
|
|
|
92
93
|
process.exit(1);
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
|
-
const userConfig = await loadAndValidateConfig();
|
|
96
|
+
const userConfig = await loadAndValidateConfig(styles.stderr);
|
|
96
97
|
let discoveredPaths;
|
|
97
98
|
try {
|
|
98
99
|
discoveredPaths = await discoverWorkspaces();
|
|
@@ -102,13 +103,13 @@ export async function prepareCommand(argv) {
|
|
|
102
103
|
process.exit(1);
|
|
103
104
|
}
|
|
104
105
|
if (discoveredPaths === undefined) {
|
|
105
|
-
runSinglePackageMode(userConfig, options, only, dryRun);
|
|
106
|
+
runSinglePackageMode(userConfig, options, only, dryRun, styles.stdout);
|
|
106
107
|
}
|
|
107
108
|
else {
|
|
108
|
-
runMonorepoMode(discoveredPaths, userConfig, options, only, setVersion, dryRun);
|
|
109
|
+
runMonorepoMode(discoveredPaths, userConfig, options, only, setVersion, dryRun, styles.stdout);
|
|
109
110
|
}
|
|
110
111
|
}
|
|
111
|
-
function runSinglePackageMode(userConfig, options, only, dryRun) {
|
|
112
|
+
function runSinglePackageMode(userConfig, options, only, dryRun, style) {
|
|
112
113
|
if (only !== undefined) {
|
|
113
114
|
reportError('--only is only supported for monorepo configurations');
|
|
114
115
|
process.exit(1);
|
|
@@ -119,9 +120,9 @@ function runSinglePackageMode(userConfig, options, only, dryRun) {
|
|
|
119
120
|
process.exit(1);
|
|
120
121
|
}
|
|
121
122
|
const config = mergeSinglePackageConfig(userConfig);
|
|
122
|
-
runAndReport(() => releasePrepare(config, options), dryRun);
|
|
123
|
+
runAndReport(() => releasePrepare(config, options), dryRun, style);
|
|
123
124
|
}
|
|
124
|
-
function runMonorepoMode(discoveredPaths, userConfig, options, only, setVersion, dryRun) {
|
|
125
|
+
function runMonorepoMode(discoveredPaths, userConfig, options, only, setVersion, dryRun, style) {
|
|
125
126
|
let config;
|
|
126
127
|
try {
|
|
127
128
|
const rootPackage = readRootPackageVersion();
|
|
@@ -177,9 +178,9 @@ function runMonorepoMode(discoveredPaths, userConfig, options, only, setVersion,
|
|
|
177
178
|
process.exit(1);
|
|
178
179
|
}
|
|
179
180
|
}
|
|
180
|
-
runAndReport(() => releasePrepareMono(config, { ...options, ...(only !== undefined && { only }) }), dryRun);
|
|
181
|
+
runAndReport(() => releasePrepareMono(config, { ...options, ...(only !== undefined && { only }) }), dryRun, style);
|
|
181
182
|
}
|
|
182
|
-
async function loadAndValidateConfig() {
|
|
183
|
+
async function loadAndValidateConfig(stderrStyle) {
|
|
183
184
|
let rawConfig;
|
|
184
185
|
try {
|
|
185
186
|
rawConfig = await loadConfig();
|
|
@@ -195,16 +196,16 @@ async function loadAndValidateConfig() {
|
|
|
195
196
|
if (errors.length > 0) {
|
|
196
197
|
process.stderr.write('Invalid config:\n');
|
|
197
198
|
for (const err of errors) {
|
|
198
|
-
|
|
199
|
+
printError(err, stderrStyle);
|
|
199
200
|
}
|
|
200
201
|
process.exit(1);
|
|
201
202
|
}
|
|
202
203
|
for (const warning of warnings) {
|
|
203
|
-
console.warn(`
|
|
204
|
+
console.warn(` ${formatStatusLine(stderrStyle, 'warning', warning)}`);
|
|
204
205
|
}
|
|
205
206
|
return config;
|
|
206
207
|
}
|
|
207
|
-
function runAndReport(computePlan, dryRun) {
|
|
208
|
+
function runAndReport(computePlan, dryRun, style) {
|
|
208
209
|
let plan;
|
|
209
210
|
try {
|
|
210
211
|
plan = computePlan();
|
|
@@ -215,7 +216,7 @@ function runAndReport(computePlan, dryRun) {
|
|
|
215
216
|
process.exit(1);
|
|
216
217
|
}
|
|
217
218
|
if (dryRun) {
|
|
218
|
-
process.stdout.write(reportPrepare(plan, { applied: false }) + '\n');
|
|
219
|
+
process.stdout.write(reportPrepare(plan, { applied: false, style }) + '\n');
|
|
219
220
|
reportPlanFiles(plan, true);
|
|
220
221
|
return;
|
|
221
222
|
}
|
|
@@ -227,7 +228,7 @@ function runAndReport(computePlan, dryRun) {
|
|
|
227
228
|
process.exit(1);
|
|
228
229
|
}
|
|
229
230
|
const formatError = runFormatCommand(plan.formatCommand);
|
|
230
|
-
process.stdout.write(reportPrepare(plan, { applied: true, ...(formatError !== undefined && { formatError }) }) + '\n');
|
|
231
|
+
process.stdout.write(reportPrepare(plan, { applied: true, style, ...(formatError !== undefined && { formatError }) }) + '\n');
|
|
231
232
|
reportPlanFiles(plan, false);
|
|
232
233
|
if (formatError !== undefined) {
|
|
233
234
|
reportError(`The format command failed, but the release is prepared and ${RELEASE_TAGS_FILE} is written. ` +
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { type StreamStyles } from '@williamthorsen/nmr-core';
|
|
1
2
|
/**
|
|
2
3
|
* Orchestrate the CLI `publish` command: parse flags, discover workspaces, resolve tags from HEAD,
|
|
3
4
|
* detect the package manager, validate `--tags`, and publish each tag with inject/restore lifecycle.
|
|
4
5
|
*/
|
|
5
|
-
export declare function publishCommand(argv: string[]): Promise<void>;
|
|
6
|
+
export declare function publishCommand(argv: string[], styles: StreamStyles): Promise<void>;
|
|
@@ -16,7 +16,7 @@ const publishFlagSchema = {
|
|
|
16
16
|
provenance: { long: '--provenance', type: 'boolean' },
|
|
17
17
|
tags: { long: '--tags', type: 'string' },
|
|
18
18
|
};
|
|
19
|
-
export async function publishCommand(argv) {
|
|
19
|
+
export async function publishCommand(argv, styles) {
|
|
20
20
|
const parsed = parseArgsOrExit(argv, publishFlagSchema);
|
|
21
21
|
const { dryRun, noGitChecks, provenance } = parsed.flags;
|
|
22
22
|
if (!dryRun && !noGitChecks) {
|
|
@@ -39,7 +39,7 @@ export async function publishCommand(argv) {
|
|
|
39
39
|
return;
|
|
40
40
|
}
|
|
41
41
|
const packageManager = detectPackageManager();
|
|
42
|
-
const { releaseNotes, changelogJsonOutputPath, sectionOrder } = await resolveReleaseNotesConfig();
|
|
42
|
+
const { releaseNotes, changelogJsonOutputPath, sectionOrder } = await resolveReleaseNotesConfig(styles.stderr);
|
|
43
43
|
const shouldInject = releaseNotes.shouldInjectIntoReadme;
|
|
44
44
|
console.info(dryRun ? '[dry-run] Would publish:' : 'Publishing:');
|
|
45
45
|
for (const { tag, workspacePath } of publishableTags) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type OutputStyle } from '@williamthorsen/nmr-core';
|
|
1
2
|
import type { PrepareResult } from './types.js';
|
|
2
3
|
/** How the plan was carried out, which decides the tense the report is rendered in. */
|
|
3
4
|
export interface ReportPrepareOptions {
|
|
@@ -5,6 +6,7 @@ export interface ReportPrepareOptions {
|
|
|
5
6
|
applied: boolean;
|
|
6
7
|
/** The format command's failure message, when it ran and failed. */
|
|
7
8
|
formatError?: string;
|
|
9
|
+
style: OutputStyle;
|
|
8
10
|
}
|
|
9
11
|
/**
|
|
10
12
|
* Format a release plan into styled terminal output.
|