@williamthorsen/release-kit 14.2.1 → 14.2.3
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 +77 -0
- package/.readyup/kits/default.js +142 -152
- package/.readyup/kits/npm-auto-publish.js +183 -184
- package/.readyup/manifest.json +83 -9
- package/CHANGELOG.md +24 -0
- package/README.md +7 -1
- package/dist/esm/applyChangelogOverrides.d.ts +50 -0
- package/dist/esm/applyChangelogOverrides.js +162 -0
- package/dist/esm/attachChangelogDiagnostics.d.ts +1 -1
- package/dist/esm/bin/release-kit.js +6 -238
- package/dist/esm/buildChangelogEntries.d.ts +20 -31
- package/dist/esm/buildChangelogEntries.js +71 -188
- package/dist/esm/buildChangelogItem.d.ts +56 -0
- package/dist/esm/buildChangelogItem.js +119 -0
- package/dist/esm/buildReleasedResult.d.ts +20 -0
- package/dist/esm/buildReleasedResult.js +78 -0
- package/dist/esm/changelogJsonUtils.d.ts +1 -1
- package/dist/esm/changelogOverrides.d.ts +29 -143
- package/dist/esm/changelogOverrides.js +35 -467
- package/dist/esm/configSchema.d.ts +225 -0
- package/dist/esm/configSchema.js +103 -0
- package/dist/esm/createGithubReleaseCommand.js +4 -3
- package/dist/esm/decideDirectReleases.d.ts +30 -0
- package/dist/esm/decideDirectReleases.js +66 -0
- package/dist/esm/defaults.js +1 -4
- package/dist/esm/defineConfig.d.ts +2 -2
- package/dist/esm/deriveReleaseNotesConfig.d.ts +2 -1
- package/dist/esm/deriveReleaseNotesConfig.js +1 -1
- package/dist/esm/determineBumpType.js +4 -3
- package/dist/esm/enumerateReleaseWindows.js +4 -4
- package/dist/esm/formatPrepareFiles.d.ts +11 -0
- package/dist/esm/formatPrepareFiles.js +55 -0
- package/dist/esm/formatPrepareWarnings.d.ts +26 -0
- package/dist/esm/formatPrepareWarnings.js +72 -0
- package/dist/esm/help/initHelp.d.ts +4 -0
- package/dist/esm/help/initHelp.js +31 -0
- package/dist/esm/help/overridesHelp.d.ts +4 -0
- package/dist/esm/help/overridesHelp.js +32 -0
- package/dist/esm/help/releaseStepsHelp.d.ts +12 -0
- package/dist/esm/help/releaseStepsHelp.js +91 -0
- package/dist/esm/help/syncLabelsHelp.d.ts +8 -0
- package/dist/esm/help/syncLabelsHelp.js +55 -0
- package/dist/esm/help/usage.d.ts +2 -0
- package/dist/esm/help/usage.js +29 -0
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/init/initCommand.js +3 -7
- package/dist/esm/loadChangelogOverrides.d.ts +31 -0
- package/dist/esm/loadChangelogOverrides.js +138 -0
- package/dist/esm/loadConfig.d.ts +0 -40
- package/dist/esm/loadConfig.js +0 -242
- package/dist/esm/loadValidatedConfig.d.ts +1 -1
- package/dist/esm/mergeConfig.d.ts +41 -0
- package/dist/esm/mergeConfig.js +118 -0
- package/dist/esm/monorepoConfigAssertions.d.ts +49 -0
- package/dist/esm/monorepoConfigAssertions.js +126 -0
- package/dist/esm/planChangelogFiles.d.ts +16 -0
- package/dist/esm/planChangelogFiles.js +41 -0
- package/dist/esm/prepareArgs.d.ts +55 -0
- package/dist/esm/prepareArgs.js +69 -0
- package/dist/esm/prepareCommand.d.ts +0 -48
- package/dist/esm/prepareCommand.js +11 -77
- package/dist/esm/prepareComposite.d.ts +16 -0
- package/dist/esm/prepareComposite.js +39 -0
- package/dist/esm/prepareRunContext.d.ts +38 -0
- package/dist/esm/prepareRunContext.js +39 -0
- package/dist/esm/prepareTarget.d.ts +2 -7
- package/dist/esm/prepareTarget.js +2 -118
- package/dist/esm/previewTagPrefixes.d.ts +1 -1
- package/dist/esm/releasePrepareTargets.js +13 -207
- package/dist/esm/renderReleaseNotes.js +6 -5
- package/dist/esm/reportPrepare.js +3 -123
- package/dist/esm/resolveCommandTags.d.ts +1 -1
- package/dist/esm/resolveCommandTags.js +2 -1
- package/dist/esm/resolveReleaseDeclaration.d.ts +2 -1
- package/dist/esm/resolveReleaseTargets.d.ts +2 -1
- package/dist/esm/resolveReleaseTargets.js +2 -1
- package/dist/esm/stripScope.js +4 -3
- package/dist/esm/sync-labels/generateCommand.d.ts +1 -1
- package/dist/esm/sync-labels/resolveLabels.d.ts +1 -1
- package/dist/esm/topologicalSort.d.ts +12 -0
- package/dist/esm/topologicalSort.js +60 -0
- package/dist/esm/types.d.ts +1 -225
- package/dist/esm/types.js +1 -103
- package/dist/esm/validateAllChangelogOverrides.d.ts +56 -0
- package/dist/esm/validateAllChangelogOverrides.js +138 -0
- package/dist/esm/validateConfig.d.ts +1 -1
- package/dist/esm/validateConfig.js +7 -9
- package/dist/esm/validateOverridesCommand.d.ts +1 -1
- package/dist/esm/validateOverridesCommand.js +2 -1
- package/package.json +4 -4
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { ChangelogEntry, ChangelogOverride } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Applies overrides to changelog entries, returning new entries without mutating the input.
|
|
4
|
+
*
|
|
5
|
+
* Each key's hash prefix is matched against the distinct `ChangelogItem.hash` values:
|
|
6
|
+
* - No match: The key is unmatched in this batch, and this function doesn't emit a warning.
|
|
7
|
+
* - One match: A bare key resolves to every item of that commit, and an ordinal key `<hash>:<n>` to the items whose
|
|
8
|
+
* `entry` is `n`. A key that doesn't resolve to any item is unmatched, so an ordinal key on a title-derived item
|
|
9
|
+
* goes stale.
|
|
10
|
+
* - Several matches: an error (ambiguous prefix).
|
|
11
|
+
*
|
|
12
|
+
* Two more conditions are errors, and the keys involved apply nowhere: a bare key that sets `description` or `body` on a
|
|
13
|
+
* commit with several items, and two keys that resolve to the same item.
|
|
14
|
+
*
|
|
15
|
+
* `matchedKeys` lists the keys that resolved to at least one item without error. The caller computes stale-key
|
|
16
|
+
* warnings, because in a monorepo a key may target a commit in another workspace: A key unmatched in one batch is not
|
|
17
|
+
* necessarily stale.
|
|
18
|
+
*
|
|
19
|
+
* An override whose audience is `'skip'` removes its item, and a section left empty is dropped; an entry left without
|
|
20
|
+
* sections is kept. An item without a `hash`, such as a synthetic propagation item, passes through unmatched. Errors
|
|
21
|
+
* are returned rather than thrown, and the caller decides whether to abort.
|
|
22
|
+
*/
|
|
23
|
+
export declare function applyChangelogOverrides(entries: ChangelogEntry[], overrides: Map<string, ChangelogOverride>): {
|
|
24
|
+
entries: ChangelogEntry[];
|
|
25
|
+
warnings: string[];
|
|
26
|
+
errors: string[];
|
|
27
|
+
matchedKeys: string[];
|
|
28
|
+
};
|
|
29
|
+
/** Formats the warning for an override key that did not match any item in the changelog. */
|
|
30
|
+
export declare function formatStaleOverrideKeyWarning(key: string): string;
|
|
31
|
+
/** Collects, for each hash, the distinct `entry` positions of the items that have it. */
|
|
32
|
+
export declare function indexItemPositions(items: readonly {
|
|
33
|
+
hash?: string | undefined;
|
|
34
|
+
entry?: number | undefined;
|
|
35
|
+
}[]): Map<string, Set<number | undefined>>;
|
|
36
|
+
/**
|
|
37
|
+
* Resolves one override key against the commits' entry positions. `positions` lists the targeted items' `entry` values,
|
|
38
|
+
* ascending, with `undefined` standing for a title-derived item; it is empty when the key doesn't target any item of
|
|
39
|
+
* the commit.
|
|
40
|
+
*/
|
|
41
|
+
export declare function resolveOverrideKey(overrideKey: string, positionsByHash: Map<string, Set<number | undefined>>): {
|
|
42
|
+
kind: 'none';
|
|
43
|
+
} | {
|
|
44
|
+
kind: 'ambiguous';
|
|
45
|
+
hashes: string[];
|
|
46
|
+
} | {
|
|
47
|
+
kind: 'items';
|
|
48
|
+
hash: string;
|
|
49
|
+
positions: (number | undefined)[];
|
|
50
|
+
};
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { extractMigration } from "./extractMigration.js";
|
|
2
|
+
import { parseOverrideKey } from "./loadChangelogOverrides.js";
|
|
3
|
+
export function applyChangelogOverrides(entries, overrides) {
|
|
4
|
+
const warnings = [];
|
|
5
|
+
if (overrides.size === 0) {
|
|
6
|
+
return { entries: entries.map(cloneEntry), warnings, errors: [], matchedKeys: [] };
|
|
7
|
+
}
|
|
8
|
+
const { errors, itemIdToKey } = resolveOverrideKeys(indexEntryPositions(entries), overrides);
|
|
9
|
+
const itemIdToOverride = new Map();
|
|
10
|
+
for (const [itemId, overrideKey] of itemIdToKey) {
|
|
11
|
+
const override = overrides.get(overrideKey);
|
|
12
|
+
if (override !== undefined) {
|
|
13
|
+
itemIdToOverride.set(itemId, override);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const matchedKeys = [...new Set(itemIdToKey.values())];
|
|
17
|
+
const transformedEntries = [];
|
|
18
|
+
for (const entry of entries) {
|
|
19
|
+
const transformedSections = [];
|
|
20
|
+
for (const section of entry.sections) {
|
|
21
|
+
const transformedItems = applyOverridesToItems(section.items, itemIdToOverride);
|
|
22
|
+
if (transformedItems.length === 0) {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
transformedSections.push({ ...section, items: transformedItems });
|
|
26
|
+
}
|
|
27
|
+
transformedEntries.push({ ...entry, sections: transformedSections });
|
|
28
|
+
}
|
|
29
|
+
return { entries: transformedEntries, warnings, errors, matchedKeys };
|
|
30
|
+
}
|
|
31
|
+
export function formatStaleOverrideKeyWarning(key) {
|
|
32
|
+
return `Override key '${key}' did not match any item in the changelog (likely a stale reference)`;
|
|
33
|
+
}
|
|
34
|
+
export function indexItemPositions(items) {
|
|
35
|
+
const positionsByHash = new Map();
|
|
36
|
+
for (const item of items) {
|
|
37
|
+
if (item.hash === undefined)
|
|
38
|
+
continue;
|
|
39
|
+
const positions = positionsByHash.get(item.hash) ?? new Set();
|
|
40
|
+
positions.add(item.entry);
|
|
41
|
+
positionsByHash.set(item.hash, positions);
|
|
42
|
+
}
|
|
43
|
+
return positionsByHash;
|
|
44
|
+
}
|
|
45
|
+
export function resolveOverrideKey(overrideKey, positionsByHash) {
|
|
46
|
+
const { hashPrefix, entry } = parseOverrideKey(overrideKey);
|
|
47
|
+
const hashes = positionsByHash
|
|
48
|
+
.keys()
|
|
49
|
+
.filter((hash) => hash.startsWith(hashPrefix))
|
|
50
|
+
.toArray();
|
|
51
|
+
const [hash] = hashes;
|
|
52
|
+
if (hash === undefined) {
|
|
53
|
+
return { kind: 'none' };
|
|
54
|
+
}
|
|
55
|
+
if (hashes.length > 1) {
|
|
56
|
+
return { kind: 'ambiguous', hashes };
|
|
57
|
+
}
|
|
58
|
+
const available = [...(positionsByHash.get(hash) ?? [])];
|
|
59
|
+
const positions = entry === undefined
|
|
60
|
+
? available.toSorted((left, right) => (left ?? 0) - (right ?? 0))
|
|
61
|
+
: available.filter((position) => position === entry);
|
|
62
|
+
return positions.length === 0 ? { kind: 'none' } : { kind: 'items', hash, positions };
|
|
63
|
+
}
|
|
64
|
+
function applyOverridesToItems(items, itemIdToOverride) {
|
|
65
|
+
const result = [];
|
|
66
|
+
for (const item of items) {
|
|
67
|
+
if (item.hash === undefined) {
|
|
68
|
+
result.push(cloneItem(item));
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
const override = itemIdToOverride.get(formatItemId(item.hash, item.entry));
|
|
72
|
+
if (override === undefined) {
|
|
73
|
+
result.push(cloneItem(item));
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (override.audience === 'skip') {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
result.push(applyOverrideToItem(item, override));
|
|
80
|
+
}
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
function applyOverrideToItem(item, override) {
|
|
84
|
+
const result = { ...item };
|
|
85
|
+
if (override.description !== undefined) {
|
|
86
|
+
result.description = override.description;
|
|
87
|
+
}
|
|
88
|
+
if (override.body !== undefined) {
|
|
89
|
+
result.body = override.body;
|
|
90
|
+
}
|
|
91
|
+
if (override.body !== undefined && item.entry === undefined) {
|
|
92
|
+
const migration = extractMigration(override.body);
|
|
93
|
+
if (migration === undefined) {
|
|
94
|
+
delete result.migration;
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
result.migration = migration;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (override.breaking !== undefined) {
|
|
101
|
+
result.breaking = override.breaking;
|
|
102
|
+
}
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
105
|
+
function cloneEntry(entry) {
|
|
106
|
+
return {
|
|
107
|
+
...entry,
|
|
108
|
+
sections: entry.sections.map((section) => ({ ...section, items: section.items.map(cloneItem) })),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function cloneItem(item) {
|
|
112
|
+
return { ...item };
|
|
113
|
+
}
|
|
114
|
+
function formatItemId(hash, entry) {
|
|
115
|
+
return entry === undefined ? hash : `${hash}:${entry}`;
|
|
116
|
+
}
|
|
117
|
+
function indexEntryPositions(entries) {
|
|
118
|
+
return indexItemPositions(entries.flatMap((entry) => entry.sections.flatMap((section) => section.items)));
|
|
119
|
+
}
|
|
120
|
+
function resolveOverrideKeys(positionsByHash, overrides) {
|
|
121
|
+
const errors = [];
|
|
122
|
+
const failedKeys = new Set();
|
|
123
|
+
const itemIdToKey = new Map();
|
|
124
|
+
for (const [overrideKey, override] of overrides) {
|
|
125
|
+
const resolution = resolveOverrideKey(overrideKey, positionsByHash);
|
|
126
|
+
if (resolution.kind === 'ambiguous') {
|
|
127
|
+
errors.push(`Override key '${overrideKey}' is ambiguous: matches multiple commits (${resolution.hashes.join(', ')}). ` +
|
|
128
|
+
'Use a longer prefix or the full commit hash.');
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (resolution.kind === 'none') {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
const { hash, positions } = resolution;
|
|
135
|
+
if (parseOverrideKey(overrideKey).entry === undefined && positions.length > 1) {
|
|
136
|
+
const fieldsSet = ['description', 'body'].filter((field) => override[field] !== undefined);
|
|
137
|
+
if (fieldsSet.length > 0) {
|
|
138
|
+
const ordinalKeys = positions.map((position) => `${overrideKey}:${position}`).join(', ');
|
|
139
|
+
errors.push(`Override key '${overrideKey}' sets ${fieldsSet.join(' and ')} on a commit with several items; use ${ordinalKeys}`);
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
for (const position of positions) {
|
|
144
|
+
const itemId = formatItemId(hash, position);
|
|
145
|
+
const claimingKey = itemIdToKey.get(itemId);
|
|
146
|
+
if (claimingKey === undefined) {
|
|
147
|
+
itemIdToKey.set(itemId, overrideKey);
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
const target = position === undefined ? `commit ${hash}` : `the item at ${hash}:${position}`;
|
|
151
|
+
errors.push(`Override keys '${claimingKey}' and '${overrideKey}' both match ${target}; keep one`);
|
|
152
|
+
failedKeys.add(claimingKey);
|
|
153
|
+
failedKeys.add(overrideKey);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
for (const [itemId, overrideKey] of itemIdToKey) {
|
|
157
|
+
if (failedKeys.has(overrideKey)) {
|
|
158
|
+
itemIdToKey.delete(itemId);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return { errors, itemIdToKey };
|
|
162
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ChangelogDiagnostics } from './
|
|
1
|
+
import type { ChangelogDiagnostics } from './buildChangelogItem.js';
|
|
2
2
|
import type { ReleasedPackageResult } from './types.js';
|
|
3
3
|
/** Attaches a history's diagnostics to a released or skipped result, omitting each empty list. */
|
|
4
4
|
export declare function attachChangelogDiagnostics(result: Pick<ReleasedPackageResult, 'malformedBlocks' | 'policyViolations' | 'undeclaredEntryTypes' | 'unroutedEntryScopes'>, diagnostics: ChangelogDiagnostics): void;
|
|
@@ -5,14 +5,19 @@ import { commitCommand } from "../commitCommand.js";
|
|
|
5
5
|
import { configFlagSchema } from "../configFlagSchema.js";
|
|
6
6
|
import { createGithubReleaseCommand } from "../createGithubReleaseCommand.js";
|
|
7
7
|
import { enterRepoRoot } from "../enterRepoRoot.js";
|
|
8
|
+
import { showInitHelp, showUpdateTemplatesHelp } from "../help/initHelp.js";
|
|
9
|
+
import { showOverridesHelp, showOverridesValidateHelp } from "../help/overridesHelp.js";
|
|
8
10
|
import { showPrepareHelp } from "../help/prepareHelp.js";
|
|
11
|
+
import { showCommitHelp, showCreateGithubReleaseHelp, showPublishHelp, showPushHelp, showShowTagPrefixesHelp, showTagHelp, } from "../help/releaseStepsHelp.js";
|
|
12
|
+
import { showSyncLabelsGenerateHelp, showSyncLabelsHelp, showSyncLabelsInitHelp, showSyncLabelsSyncHelp, } from "../help/syncLabelsHelp.js";
|
|
13
|
+
import { showUsage } from "../help/usage.js";
|
|
9
14
|
import { initCommand } from "../init/initCommand.js";
|
|
10
15
|
import { updateTemplatesCommand } from "../init/updateTemplatesCommand.js";
|
|
11
16
|
import { prepareCommand } from "../prepareCommand.js";
|
|
12
17
|
import { publishCommand } from "../publishCommand.js";
|
|
13
18
|
import { pushCommand } from "../pushCommand.js";
|
|
14
19
|
import { resolveConfigFlag } from "../resolveConfigFlag.js";
|
|
15
|
-
import {
|
|
20
|
+
import { resolveStylesOrExit } from "../resolveStylesOrExit.js";
|
|
16
21
|
import { showTagPrefixesCommand } from "../showTagPrefixesCommand.js";
|
|
17
22
|
import { generateCommand } from "../sync-labels/generateCommand.js";
|
|
18
23
|
import { syncLabelsInitCommand } from "../sync-labels/initCommand.js";
|
|
@@ -20,243 +25,6 @@ import { syncLabelsCommand } from "../sync-labels/syncCommand.js";
|
|
|
20
25
|
import { tagCommand } from "../tagCommand.js";
|
|
21
26
|
import { validateOverridesCommand } from "../validateOverridesCommand.js";
|
|
22
27
|
const VERSION = resolveSelfVersion(import.meta.url);
|
|
23
|
-
function showUsage() {
|
|
24
|
-
console.info(`
|
|
25
|
-
Usage: release-kit <command> [options]
|
|
26
|
-
|
|
27
|
-
Commands:
|
|
28
|
-
prepare Run release preparation (auto-discovers workspaces)
|
|
29
|
-
commit Stage changes and create the release commit
|
|
30
|
-
tag Create annotated git tags from the tags file
|
|
31
|
-
push Push release commit and tags (one push per tag)
|
|
32
|
-
publish Publish packages with release tags on HEAD
|
|
33
|
-
create-github-release Create GitHub Releases from changelog.json for tags on HEAD
|
|
34
|
-
show-tag-prefixes Show derived and declared legacy tag prefixes per workspace
|
|
35
|
-
init Initialize release-kit in the current repository
|
|
36
|
-
update-templates Update the scaffolded workflows to the current templates
|
|
37
|
-
overrides Manage editorial changelog overrides
|
|
38
|
-
sync-labels Manage GitHub label synchronization
|
|
39
|
-
|
|
40
|
-
Options:
|
|
41
|
-
--dry-run Preview changes without writing files
|
|
42
|
-
--help, -h Show this help message
|
|
43
|
-
--version, -V Show the version number
|
|
44
|
-
|
|
45
|
-
Environment:
|
|
46
|
-
${OUTPUT_STYLE_ENV_VAR}
|
|
47
|
-
Output style: auto (default), plain, or rich. auto prints plain,
|
|
48
|
-
without emoji, when CI is set or the stream is not a terminal.
|
|
49
|
-
`);
|
|
50
|
-
}
|
|
51
|
-
function showSyncLabelsHelp() {
|
|
52
|
-
console.info(`
|
|
53
|
-
Usage: release-kit sync-labels <subcommand> [options]
|
|
54
|
-
|
|
55
|
-
Manage GitHub label synchronization via preset and custom label definitions.
|
|
56
|
-
|
|
57
|
-
Subcommands:
|
|
58
|
-
init Scaffold caller workflow and config, then generate labels
|
|
59
|
-
generate Regenerate .github/labels.yaml from config
|
|
60
|
-
sync Trigger the sync-labels workflow via gh CLI
|
|
61
|
-
|
|
62
|
-
Options:
|
|
63
|
-
--help, -h Show this help message
|
|
64
|
-
`);
|
|
65
|
-
}
|
|
66
|
-
function showSyncLabelsInitHelp() {
|
|
67
|
-
console.info(`
|
|
68
|
-
Usage: release-kit sync-labels init [options]
|
|
69
|
-
|
|
70
|
-
Scaffold the sync-labels caller workflow and seed the repoLabels block of
|
|
71
|
-
.config/release-kit.config.ts with scope labels discovered from workspaces and
|
|
72
|
-
retired packages, then generate .github/labels.yaml. When the config file already
|
|
73
|
-
exists, print the block for manual paste instead of rewriting the file.
|
|
74
|
-
|
|
75
|
-
Options:
|
|
76
|
-
--config <path> Config file, relative to the current directory
|
|
77
|
-
(default: .config/release-kit.config.ts at the repo root)
|
|
78
|
-
--dry-run Preview changes without writing files
|
|
79
|
-
--force Overwrite existing files instead of skipping them
|
|
80
|
-
--help, -h Show this help message
|
|
81
|
-
`);
|
|
82
|
-
}
|
|
83
|
-
function showSyncLabelsGenerateHelp() {
|
|
84
|
-
console.info(`
|
|
85
|
-
Usage: release-kit sync-labels generate [options]
|
|
86
|
-
|
|
87
|
-
Regenerate .github/labels.yaml from the repoLabels block of .config/release-kit.config.ts.
|
|
88
|
-
|
|
89
|
-
Options:
|
|
90
|
-
--check Report whether .github/labels.yaml is stale instead of writing it
|
|
91
|
-
--config <path> Config file, relative to the current directory
|
|
92
|
-
(default: .config/release-kit.config.ts at the repo root)
|
|
93
|
-
--help, -h Show this help message
|
|
94
|
-
`);
|
|
95
|
-
}
|
|
96
|
-
function showSyncLabelsSyncHelp() {
|
|
97
|
-
console.info(`
|
|
98
|
-
Usage: release-kit sync-labels sync
|
|
99
|
-
|
|
100
|
-
Trigger the sync-labels GitHub Actions workflow via the gh CLI.
|
|
101
|
-
|
|
102
|
-
Options:
|
|
103
|
-
--help, -h Show this help message
|
|
104
|
-
`);
|
|
105
|
-
}
|
|
106
|
-
function showInitHelp() {
|
|
107
|
-
console.info(`
|
|
108
|
-
Usage: release-kit init [options]
|
|
109
|
-
|
|
110
|
-
Initialize release-kit in the current repository.
|
|
111
|
-
By default, scaffolds only the GitHub Actions workflow files. When every
|
|
112
|
-
package is private, skips publish.yaml and create-github-release.yaml.
|
|
113
|
-
|
|
114
|
-
Options:
|
|
115
|
-
--with-config Also scaffold .config/release-kit.config.ts
|
|
116
|
-
--force Overwrite existing files instead of skipping them
|
|
117
|
-
--dry-run Preview changes without writing files
|
|
118
|
-
--help, -h Show this help message
|
|
119
|
-
`);
|
|
120
|
-
}
|
|
121
|
-
function showUpdateTemplatesHelp() {
|
|
122
|
-
console.info(`
|
|
123
|
-
Usage: release-kit update-templates [options]
|
|
124
|
-
|
|
125
|
-
Update the GitHub Actions workflows that release-kit scaffolds to the templates
|
|
126
|
-
of the installed version, showing what changed in each file. Creates a missing
|
|
127
|
-
workflow that \`init\` would create, and refreshes sync-labels.yaml only when it
|
|
128
|
-
exists. When every package is private, refreshes publish.yaml and
|
|
129
|
-
create-github-release.yaml only when they exist. Keeps publish.yaml's provenance
|
|
130
|
-
setting. Never touches config files.
|
|
131
|
-
|
|
132
|
-
Options:
|
|
133
|
-
--dry-run Preview changes without writing files
|
|
134
|
-
--help, -h Show this help message
|
|
135
|
-
`);
|
|
136
|
-
}
|
|
137
|
-
function showCommitHelp() {
|
|
138
|
-
console.info(`
|
|
139
|
-
Usage: release-kit commit [options]
|
|
140
|
-
|
|
141
|
-
Stage all changes and create the release commit using tags and summary
|
|
142
|
-
produced by \`prepare\`.
|
|
143
|
-
|
|
144
|
-
Options:
|
|
145
|
-
--dry-run Preview the commit message without creating it
|
|
146
|
-
--help, -h Show this help message
|
|
147
|
-
`);
|
|
148
|
-
}
|
|
149
|
-
function showTagHelp() {
|
|
150
|
-
console.info(`
|
|
151
|
-
Usage: release-kit tag [options]
|
|
152
|
-
|
|
153
|
-
Create annotated git tags from the tags file produced by \`prepare\`.
|
|
154
|
-
|
|
155
|
-
Options:
|
|
156
|
-
--dry-run Preview without creating tags
|
|
157
|
-
--no-git-checks Skip dirty working tree check
|
|
158
|
-
--help, -h Show this help message
|
|
159
|
-
`);
|
|
160
|
-
}
|
|
161
|
-
function showPushHelp() {
|
|
162
|
-
console.info(`
|
|
163
|
-
Usage: release-kit push [options]
|
|
164
|
-
|
|
165
|
-
Push the release commit and each tag individually, so that GitHub Actions
|
|
166
|
-
starts a separate workflow run for each tag.
|
|
167
|
-
|
|
168
|
-
Options:
|
|
169
|
-
--config <path> Config file, relative to the current directory
|
|
170
|
-
(default: .config/release-kit.config.ts at the repo root)
|
|
171
|
-
--dry-run Preview without pushing
|
|
172
|
-
--tags=tag1,tag2 Only push the named tags (comma-separated, full tag names)
|
|
173
|
-
--tags-only Skip the branch push (push tags only)
|
|
174
|
-
--help, -h Show this help message
|
|
175
|
-
`);
|
|
176
|
-
}
|
|
177
|
-
function showCreateGithubReleaseHelp() {
|
|
178
|
-
console.info(`
|
|
179
|
-
Usage: release-kit create-github-release [options]
|
|
180
|
-
|
|
181
|
-
Create GitHub Releases from changelog.json for tags on HEAD. Private
|
|
182
|
-
(package.json#private) workspaces are skipped with a warning, and the command
|
|
183
|
-
doesn't create a Release for them. A project tag gets a Release even when the
|
|
184
|
-
root package is private.
|
|
185
|
-
|
|
186
|
-
Options:
|
|
187
|
-
--config <path> Config file, relative to the current directory
|
|
188
|
-
(default: .config/release-kit.config.ts at the repo root)
|
|
189
|
-
--dry-run Preview without creating releases
|
|
190
|
-
--tags=tag1,tag2 Only create releases for the named tags (comma-separated, full tag names)
|
|
191
|
-
--help, -h Show this help message
|
|
192
|
-
`);
|
|
193
|
-
}
|
|
194
|
-
function showShowTagPrefixesHelp() {
|
|
195
|
-
console.info(`
|
|
196
|
-
Usage: release-kit show-tag-prefixes [options]
|
|
197
|
-
|
|
198
|
-
Print a per-workspace table of derived tag prefixes, tag counts, and declared
|
|
199
|
-
legacy tag prefixes. Reports any release-shaped tags whose prefix is neither a
|
|
200
|
-
derived prefix nor declared in \`legacyIdentities\`, with a copy-pasteable
|
|
201
|
-
config snippet.
|
|
202
|
-
|
|
203
|
-
Options:
|
|
204
|
-
--config <path> Config file, relative to the current directory
|
|
205
|
-
(default: .config/release-kit.config.ts at the repo root)
|
|
206
|
-
--help, -h Show this help message
|
|
207
|
-
`);
|
|
208
|
-
}
|
|
209
|
-
function showOverridesHelp() {
|
|
210
|
-
console.info(`
|
|
211
|
-
Usage: release-kit overrides <subcommand> [options]
|
|
212
|
-
|
|
213
|
-
Manage editorial changelog overrides.
|
|
214
|
-
|
|
215
|
-
Subcommands:
|
|
216
|
-
validate Validate every \`.meta/changelog-overrides.json\` file across all scopes
|
|
217
|
-
|
|
218
|
-
Options:
|
|
219
|
-
--help, -h Show this help message
|
|
220
|
-
`);
|
|
221
|
-
}
|
|
222
|
-
function showOverridesValidateHelp() {
|
|
223
|
-
console.info(`
|
|
224
|
-
Usage: release-kit overrides validate
|
|
225
|
-
|
|
226
|
-
Validate every \`.meta/changelog-overrides.json\` file across the project and per-workspace
|
|
227
|
-
scopes. Reports schema/parse errors, ambiguous-prefix errors, conflicting-key errors, and
|
|
228
|
-
stale-key warnings.
|
|
229
|
-
|
|
230
|
-
Exit codes:
|
|
231
|
-
0 Clean: no errors, no stale keys
|
|
232
|
-
1 Stale-key warnings only (no errors)
|
|
233
|
-
2 Schema/parse, ambiguous-prefix, or conflicting-key errors (errors take precedence)
|
|
234
|
-
|
|
235
|
-
Options:
|
|
236
|
-
--config <path> Config file, relative to the current directory
|
|
237
|
-
(default: .config/release-kit.config.ts at the repo root)
|
|
238
|
-
--help, -h Show this help message
|
|
239
|
-
`);
|
|
240
|
-
}
|
|
241
|
-
function showPublishHelp() {
|
|
242
|
-
console.info(`
|
|
243
|
-
Usage: release-kit publish [options]
|
|
244
|
-
|
|
245
|
-
Publish packages that have release tags on HEAD. Operates only on workspaces whose
|
|
246
|
-
package.json#private is absent or false. Without --tags, unpublishable workspaces are
|
|
247
|
-
silently filtered out. With --tags, an unpublishable tag is skipped with a warning while
|
|
248
|
-
any publishable tags are still published. A project tag is never published.
|
|
249
|
-
|
|
250
|
-
Options:
|
|
251
|
-
--config <path> Config file, relative to the current directory
|
|
252
|
-
(default: .config/release-kit.config.ts at the repo root)
|
|
253
|
-
--dry-run Preview without publishing
|
|
254
|
-
--no-git-checks Skip the clean-working-tree check
|
|
255
|
-
--tags=tag1,tag2 Only publish the named tags (comma-separated, full tag names)
|
|
256
|
-
--provenance Generate provenance statement (requires OIDC, not supported by classic yarn)
|
|
257
|
-
--help, -h Show this help message
|
|
258
|
-
`);
|
|
259
|
-
}
|
|
260
28
|
function enterRepoRootOrExit() {
|
|
261
29
|
try {
|
|
262
30
|
return enterRepoRoot();
|
|
@@ -1,14 +1,7 @@
|
|
|
1
|
+
import { type ChangelogDiagnostics } from './buildChangelogItem.js';
|
|
1
2
|
import { type RawCommit } from './enumerateReleaseWindows.js';
|
|
2
3
|
import type { GenerateChangelogOptions } from './generateChangelogs.js';
|
|
3
|
-
import type { ChangelogEntry, ChangelogSection,
|
|
4
|
-
/**
|
|
5
|
-
* Strips a section title down to its bare name.
|
|
6
|
-
*
|
|
7
|
-
* A default title has a leading emoji (e.g. `"🐛 Bug fixes"`), while a consumer's
|
|
8
|
-
* `devOnlySections` or `workTypes` override may be written as a bare name. Comparing both sides
|
|
9
|
-
* through this helper lets the two forms match.
|
|
10
|
-
*/
|
|
11
|
-
export declare function stripGroupDecorations(group: string): string;
|
|
4
|
+
import type { ChangelogEntry, ChangelogSection, ReleaseSettings, ReleaseType } from './types.js';
|
|
12
5
|
/**
|
|
13
6
|
* Builds structured changelog entries from the release windows of git history, naming the unreleased window `tag`.
|
|
14
7
|
*
|
|
@@ -18,18 +11,6 @@ export declare function buildChangelogEntries(config: ReleaseHistoryConfig, tag:
|
|
|
18
11
|
entries: ChangelogEntry[];
|
|
19
12
|
diagnostics: ChangelogDiagnostics;
|
|
20
13
|
};
|
|
21
|
-
/** What reading the unreleased window reports beyond its items. */
|
|
22
|
-
export interface ChangelogDiagnostics {
|
|
23
|
-
malformedBlocks: MalformedChangeRecordBlock[];
|
|
24
|
-
/** Breaking-policy violations of the window's titles and change-record entries. */
|
|
25
|
-
policyViolations: PolicyViolation[];
|
|
26
|
-
undeclaredEntryTypes: UndeclaredEntryType[];
|
|
27
|
-
/**
|
|
28
|
-
* Entry scopes that don't route to any workspace. A read leaves it empty: Only a pass over every workspace can fill
|
|
29
|
-
* it.
|
|
30
|
-
*/
|
|
31
|
-
unroutedEntryScopes: UnroutedEntryScope[];
|
|
32
|
-
}
|
|
33
14
|
/**
|
|
34
15
|
* Reads a scope's release windows once and returns the changelog items of every window, with what the unreleased
|
|
35
16
|
* window decides: its commits, its bump, and its diagnostics.
|
|
@@ -40,8 +21,6 @@ export interface ChangelogDiagnostics {
|
|
|
40
21
|
* released windows were reported when they were prepared.
|
|
41
22
|
*/
|
|
42
23
|
export declare function readReleaseHistory(config: ReleaseHistoryConfig, options: GenerateChangelogOptions): ReleaseHistory;
|
|
43
|
-
/** The configuration that `readReleaseHistory` reads. */
|
|
44
|
-
export type ReleaseHistoryConfig = Pick<ReleaseSettings, 'breakingPolicies' | 'changelogJson' | 'scopeAliases' | 'versionPatterns' | 'workTypes'>;
|
|
45
24
|
/** One read of a scope's release windows. */
|
|
46
25
|
export interface ReleaseHistory {
|
|
47
26
|
/** The newest matching tag that HEAD reaches; undefined when none does. */
|
|
@@ -50,6 +29,24 @@ export interface ReleaseHistory {
|
|
|
50
29
|
releasedEntries: ChangelogEntry[];
|
|
51
30
|
unreleased: UnreleasedWindowReading;
|
|
52
31
|
}
|
|
32
|
+
/** The configuration that `readReleaseHistory` reads. */
|
|
33
|
+
export type ReleaseHistoryConfig = Pick<ReleaseSettings, 'breakingPolicies' | 'changelogJson' | 'scopeAliases' | 'versionPatterns' | 'workTypes'>;
|
|
34
|
+
/**
|
|
35
|
+
* Strips a section title down to its bare name.
|
|
36
|
+
*
|
|
37
|
+
* A default title has a leading emoji (e.g. `"🐛 Bug fixes"`), while a consumer's
|
|
38
|
+
* `devOnlySections` or `workTypes` override may be written as a bare name. Comparing both sides
|
|
39
|
+
* through this helper lets the two forms match.
|
|
40
|
+
*/
|
|
41
|
+
export declare function stripGroupDecorations(group: string): string;
|
|
42
|
+
/** Labels the unreleased window of `history` with `tag` and returns the entries of every window, newest first. */
|
|
43
|
+
export declare function toChangelogEntries(history: ReleaseHistory, tag: string): ChangelogEntry[];
|
|
44
|
+
/**
|
|
45
|
+
* Returns the entries that a direct release tagged `tag` records: those of `toChangelogEntries`, or, when the
|
|
46
|
+
* unreleased window doesn't yield any item, the synthetic "Forced version bump." entry dated `today` ahead of the
|
|
47
|
+
* released entries.
|
|
48
|
+
*/
|
|
49
|
+
export declare function toReleaseEntries(history: ReleaseHistory, tag: string, today: string): ChangelogEntry[];
|
|
53
50
|
/** The unreleased window: its changelog sections and commits, and the bump and diagnostics that they determine. */
|
|
54
51
|
export interface UnreleasedWindowReading {
|
|
55
52
|
/** The highest bump that the window's items call for; undefined when the window doesn't yield any item. */
|
|
@@ -68,11 +65,3 @@ export interface UnreleasedWindowReading {
|
|
|
68
65
|
*/
|
|
69
66
|
unparseableCommits: RawCommit[] | undefined;
|
|
70
67
|
}
|
|
71
|
-
/** Labels the unreleased window of `history` with `tag` and returns the entries of every window, newest first. */
|
|
72
|
-
export declare function toChangelogEntries(history: ReleaseHistory, tag: string): ChangelogEntry[];
|
|
73
|
-
/**
|
|
74
|
-
* Returns the entries that a direct release tagged `tag` records: those of `toChangelogEntries`, or, when the
|
|
75
|
-
* unreleased window doesn't yield any item, the synthetic "Forced version bump." entry dated `today` ahead of the
|
|
76
|
-
* released entries.
|
|
77
|
-
*/
|
|
78
|
-
export declare function toReleaseEntries(history: ReleaseHistory, tag: string, today: string): ChangelogEntry[];
|