@williamthorsen/release-kit 11.0.0 → 13.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.
- package/.meta/changelog.json +274 -2
- package/.readyup/kits/default.js +18 -33
- package/.readyup/kits/npm-auto-publish.js +24 -23
- package/.readyup/manifest.json +16 -11
- package/CHANGELOG.md +98 -0
- package/README.md +57 -69
- package/bin/release-kit.js +1 -1
- package/dist/esm/assertCleanWorkingTree.d.ts +1 -5
- package/dist/esm/assertTaggedBaseline.d.ts +29 -0
- package/dist/esm/assertTaggedBaseline.js +41 -0
- package/dist/esm/attachChangelogDiagnostics.d.ts +4 -0
- package/dist/esm/attachChangelogDiagnostics.js +14 -0
- package/dist/esm/bin/release-kit.js +88 -24
- package/dist/esm/buildChangelogEntries.d.ts +69 -17
- package/dist/esm/buildChangelogEntries.js +222 -120
- package/dist/esm/buildDependencyGraph.d.ts +6 -6
- package/dist/esm/buildEmptyReleaseEntry.d.ts +1 -8
- package/dist/esm/buildReleaseSummary.d.ts +2 -8
- package/dist/esm/buildReleaseSummary.js +2 -2
- package/dist/esm/buildSyntheticChangelogEntry.d.ts +3 -5
- package/dist/esm/buildSyntheticChangelogEntry.js +2 -2
- package/dist/esm/bumpVersion.d.ts +1 -8
- package/dist/esm/changelogJsonFile.d.ts +5 -7
- package/dist/esm/changelogJsonFile.js +2 -17
- package/dist/esm/changelogJsonUtils.d.ts +7 -10
- package/dist/esm/changelogOverrides.d.ts +79 -100
- package/dist/esm/changelogOverrides.js +138 -58
- package/dist/esm/classifyChangelogCommit.d.ts +36 -0
- package/dist/esm/classifyChangelogCommit.js +34 -0
- package/dist/esm/commitCommand.d.ts +2 -4
- package/dist/esm/compareVersions.d.ts +10 -4
- package/dist/esm/compareVersions.js +16 -0
- package/dist/esm/configFlagSchema.d.ts +1 -1
- package/dist/esm/createGithubRelease.d.ts +7 -19
- package/dist/esm/createGithubReleaseCommand.d.ts +5 -5
- package/dist/esm/createGithubReleaseCommand.js +9 -9
- package/dist/esm/createTags.d.ts +2 -3
- package/dist/esm/decideRelease.d.ts +11 -41
- package/dist/esm/decideRelease.js +5 -27
- package/dist/esm/defaults.d.ts +5 -24
- package/dist/esm/defaults.js +7 -5
- package/dist/esm/defineConfig.d.ts +1 -1
- package/dist/esm/deleteFileIfExists.d.ts +1 -1
- package/dist/esm/deriveReleaseNotesConfig.d.ts +20 -0
- package/dist/esm/deriveReleaseNotesConfig.js +21 -0
- package/dist/esm/deriveWorkspaceConfig.d.ts +3 -5
- package/dist/esm/detectPackageManager.d.ts +2 -4
- package/dist/esm/detectUndeclaredTagPrefixes.d.ts +4 -6
- package/dist/esm/detectUndeclaredTagPrefixes.js +1 -1
- package/dist/esm/determineBumpType.d.ts +11 -11
- package/dist/esm/determineBumpType.js +6 -7
- package/dist/esm/discoverWorkspaces.d.ts +14 -15
- package/dist/esm/discoverWorkspaces.js +12 -12
- package/dist/esm/enterRepoRoot.d.ts +12 -0
- package/dist/esm/enterRepoRoot.js +16 -0
- package/dist/esm/enumerateReleaseWindows.d.ts +50 -0
- package/dist/esm/enumerateReleaseWindows.js +124 -0
- package/dist/esm/extractMigration.d.ts +6 -8
- package/dist/esm/findUnroutedEntryScopes.d.ts +16 -0
- package/dist/esm/findUnroutedEntryScopes.js +57 -0
- package/dist/esm/formatExcludedSkip.d.ts +3 -0
- package/dist/esm/formatExcludedSkip.js +3 -0
- package/dist/esm/formatPrivateSkip.d.ts +1 -6
- package/dist/esm/generateChangelogs.d.ts +13 -26
- package/dist/esm/generateChangelogs.js +0 -14
- package/dist/esm/glyphs.d.ts +2 -2
- package/dist/esm/help/prepareHelp.d.ts +3 -4
- package/dist/esm/help/prepareHelp.js +7 -8
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/init/checks.d.ts +3 -3
- package/dist/esm/init/checks.js +4 -1
- package/dist/esm/init/detectRepoType.d.ts +2 -3
- package/dist/esm/init/hasProvenance.d.ts +2 -0
- package/dist/esm/init/hasProvenance.js +3 -0
- package/dist/esm/init/initCommand.d.ts +3 -6
- package/dist/esm/init/initCommand.js +11 -11
- package/dist/esm/init/parseJsonRecord.d.ts +1 -4
- package/dist/esm/init/scaffold.d.ts +1 -3
- package/dist/esm/init/scaffold.js +2 -30
- package/dist/esm/init/templates.d.ts +9 -11
- package/dist/esm/init/templates.js +12 -11
- package/dist/esm/init/updateTemplatesCommand.d.ts +13 -0
- package/dist/esm/init/updateTemplatesCommand.js +64 -0
- package/dist/esm/injectReleaseNotesIntoReadme.d.ts +12 -17
- package/dist/esm/injectSection.d.ts +3 -3
- package/dist/esm/loadConfig.d.ts +16 -14
- package/dist/esm/loadConfig.js +2 -5
- package/dist/esm/loadValidatedConfig.d.ts +16 -19
- package/dist/esm/loadValidatedConfig.js +6 -1
- package/dist/esm/packsPath.d.ts +9 -9
- package/dist/esm/parseChangeRecordBlock.d.ts +37 -0
- package/dist/esm/parseChangeRecordBlock.js +134 -0
- package/dist/esm/parseCommitMessage.d.ts +42 -32
- package/dist/esm/parseCommitMessage.js +33 -41
- package/dist/esm/parseRequestedTags.d.ts +3 -3
- package/dist/esm/planReleaseNotesPreviews.d.ts +6 -6
- package/dist/esm/planVersionBump.d.ts +5 -3
- package/dist/esm/planVersionBump.js +3 -0
- package/dist/esm/prepareCommand.d.ts +4 -7
- package/dist/esm/prepareCommand.js +17 -18
- package/dist/esm/previewTagPrefixes.d.ts +8 -10
- package/dist/esm/propagateBumps.d.ts +6 -7
- package/dist/esm/publish.d.ts +1 -1
- package/dist/esm/publishCommand.d.ts +4 -3
- package/dist/esm/publishCommand.js +8 -8
- package/dist/esm/pushCommand.d.ts +4 -3
- package/dist/esm/pushCommand.js +8 -2
- package/dist/esm/pushRelease.d.ts +2 -2
- package/dist/esm/readChangelogSections.d.ts +33 -0
- package/dist/esm/readChangelogSections.js +80 -0
- package/dist/esm/releaseFiles.d.ts +5 -7
- package/dist/esm/releasePlan.d.ts +11 -13
- package/dist/esm/releasePrepare.d.ts +25 -25
- package/dist/esm/releasePrepare.js +80 -80
- package/dist/esm/releasePrepareMono.d.ts +9 -7
- package/dist/esm/releasePrepareMono.js +114 -99
- package/dist/esm/releasePrepareProject.d.ts +19 -29
- package/dist/esm/releasePrepareProject.js +46 -45
- package/dist/esm/renderChangelogMarkdown.d.ts +10 -4
- package/dist/esm/renderChangelogMarkdown.js +27 -2
- package/dist/esm/renderReleaseNotes.d.ts +3 -11
- package/dist/esm/renderReleaseNotes.js +2 -6
- package/dist/esm/reportPrepare.d.ts +4 -5
- package/dist/esm/reportPrepare.js +67 -42
- package/dist/esm/resolveCommandTags.d.ts +15 -11
- package/dist/esm/resolveCommandTags.js +35 -5
- package/dist/esm/resolveConfigFlag.d.ts +7 -0
- package/dist/esm/resolveConfigFlag.js +4 -0
- package/dist/esm/resolveReleaseTags.d.ts +6 -8
- package/dist/esm/resolveReleaseTags.js +1 -1
- package/dist/esm/resolveStylesOrExit.d.ts +2 -2
- package/dist/esm/showTagPrefixesCommand.d.ts +7 -10
- package/dist/esm/showTagPrefixesCommand.js +4 -4
- package/dist/esm/stripEmojiPrefix.d.ts +1 -0
- package/dist/esm/stripScope.d.ts +2 -2
- package/dist/esm/stripScope.js +3 -3
- package/dist/esm/sync-labels/generateCommand.d.ts +11 -10
- package/dist/esm/sync-labels/generateCommand.js +11 -8
- package/dist/esm/sync-labels/initCommand.d.ts +6 -7
- package/dist/esm/sync-labels/initCommand.js +2 -2
- package/dist/esm/sync-labels/presets.d.ts +5 -4
- package/dist/esm/sync-labels/presets.js +9 -9
- package/dist/esm/sync-labels/resolveLabels.d.ts +7 -7
- package/dist/esm/sync-labels/resolveLabels.js +1 -1
- package/dist/esm/sync-labels/retiredConfig.d.ts +4 -5
- package/dist/esm/sync-labels/syncCommand.d.ts +1 -4
- package/dist/esm/sync-labels/templates.d.ts +3 -3
- package/dist/esm/sync-labels/templates.js +3 -3
- package/dist/esm/sync-labels/typeLabels.d.ts +14 -0
- package/dist/esm/sync-labels/typeLabels.js +38 -0
- package/dist/esm/sync-labels/types.d.ts +1 -1
- package/dist/esm/tagCommand.d.ts +1 -1
- package/dist/esm/typeGuards.d.ts +2 -2
- package/dist/esm/types.d.ts +185 -116
- package/dist/esm/types.js +2 -2
- package/dist/esm/validateConfig.d.ts +2 -11
- package/dist/esm/validateConfig.js +5 -1
- package/dist/esm/validateOnlyExcludesStrandedDependents.d.ts +14 -12
- package/dist/esm/validateOverridesCommand.d.ts +19 -21
- package/dist/esm/validateOverridesCommand.js +16 -23
- package/docs/api.md +6 -6
- package/docs/changelogs.md +90 -28
- package/docs/configuration.md +30 -29
- package/docs/editorial-overrides.md +90 -31
- package/docs/labels.md +21 -19
- package/docs/project-releases.md +14 -14
- package/docs/publishing.md +5 -5
- package/docs/readiness-checks.md +3 -3
- package/docs/releasing.md +54 -24
- package/docs/work-types.md +46 -58
- package/package.json +7 -7
- package/presets/labels/common.yaml +1 -41
- package/schemas/changelog-overrides.json +39 -0
- package/cliff.toml.template +0 -65
- package/dist/esm/collectPolicyViolations.d.ts +0 -15
- package/dist/esm/collectPolicyViolations.js +0 -12
- package/dist/esm/determineBumpFromCommits.d.ts +0 -17
- package/dist/esm/determineBumpFromCommits.js +0 -28
- package/dist/esm/getCommitsSinceTarget.d.ts +0 -21
- package/dist/esm/getCommitsSinceTarget.js +0 -66
- package/dist/esm/resolveCliffConfigPath.d.ts +0 -11
- package/dist/esm/resolveCliffConfigPath.js +0 -20
- package/dist/esm/resolveReleaseNotesConfig.d.ts +0 -26
- package/dist/esm/resolveReleaseNotesConfig.js +0 -29
- package/dist/esm/runGitCliff.d.ts +0 -38
- package/dist/esm/runGitCliff.js +0 -25
- package/dist/esm/workTypesData.d.ts +0 -50
- package/dist/esm/workTypesData.js +0 -145
- package/schemas/label-map.json +0 -24
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { parseDocument } from 'yaml';
|
|
2
|
+
import { isRecord } from "./typeGuards.js";
|
|
3
|
+
export function parseChangeRecordBlock(message) {
|
|
4
|
+
const lines = message.split(/\r?\n/);
|
|
5
|
+
const fence = findFences(lines).at(-1);
|
|
6
|
+
if (fence === undefined) {
|
|
7
|
+
return { kind: 'absent' };
|
|
8
|
+
}
|
|
9
|
+
if (fence.close === undefined) {
|
|
10
|
+
return { kind: 'malformed', reason: 'the block opens but never closes' };
|
|
11
|
+
}
|
|
12
|
+
const document = parseDocument(lines.slice(fence.open + 1, fence.close).join('\n'));
|
|
13
|
+
const [error] = document.errors;
|
|
14
|
+
if (error !== undefined) {
|
|
15
|
+
const detail = (error.message.split('\n', 1)[0] ?? '').replace(/:$/, '');
|
|
16
|
+
return { kind: 'malformed', reason: `the payload is not valid YAML: ${detail}` };
|
|
17
|
+
}
|
|
18
|
+
return readPayload(document.toJS());
|
|
19
|
+
}
|
|
20
|
+
export function stripChangeRecordBlocks(message) {
|
|
21
|
+
const lines = message.split(/\r?\n/);
|
|
22
|
+
const fences = findFences(lines);
|
|
23
|
+
return lines
|
|
24
|
+
.filter((_line, index) => fences.every((fence) => index < fence.open || index > (fence.close ?? lines.length)))
|
|
25
|
+
.join('\n');
|
|
26
|
+
}
|
|
27
|
+
const FENCE = '```';
|
|
28
|
+
function findFences(lines) {
|
|
29
|
+
const fences = [];
|
|
30
|
+
let open;
|
|
31
|
+
for (const [index, line] of lines.entries()) {
|
|
32
|
+
if (open === undefined) {
|
|
33
|
+
if (line.trim() === `${FENCE}${INFO_STRING}`) {
|
|
34
|
+
open = index;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
else if (line.trim() === FENCE) {
|
|
38
|
+
fences.push({ close: index, open });
|
|
39
|
+
open = undefined;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (open !== undefined) {
|
|
43
|
+
fences.push({ open });
|
|
44
|
+
}
|
|
45
|
+
return fences;
|
|
46
|
+
}
|
|
47
|
+
const INFO_STRING = 'change-record';
|
|
48
|
+
function readEntry(item, index) {
|
|
49
|
+
const at = `entries[${index}]`;
|
|
50
|
+
if (!isRecord(item)) {
|
|
51
|
+
return { reason: `\`${at}\` is not a mapping` };
|
|
52
|
+
}
|
|
53
|
+
const { breaking, migration, scopes } = item;
|
|
54
|
+
if (breaking !== undefined && breaking !== null && typeof breaking !== 'boolean') {
|
|
55
|
+
return { reason: `\`${at}.breaking\` is not a boolean` };
|
|
56
|
+
}
|
|
57
|
+
if (migration !== undefined && migration !== null && typeof migration !== 'string') {
|
|
58
|
+
return { reason: `\`${at}.migration\` is not a string` };
|
|
59
|
+
}
|
|
60
|
+
if (scopes !== undefined && scopes !== null && !Array.isArray(scopes)) {
|
|
61
|
+
return { reason: `\`${at}.scopes\` is not a list` };
|
|
62
|
+
}
|
|
63
|
+
const declaredScopes = scopes ?? [];
|
|
64
|
+
const readScopes = [];
|
|
65
|
+
for (const [position, scope] of declaredScopes.entries()) {
|
|
66
|
+
if (typeof scope !== 'string') {
|
|
67
|
+
return { reason: `\`${at}.scopes[${position}]\` is not a string` };
|
|
68
|
+
}
|
|
69
|
+
readScopes.push(scope.trim());
|
|
70
|
+
}
|
|
71
|
+
const type = readRequiredString(item, at, 'type');
|
|
72
|
+
if ('reason' in type) {
|
|
73
|
+
return type;
|
|
74
|
+
}
|
|
75
|
+
const text = readRequiredString(item, at, 'text');
|
|
76
|
+
if ('reason' in text) {
|
|
77
|
+
return text;
|
|
78
|
+
}
|
|
79
|
+
const trimmedMigration = migration?.trim();
|
|
80
|
+
return {
|
|
81
|
+
entry: {
|
|
82
|
+
breaking: breaking === true,
|
|
83
|
+
...(trimmedMigration !== undefined && trimmedMigration !== '' && { migration: trimmedMigration }),
|
|
84
|
+
scopes: readScopes,
|
|
85
|
+
text: text.value,
|
|
86
|
+
type: type.value,
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function readPayload(payload) {
|
|
91
|
+
if (!isRecord(payload)) {
|
|
92
|
+
return { kind: 'malformed', reason: 'the payload is not a mapping' };
|
|
93
|
+
}
|
|
94
|
+
const { entries, pr_number: prNumber, ticket_ref: ticketRef } = payload;
|
|
95
|
+
if (prNumber !== undefined &&
|
|
96
|
+
prNumber !== null &&
|
|
97
|
+
(typeof prNumber !== 'number' || !Number.isSafeInteger(prNumber) || prNumber <= 0)) {
|
|
98
|
+
return { kind: 'malformed', reason: '`pr_number` is not a positive integer' };
|
|
99
|
+
}
|
|
100
|
+
if (ticketRef !== undefined && ticketRef !== null && typeof ticketRef !== 'string') {
|
|
101
|
+
return { kind: 'malformed', reason: '`ticket_ref` is not a string' };
|
|
102
|
+
}
|
|
103
|
+
const readEntries = [];
|
|
104
|
+
if (entries !== undefined && entries !== null) {
|
|
105
|
+
if (!Array.isArray(entries)) {
|
|
106
|
+
return { kind: 'malformed', reason: '`entries` is not a list' };
|
|
107
|
+
}
|
|
108
|
+
for (const [index, item] of entries.entries()) {
|
|
109
|
+
const read = readEntry(item, index);
|
|
110
|
+
if ('reason' in read) {
|
|
111
|
+
return { kind: 'malformed', reason: read.reason };
|
|
112
|
+
}
|
|
113
|
+
readEntries.push(read.entry);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const trimmedTicketRef = ticketRef?.trim();
|
|
117
|
+
return {
|
|
118
|
+
kind: 'read',
|
|
119
|
+
entries: readEntries,
|
|
120
|
+
...(typeof prNumber === 'number' && { prNumber }),
|
|
121
|
+
...(trimmedTicketRef !== undefined && trimmedTicketRef !== '' && { ticketRef: trimmedTicketRef }),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function readRequiredString(item, at, name) {
|
|
125
|
+
const value = item[name];
|
|
126
|
+
if (value === undefined || value === null) {
|
|
127
|
+
return { reason: `\`${at}.${name}\` is missing` };
|
|
128
|
+
}
|
|
129
|
+
if (typeof value !== 'string') {
|
|
130
|
+
return { reason: `\`${at}.${name}\` is not a string` };
|
|
131
|
+
}
|
|
132
|
+
const trimmed = value.trim();
|
|
133
|
+
return trimmed === '' ? { reason: `\`${at}.${name}\` is blank` } : { value: trimmed };
|
|
134
|
+
}
|
|
@@ -1,51 +1,61 @@
|
|
|
1
|
+
import { type BreakingPolicy, type ChangeRecord } from '@williamthorsen/change-grammar';
|
|
1
2
|
import type { Commit, ParsedCommit, WorkTypeConfig } from './types.js';
|
|
2
|
-
/** Regex patterns stripped from the start of commit messages before parsing. */
|
|
3
|
-
export declare const COMMIT_PREPROCESSOR_PATTERNS: readonly RegExp[];
|
|
4
3
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* Deliberately permissive: `*` is the sanctioned structural scope for changes spanning every
|
|
8
|
-
* workspace, so the atom admits any run of non-pipe characters rather than word characters.
|
|
9
|
-
* `cliff.toml.template` embeds the same atom in every ticketed commit parser, and
|
|
10
|
-
* `cliffConfigAlignment.unit.test.ts` asserts that parity — exported so neither side can drift.
|
|
4
|
+
* Surface where a breaking-policy violation was detected: a subject's `!`, a `BREAKING CHANGE:` footer, or a
|
|
5
|
+
* change-record entry's `breaking`.
|
|
11
6
|
*/
|
|
12
|
-
export
|
|
13
|
-
/** Surface where a `!`/`BREAKING CHANGE:` policy violation was detected. */
|
|
14
|
-
export type PolicyViolationSurface = 'prefix' | 'body';
|
|
7
|
+
export type PolicyViolationSurface = 'prefix' | 'body' | 'entry';
|
|
15
8
|
/**
|
|
16
9
|
* Callback invoked when `parseCommitMessage` detects a `!`-policy violation.
|
|
17
10
|
*
|
|
18
|
-
*
|
|
19
|
-
* Callers (`decideRelease`, `releasePrepareMono`, etc.) collect callback invocations and
|
|
20
|
-
* surface them in the release report.
|
|
11
|
+
* Parsing continues after a violation so that an older commit in the log does not block a release.
|
|
21
12
|
*/
|
|
22
13
|
export type PolicyViolationHandler = (commit: Commit, type: string, surface: PolicyViolationSurface) => void;
|
|
23
14
|
/** Optional configuration for `parseCommitMessage` beyond the core inputs. */
|
|
24
15
|
export interface ParseCommitMessageOptions {
|
|
25
|
-
/**
|
|
26
|
-
|
|
27
|
-
* treated as `'optional'` for backward compatibility with consumers that have not
|
|
28
|
-
* supplied policies.
|
|
29
|
-
*/
|
|
30
|
-
breakingPolicies?: Record<string, 'forbidden' | 'optional' | 'required'>;
|
|
16
|
+
/** Per-type breaking-policy lookup keyed by canonical type name; a type without an entry is `'optional'`. */
|
|
17
|
+
breakingPolicies?: Record<string, BreakingPolicy>;
|
|
31
18
|
/** Receives policy-violation notifications. See {@link PolicyViolationHandler}. */
|
|
32
19
|
onPolicyViolation?: PolicyViolationHandler;
|
|
33
20
|
}
|
|
34
21
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* Supports three formats:
|
|
38
|
-
* - `type: description`
|
|
39
|
-
* - `scope|type: description` (pipe-prefixed scope)
|
|
40
|
-
* - `type(scope): description` (conventional commit parenthesized scope)
|
|
22
|
+
* Parses a commit message into structured metadata.
|
|
41
23
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
24
|
+
* Reads the first line through change-grammar's `pipedScope` template (`scope|type: description`, the scope optional),
|
|
25
|
+
* then its `conventionalCommits` template (`type(scope): description`), and takes the first match. Types and aliases
|
|
26
|
+
* resolve against `workTypes`, ignoring case; scope aliases resolve when a `scopeAliases` map is provided. Detects
|
|
27
|
+
* breaking changes via the subject's `!` or `BREAKING CHANGE:` in the message.
|
|
45
28
|
*
|
|
46
|
-
* `!`-policy enforcement is **release-time tolerant**:
|
|
29
|
+
* `!`-policy enforcement is **release-time tolerant**: When the resolved type's policy
|
|
47
30
|
* forbids `!`, the marker is dropped from the parse (`breaking: false`) and
|
|
48
|
-
* `onPolicyViolation` is invoked.
|
|
49
|
-
* same warning path.
|
|
31
|
+
* `onPolicyViolation` is invoked.
|
|
50
32
|
*/
|
|
51
33
|
export declare function parseCommitMessage(message: string, hash: string, workTypes: Record<string, WorkTypeConfig>, scopeAliases?: Record<string, string>, options?: ParseCommitMessageOptions): ParsedCommit | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Reads a commit subject into a change record through the templates that release-kit accepts, before any breaking
|
|
36
|
+
* policy applies. The engine strips ticket prefixes.
|
|
37
|
+
*/
|
|
38
|
+
export declare function parseSubject(subject: string, workTypes: Record<string, WorkTypeConfig>): ChangeRecord | undefined;
|
|
39
|
+
/** Inputs for {@link evaluateBreakingPolicy}. */
|
|
40
|
+
export interface BreakingPolicyInputs {
|
|
41
|
+
commit: Commit;
|
|
42
|
+
resolvedType: string;
|
|
43
|
+
/** Whether the marker that `prefixSurface` names is present. */
|
|
44
|
+
hasPrefixBreaking: boolean;
|
|
45
|
+
hasFooterBreaking: boolean;
|
|
46
|
+
policy: BreakingPolicy;
|
|
47
|
+
onPolicyViolation: PolicyViolationHandler | undefined;
|
|
48
|
+
/** The surface reported for a violation of the marker; `'prefix'` when omitted. */
|
|
49
|
+
prefixSurface?: PolicyViolationSurface;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Applies the `!`-policy rules and returns the effective `breaking` flag.
|
|
53
|
+
*
|
|
54
|
+
* A violation invokes `onPolicyViolation` and drops the marker (`breaking: false`); the
|
|
55
|
+
* commit still parses.
|
|
56
|
+
*/
|
|
57
|
+
export declare function evaluateBreakingPolicy(inputs: BreakingPolicyInputs): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Resolves a raw type string to its canonical type name using the record keys and aliases.
|
|
60
|
+
*/
|
|
61
|
+
export declare function resolveType(rawType: string, workTypes: Record<string, WorkTypeConfig>): string | undefined;
|
|
@@ -1,66 +1,59 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { compileTemplate, parse, TEMPLATE_CATALOGUE, } from '@williamthorsen/change-grammar';
|
|
2
|
+
const SUBJECT_TEMPLATES = [
|
|
3
|
+
compileTemplate(TEMPLATE_CATALOGUE.pipedScope),
|
|
4
|
+
compileTemplate(TEMPLATE_CATALOGUE.conventionalCommits),
|
|
5
|
+
];
|
|
4
6
|
export function parseCommitMessage(message, hash, workTypes, scopeAliases, options) {
|
|
5
7
|
const firstLine = message.split('\n', 1)[0] ?? '';
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
if (!match) {
|
|
8
|
+
const record = parseSubject(firstLine, workTypes);
|
|
9
|
+
if (record?.type === undefined || record.title === undefined) {
|
|
9
10
|
return undefined;
|
|
10
11
|
}
|
|
11
|
-
const
|
|
12
|
-
const rawType = match[2];
|
|
13
|
-
const parenthesizedScope = match[3];
|
|
14
|
-
const breakingMarker = match[4];
|
|
15
|
-
const description = match[5];
|
|
16
|
-
if (rawType === undefined || description === undefined) {
|
|
17
|
-
return undefined;
|
|
18
|
-
}
|
|
19
|
-
const resolvedType = resolveType(rawType, workTypes);
|
|
20
|
-
if (resolvedType === undefined) {
|
|
21
|
-
return undefined;
|
|
22
|
-
}
|
|
23
|
-
const commit = { message, hash };
|
|
12
|
+
const commit = { message, subject: firstLine, hash };
|
|
24
13
|
const breaking = evaluateBreakingPolicy({
|
|
25
14
|
commit,
|
|
26
|
-
resolvedType,
|
|
27
|
-
hasPrefixBreaking:
|
|
15
|
+
resolvedType: record.type,
|
|
16
|
+
hasPrefixBreaking: record.breaking === true,
|
|
28
17
|
hasFooterBreaking: message.includes('BREAKING CHANGE:'),
|
|
29
|
-
policy: options?.breakingPolicies?.[
|
|
18
|
+
policy: options?.breakingPolicies?.[record.type] ?? 'optional',
|
|
30
19
|
onPolicyViolation: options?.onPolicyViolation,
|
|
31
20
|
});
|
|
32
|
-
const rawScope =
|
|
21
|
+
const rawScope = record.scope;
|
|
33
22
|
const resolvedScope = rawScope !== undefined && scopeAliases !== undefined ? (scopeAliases[rawScope] ?? rawScope) : rawScope;
|
|
34
23
|
return {
|
|
35
24
|
message,
|
|
36
25
|
hash,
|
|
37
|
-
type:
|
|
38
|
-
description,
|
|
26
|
+
type: record.type,
|
|
27
|
+
description: record.title,
|
|
39
28
|
breaking,
|
|
40
29
|
...(resolvedScope !== undefined && { scope: resolvedScope }),
|
|
41
30
|
};
|
|
42
31
|
}
|
|
43
|
-
function
|
|
32
|
+
export function parseSubject(subject, workTypes) {
|
|
33
|
+
const taxonomy = toTaxonomy(workTypes);
|
|
34
|
+
for (const nodes of SUBJECT_TEMPLATES) {
|
|
35
|
+
const record = parse(nodes, subject, taxonomy);
|
|
36
|
+
if (record !== undefined) {
|
|
37
|
+
return record;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
export function evaluateBreakingPolicy(inputs) {
|
|
44
43
|
const { commit, resolvedType, hasPrefixBreaking, hasFooterBreaking, policy, onPolicyViolation } = inputs;
|
|
44
|
+
const prefixSurface = inputs.prefixSurface ?? 'prefix';
|
|
45
45
|
if (policy === 'forbidden') {
|
|
46
46
|
if (hasPrefixBreaking) {
|
|
47
|
-
onPolicyViolation?.(commit, resolvedType,
|
|
47
|
+
onPolicyViolation?.(commit, resolvedType, prefixSurface);
|
|
48
48
|
}
|
|
49
49
|
if (hasFooterBreaking) {
|
|
50
50
|
onPolicyViolation?.(commit, resolvedType, 'body');
|
|
51
51
|
}
|
|
52
52
|
return false;
|
|
53
53
|
}
|
|
54
|
-
if (policy === 'required') {
|
|
55
|
-
if (!hasPrefixBreaking) {
|
|
56
|
-
onPolicyViolation?.(commit, resolvedType, 'prefix');
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
return true;
|
|
60
|
-
}
|
|
61
54
|
return hasPrefixBreaking || hasFooterBreaking;
|
|
62
55
|
}
|
|
63
|
-
function resolveType(rawType, workTypes) {
|
|
56
|
+
export function resolveType(rawType, workTypes) {
|
|
64
57
|
const lowered = rawType.toLowerCase();
|
|
65
58
|
for (const [key, config] of Object.entries(workTypes)) {
|
|
66
59
|
if (key === lowered) {
|
|
@@ -76,10 +69,9 @@ function resolveType(rawType, workTypes) {
|
|
|
76
69
|
}
|
|
77
70
|
return undefined;
|
|
78
71
|
}
|
|
79
|
-
function
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
return result;
|
|
72
|
+
function toTaxonomy(workTypes) {
|
|
73
|
+
return {
|
|
74
|
+
tiers: [],
|
|
75
|
+
types: Object.entries(workTypes).map(([key, config]) => ({ aliases: config.aliases ?? [], key, tier: '' })),
|
|
76
|
+
};
|
|
85
77
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Parses the comma-separated `--tags` flag value into a list of requested tag names.
|
|
3
3
|
*
|
|
4
4
|
* Empty segments (from `--tags=`, leading/trailing commas, or `--tags=,,`) are dropped. When the
|
|
5
|
-
* resulting list is empty, returns `undefined
|
|
6
|
-
*
|
|
5
|
+
* resulting list is empty, returns `undefined`, and the caller does not filter the tags, as when
|
|
6
|
+
* `--tags` is omitted.
|
|
7
7
|
*/
|
|
8
8
|
export declare function parseRequestedTags(flagValue: string | undefined): string[] | undefined;
|
|
@@ -11,7 +11,7 @@ export interface PlanReleaseNotesPreviewsOptions {
|
|
|
11
11
|
/** Section titles in priority order, typically derived from `resolveWorkTypes(config.workTypes)`. */
|
|
12
12
|
sectionOrder: string[];
|
|
13
13
|
}
|
|
14
|
-
/** Preview files a release will write,
|
|
14
|
+
/** Preview files that a release will write, with the reasons for any that were left out. */
|
|
15
15
|
export interface ReleaseNotesPreviewsPlan {
|
|
16
16
|
writes: PlannedWrite[];
|
|
17
17
|
warnings: string[];
|
|
@@ -20,14 +20,14 @@ export interface ReleaseNotesPreviewsPlan {
|
|
|
20
20
|
* Computes the per-workspace release-notes previews under `{workspacePath}/docs/` without
|
|
21
21
|
* writing them:
|
|
22
22
|
*
|
|
23
|
-
* - `docs/README.v{version}.md
|
|
24
|
-
* - `docs/RELEASE_NOTES.v{version}.md
|
|
23
|
+
* - `docs/README.v{version}.md`: the workspace README with release notes injected at the marker.
|
|
24
|
+
* - `docs/RELEASE_NOTES.v{version}.md`: the standalone release notes for this version.
|
|
25
25
|
*
|
|
26
|
-
* Renders from the entries the release will write rather than from a saved `changelog.json`, so
|
|
26
|
+
* Renders from the entries that the release will write rather than from a saved `changelog.json`, so
|
|
27
27
|
* a preview describes the release being prepared rather than the one already on disk.
|
|
28
28
|
*
|
|
29
29
|
* The injected-README preview is omitted (the standalone file is still planned) when the
|
|
30
|
-
* workspace
|
|
31
|
-
* for this version, with the reason recorded in `warnings`.
|
|
30
|
+
* workspace does not have a readable `README.md`. Both are omitted when the renderer does not
|
|
31
|
+
* report any content for this version, with the reason recorded in `warnings`.
|
|
32
32
|
*/
|
|
33
33
|
export declare function planReleaseNotesPreviews(options: PlanReleaseNotesPreviewsOptions): ReleaseNotesPreviewsPlan;
|
|
@@ -10,13 +10,15 @@ export interface VersionBumpPlan {
|
|
|
10
10
|
* Computes the version bump for a workspace's package files without writing them.
|
|
11
11
|
*
|
|
12
12
|
* The current version comes from the first package file, and the new one from the release type.
|
|
13
|
-
* Every file's post-bump content is rendered in full, preserving
|
|
14
|
-
*
|
|
13
|
+
* Every file's post-bump content is rendered in full, preserving every field that the file already
|
|
14
|
+
* contains, with two-space indentation and a trailing newline.
|
|
15
15
|
*/
|
|
16
16
|
export declare function planVersionBump(packageFiles: readonly string[], releaseType: ReleaseType): VersionBumpPlan;
|
|
17
17
|
/**
|
|
18
18
|
* Computes an explicit version assignment for a workspace's package files without writing them,
|
|
19
|
-
* bypassing commit-derived bump logic.
|
|
19
|
+
* bypassing commit-derived bump logic. Implements the `--set-version` flag, and so rejects a
|
|
20
20
|
* `newVersion` that is not greater than the current version.
|
|
21
21
|
*/
|
|
22
22
|
export declare function planVersionSet(packageFiles: readonly string[], newVersion: string): VersionBumpPlan;
|
|
23
|
+
/** Reads a workspace's current version from its first package file, as the version planners do. */
|
|
24
|
+
export declare function readCurrentVersion(packageFiles: readonly string[]): string;
|
|
@@ -19,6 +19,9 @@ export function planVersionSet(packageFiles, newVersion) {
|
|
|
19
19
|
}
|
|
20
20
|
return { currentVersion, newVersion, writes: renderVersionWrites(packageFiles, firstFile, firstPkg, newVersion) };
|
|
21
21
|
}
|
|
22
|
+
export function readCurrentVersion(packageFiles) {
|
|
23
|
+
return readPrimaryPackage(packageFiles).firstPkg.version;
|
|
24
|
+
}
|
|
22
25
|
function readPrimaryPackage(packageFiles) {
|
|
23
26
|
const firstFile = packageFiles[0];
|
|
24
27
|
if (firstFile === undefined) {
|
|
@@ -47,12 +47,9 @@ export declare function parseArgs(argv: string[]): {
|
|
|
47
47
|
withReleaseNotes: boolean;
|
|
48
48
|
};
|
|
49
49
|
/**
|
|
50
|
-
* Orchestrates the CLI `prepare` command
|
|
50
|
+
* Orchestrates the CLI `prepare` command: checks the working tree, loads and validates the config, discovers the
|
|
51
|
+
* workspaces, and prepares the release in single-package or monorepo mode.
|
|
51
52
|
*
|
|
52
|
-
*
|
|
53
|
-
* 2. Loads and validates `.config/release-kit.config.ts` (if present).
|
|
54
|
-
* 3. Merges discovered defaults with user config.
|
|
55
|
-
* 4. Delegates to `releasePrepare` or `releasePrepareMono` to compute the release plan.
|
|
56
|
-
* 5. Applies the plan, runs the format command, and prints the result via `reportPrepare`.
|
|
53
|
+
* A relative `--config` resolves against `invocationDir`.
|
|
57
54
|
*/
|
|
58
|
-
export declare function prepareCommand(argv: string[], styles: StreamStyles): Promise<void>;
|
|
55
|
+
export declare function prepareCommand(argv: string[], styles: StreamStyles, invocationDir: string): Promise<void>;
|
|
@@ -2,11 +2,12 @@ import { execSync } from 'node:child_process';
|
|
|
2
2
|
import { formatGlyphLine, parseArgsOrExit, reportError, } from '@williamthorsen/nmr-core';
|
|
3
3
|
import { describeError } from '@williamthorsen/toolbelt.errors';
|
|
4
4
|
import { assertCleanWorkingTree } from "./assertCleanWorkingTree.js";
|
|
5
|
+
import { readReleaseHistory } from "./buildChangelogEntries.js";
|
|
5
6
|
import { buildDependencyGraph } from "./buildDependencyGraph.js";
|
|
6
7
|
import { configFlagSchema } from "./configFlagSchema.js";
|
|
7
8
|
import { describeEmptyWorkspace, discoverWorkspaces } from "./discoverWorkspaces.js";
|
|
8
9
|
import { dim } from "./format.js";
|
|
9
|
-
import {
|
|
10
|
+
import { getAllTagPrefixes } from "./generateChangelogs.js";
|
|
10
11
|
import { RELEASE_GLYPHS } from "./glyphs.js";
|
|
11
12
|
import { mergeMonorepoConfig, mergeSinglePackageConfig, readRootPackageVersion } from "./loadConfig.js";
|
|
12
13
|
import { loadValidatedConfig, reportConfigProblem, reportConfigWarnings } from "./loadValidatedConfig.js";
|
|
@@ -15,6 +16,7 @@ import { applyReleasePlan } from "./releasePlan.js";
|
|
|
15
16
|
import { releasePrepare } from "./releasePrepare.js";
|
|
16
17
|
import { releasePrepareMono } from "./releasePrepareMono.js";
|
|
17
18
|
import { reportPrepare } from "./reportPrepare.js";
|
|
19
|
+
import { resolveConfigFlag } from "./resolveConfigFlag.js";
|
|
18
20
|
import { validateOnlyExcludesStrandedDependents } from "./validateOnlyExcludesStrandedDependents.js";
|
|
19
21
|
const VALID_BUMP_TYPES = ['major', 'minor', 'patch'];
|
|
20
22
|
const CANONICAL_SEMVER_PATTERN = /^\d+\.\d+\.\d+$/;
|
|
@@ -76,8 +78,8 @@ export function parseArgs(argv) {
|
|
|
76
78
|
withReleaseNotes: flags.withReleaseNotes,
|
|
77
79
|
};
|
|
78
80
|
}
|
|
79
|
-
export async function prepareCommand(argv, styles) {
|
|
80
|
-
const { configPath, dryRun, force, noGitChecks, bumpOverride, only, setVersion, withReleaseNotes } = parseArgs(argv);
|
|
81
|
+
export async function prepareCommand(argv, styles, invocationDir) {
|
|
82
|
+
const { configPath: configFlag, dryRun, force, noGitChecks, bumpOverride, only, setVersion, withReleaseNotes, } = parseArgs(argv);
|
|
81
83
|
const options = {
|
|
82
84
|
force,
|
|
83
85
|
...(bumpOverride !== undefined && { bumpOverride }),
|
|
@@ -85,7 +87,7 @@ export async function prepareCommand(argv, styles) {
|
|
|
85
87
|
...(withReleaseNotes && { withReleaseNotes: true }),
|
|
86
88
|
};
|
|
87
89
|
if (dryRun) {
|
|
88
|
-
console.info(`\n${formatGlyphLine(RELEASE_GLYPHS, styles.stdout, 'dryRun', 'DRY RUN
|
|
90
|
+
console.info(`\n${formatGlyphLine(RELEASE_GLYPHS, styles.stdout, 'dryRun', 'DRY RUN: release-kit will not modify any files')}\n`);
|
|
89
91
|
}
|
|
90
92
|
if (!dryRun && !noGitChecks) {
|
|
91
93
|
try {
|
|
@@ -96,7 +98,7 @@ export async function prepareCommand(argv, styles) {
|
|
|
96
98
|
process.exit(1);
|
|
97
99
|
}
|
|
98
100
|
}
|
|
99
|
-
const configResult = await loadValidatedConfig(
|
|
101
|
+
const configResult = await loadValidatedConfig(resolveConfigFlag(configFlag, invocationDir));
|
|
100
102
|
if (configResult.status === 'invalid') {
|
|
101
103
|
reportConfigProblem(configResult.problem, styles.stderr);
|
|
102
104
|
process.exit(1);
|
|
@@ -130,11 +132,6 @@ function runSinglePackageMode(userConfig, options, only, dryRun, style) {
|
|
|
130
132
|
reportError('--only is only supported for monorepo configurations');
|
|
131
133
|
process.exit(1);
|
|
132
134
|
}
|
|
133
|
-
if (options.force && options.bumpOverride === undefined) {
|
|
134
|
-
reportError('--force without --bump is only supported for monorepo configurations. ' +
|
|
135
|
-
'Use --bump=major|minor|patch to set the level for a single-package release.');
|
|
136
|
-
process.exit(1);
|
|
137
|
-
}
|
|
138
135
|
const config = mergeSinglePackageConfig(userConfig);
|
|
139
136
|
runAndReport(() => releasePrepare(config, options), dryRun, style);
|
|
140
137
|
}
|
|
@@ -154,6 +151,7 @@ function runMonorepoMode(discoveredPaths, userConfig, options, only, setVersion,
|
|
|
154
151
|
'contributing workspace. To use --set-version, run on a config without a `project` block.');
|
|
155
152
|
process.exit(1);
|
|
156
153
|
}
|
|
154
|
+
let configuredWorkspaceDirs;
|
|
157
155
|
if (only !== undefined) {
|
|
158
156
|
const knownNames = config.workspaces.map((w) => w.dir);
|
|
159
157
|
for (const name of only) {
|
|
@@ -165,12 +163,8 @@ function runMonorepoMode(discoveredPaths, userConfig, options, only, setVersion,
|
|
|
165
163
|
}
|
|
166
164
|
const graph = buildDependencyGraph(config.workspaces);
|
|
167
165
|
const violations = validateOnlyExcludesStrandedDependents(config.workspaces, only, graph, (workspace) => {
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
...(workspace.legacyIdentities?.map((identity) => identity.tagPrefix) ?? []),
|
|
171
|
-
];
|
|
172
|
-
const result = getCommitsSinceTarget(tagPrefixes, workspace.paths);
|
|
173
|
-
return { has: result.commits.length > 0, tag: result.tag };
|
|
166
|
+
const history = readReleaseHistory(config, { tagPrefixes: getAllTagPrefixes(workspace), paths: workspace.paths });
|
|
167
|
+
return { has: history.unreleased.commits.length > 0, tag: history.previousTag };
|
|
174
168
|
});
|
|
175
169
|
if (violations !== undefined) {
|
|
176
170
|
reportError('--only excludes packages with changes that would be stranded by the release.');
|
|
@@ -182,6 +176,7 @@ function runMonorepoMode(discoveredPaths, userConfig, options, only, setVersion,
|
|
|
182
176
|
process.stderr.write('Alternatively, run `release-kit prepare` without --only to release everything.\n');
|
|
183
177
|
process.exit(1);
|
|
184
178
|
}
|
|
179
|
+
configuredWorkspaceDirs = knownNames;
|
|
185
180
|
config.workspaces = config.workspaces.filter((w) => only.includes(w.dir));
|
|
186
181
|
}
|
|
187
182
|
if (setVersion !== undefined) {
|
|
@@ -194,7 +189,11 @@ function runMonorepoMode(discoveredPaths, userConfig, options, only, setVersion,
|
|
|
194
189
|
process.exit(1);
|
|
195
190
|
}
|
|
196
191
|
}
|
|
197
|
-
runAndReport(() => releasePrepareMono(config, {
|
|
192
|
+
runAndReport(() => releasePrepareMono(config, {
|
|
193
|
+
...options,
|
|
194
|
+
...(only !== undefined && { only }),
|
|
195
|
+
...(configuredWorkspaceDirs !== undefined && { configuredWorkspaceDirs }),
|
|
196
|
+
}), dryRun, style);
|
|
198
197
|
}
|
|
199
198
|
function runAndReport(computePlan, dryRun, style) {
|
|
200
199
|
let plan;
|
|
@@ -203,7 +202,7 @@ function runAndReport(computePlan, dryRun, style) {
|
|
|
203
202
|
}
|
|
204
203
|
catch (error) {
|
|
205
204
|
reportError(describeError(error));
|
|
206
|
-
process.stderr.write('
|
|
205
|
+
process.stderr.write('The command did not write any files; the working tree is unchanged.\n');
|
|
207
206
|
process.exit(1);
|
|
208
207
|
}
|
|
209
208
|
if (dryRun) {
|
|
@@ -2,7 +2,7 @@ import { type UndeclaredTagPrefix } from './detectUndeclaredTagPrefixes.js';
|
|
|
2
2
|
import type { ReleaseKitConfig } from './types.js';
|
|
3
3
|
/** One workspace's preview row in the tag-prefix preview. */
|
|
4
4
|
export interface TagPrefixPreviewRow {
|
|
5
|
-
/**
|
|
5
|
+
/** Directory path relative to the repo root (e.g., `packages/core`). */
|
|
6
6
|
workspacePath: string;
|
|
7
7
|
/** Directory basename (e.g., `core`). */
|
|
8
8
|
dir: string;
|
|
@@ -10,7 +10,7 @@ export interface TagPrefixPreviewRow {
|
|
|
10
10
|
derivedPrefix: string | null;
|
|
11
11
|
/** Human-readable reason derivation failed, or `null` when it succeeded. */
|
|
12
12
|
derivationError: string | null;
|
|
13
|
-
/** Count of tags matching the derived prefix; `0` when derivation failed or
|
|
13
|
+
/** Count of tags matching the derived prefix; `0` when derivation failed or the repo lacks matching tags. */
|
|
14
14
|
derivedTagCount: number;
|
|
15
15
|
/** One entry per declared legacy prefix, with its current tag count. */
|
|
16
16
|
legacyEntries: LegacyTagPrefixEntry[];
|
|
@@ -40,14 +40,12 @@ export interface TagPrefixPreview {
|
|
|
40
40
|
retiredPackages: RetiredPackagePreviewEntry[];
|
|
41
41
|
}
|
|
42
42
|
/**
|
|
43
|
-
*
|
|
43
|
+
* Builds a structured preview of tag-prefix state for every discovered workspace.
|
|
44
44
|
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* git tags for undeclared candidate prefixes via `detectUndeclaredTagPrefixes`, and reports collisions
|
|
51
|
-
* across successfully-derived prefixes.
|
|
45
|
+
* Records a workspace's derivation error rather than aborting. For a repo releasing as a single package, the
|
|
46
|
+
* preview doesn't contain any rows; for one declaring patterns that don't resolve to any package, the function
|
|
47
|
+
* throws, because the manifest then needs repairing and a clean table would hide that. Also reports the legacy
|
|
48
|
+
* prefixes that the validated `config` declares per workspace, undeclared candidate prefixes among the local git
|
|
49
|
+
* tags, and collisions across the successfully derived prefixes.
|
|
52
50
|
*/
|
|
53
51
|
export declare function previewTagPrefixes(config?: ReleaseKitConfig): TagPrefixPreview;
|
|
@@ -6,17 +6,16 @@ export interface ReleaseEntry {
|
|
|
6
6
|
/** Present when this workspace was bumped (wholly or partly) due to a dependency update. */
|
|
7
7
|
propagatedFrom?: PropagationSource[];
|
|
8
8
|
/**
|
|
9
|
-
* Explicit new version
|
|
10
|
-
*
|
|
11
|
-
* `releaseType`. Used by the `--set-version` CLI path so propagation reflects the overridden version.
|
|
9
|
+
* Explicit new version, which dependents record in their `propagatedFrom.newVersion` entry in place of a version
|
|
10
|
+
* computed from `releaseType`.
|
|
12
11
|
*/
|
|
13
12
|
newVersionOverride?: string;
|
|
14
13
|
}
|
|
15
14
|
/**
|
|
16
|
-
*
|
|
17
|
-
* not already in the release set
|
|
15
|
+
* Walks upward through the dependency graph breadth-first, adding a `patch` bump for each dependent
|
|
16
|
+
* not already in the release set.
|
|
18
17
|
*
|
|
19
|
-
* Returns the full release set (direct + propagated).
|
|
20
|
-
* propagated dependency
|
|
18
|
+
* Returns the full release set (direct + propagated). An entry already in the set that also has a
|
|
19
|
+
* propagated dependency gains `propagatedFrom` metadata without a change to its bump type.
|
|
21
20
|
*/
|
|
22
21
|
export declare function propagateBumps(directBumps: Map<string, ReleaseEntry>, graph: DependencyGraph): Map<string, ReleaseEntry>;
|
package/dist/esm/publish.d.ts
CHANGED
|
@@ -4,5 +4,5 @@ export interface PublishOptions {
|
|
|
4
4
|
dryRun: boolean;
|
|
5
5
|
provenance: boolean;
|
|
6
6
|
}
|
|
7
|
-
/**
|
|
7
|
+
/** Publishes a single package by running `{pm} publish` from its workspace directory. */
|
|
8
8
|
export declare function publishPackage(resolvedTag: ResolvedTag, packageManager: PackageManager, options: PublishOptions): void;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type StreamStyles } from '@williamthorsen/nmr-core';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Orchestrates the CLI `publish` command: checks for a clean working tree, resolves the tags on HEAD, and publishes
|
|
4
|
+
* each publishable one, injecting release notes into its README for the duration of the publish.
|
|
5
|
+
* A relative `--config` resolves against `invocationDir`.
|
|
5
6
|
*/
|
|
6
|
-
export declare function publishCommand(argv: string[], styles: StreamStyles): Promise<void>;
|
|
7
|
+
export declare function publishCommand(argv: string[], styles: StreamStyles, invocationDir: string): Promise<void>;
|