@williamthorsen/release-kit 10.4.4 → 10.6.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 +1502 -0
- package/.readyup/kits/default.js +120 -4
- package/.readyup/kits/npm-auto-publish.js +11 -3
- package/.readyup/manifest.json +16 -11
- package/CHANGELOG.md +57 -0
- package/README.md +64 -4
- package/dist/esm/assertCleanWorkingTree.d.ts +5 -0
- package/dist/esm/buildChangelogEntries.d.ts +22 -0
- package/dist/esm/buildChangelogEntries.js +5 -0
- package/dist/esm/buildDependencyGraph.d.ts +16 -0
- package/dist/esm/buildEmptyReleaseEntry.d.ts +8 -0
- package/dist/esm/buildReleaseSummary.d.ts +10 -0
- package/dist/esm/buildSyntheticChangelogEntry.d.ts +6 -0
- package/dist/esm/bumpVersion.d.ts +8 -0
- package/dist/esm/changelogJsonFile.d.ts +11 -0
- package/dist/esm/changelogJsonUtils.d.ts +16 -2
- package/dist/esm/changelogJsonUtils.js +0 -13
- package/dist/esm/changelogOverrides.d.ts +143 -0
- package/dist/esm/changelogOverrides.js +8 -0
- package/dist/esm/checkWorkTypesDrift.d.ts +25 -0
- package/dist/esm/collectPolicyViolations.d.ts +9 -0
- package/dist/esm/commitCommand.d.ts +6 -0
- package/dist/esm/compareVersions.d.ts +7 -0
- package/dist/esm/createGithubRelease.d.ts +30 -0
- package/dist/esm/createGithubReleaseCommand.d.ts +7 -0
- package/dist/esm/createTags.d.ts +5 -0
- package/dist/esm/decideRelease.d.ts +37 -0
- package/dist/esm/defaults.d.ts +25 -0
- package/dist/esm/defineConfig.d.ts +9 -0
- package/dist/esm/deleteFileIfExists.d.ts +1 -0
- package/dist/esm/deriveWorkspaceConfig.d.ts +9 -0
- package/dist/esm/detectPackageManager.d.ts +6 -0
- package/dist/esm/detectUndeclaredTagPrefixes.d.ts +18 -0
- package/dist/esm/determineBumpFromCommits.d.ts +5 -0
- package/dist/esm/determineBumpType.d.ts +12 -0
- package/dist/esm/discoverWorkspaces.d.ts +12 -0
- package/dist/esm/extractMigration.d.ts +14 -0
- package/dist/esm/extractMigration.js +18 -0
- package/dist/esm/format.d.ts +3 -0
- package/dist/esm/formatPrivateSkip.d.ts +6 -0
- package/dist/esm/generateChangelogs.d.ts +25 -0
- package/dist/esm/getCommitsSinceTarget.d.ts +16 -0
- package/dist/esm/hasPrettierConfig.d.ts +6 -0
- package/dist/esm/help/prepareHelp.d.ts +6 -0
- package/dist/esm/init/checks.d.ts +4 -0
- package/dist/esm/init/detectRepoType.d.ts +7 -0
- package/dist/esm/init/initCommand.d.ts +6 -0
- package/dist/esm/init/parseJsonRecord.d.ts +4 -0
- package/dist/esm/init/scaffold.d.ts +3 -1
- package/dist/esm/init/templates.d.ts +13 -0
- package/dist/esm/injectReleaseNotesIntoReadme.d.ts +39 -0
- package/dist/esm/injectSection.d.ts +6 -0
- package/dist/esm/loadConfig.d.ts +46 -0
- package/dist/esm/loadValidatedConfig.d.ts +8 -0
- package/dist/esm/packsPath.d.ts +15 -0
- package/dist/esm/packsPath.js +47 -0
- package/dist/esm/parseCommitMessage.d.ts +42 -0
- package/dist/esm/parseRequestedTags.d.ts +7 -0
- package/dist/esm/planReleaseNotesPreviews.d.ts +20 -0
- package/dist/esm/planVersionBump.d.ts +12 -0
- package/dist/esm/prepareCommand.d.ts +10 -0
- package/dist/esm/previewTagPrefixes.d.ts +21 -1
- package/dist/esm/propagateBumps.d.ts +15 -0
- package/dist/esm/publish.d.ts +1 -0
- package/dist/esm/publishCommand.d.ts +4 -0
- package/dist/esm/pushCommand.d.ts +4 -0
- package/dist/esm/pushRelease.d.ts +6 -0
- package/dist/esm/readCurrentVersion.d.ts +1 -0
- package/dist/esm/releaseFiles.d.ts +22 -0
- package/dist/esm/releasePlan.d.ts +23 -0
- package/dist/esm/releasePrepare.d.ts +40 -0
- package/dist/esm/releasePrepare.js +0 -3
- package/dist/esm/releasePrepareMono.d.ts +8 -0
- package/dist/esm/releasePrepareMono.js +0 -4
- package/dist/esm/releasePrepareProject.d.ts +42 -0
- package/dist/esm/renderChangelogMarkdown.d.ts +17 -0
- package/dist/esm/renderReleaseNotes.d.ts +25 -0
- package/dist/esm/reportPrepare.d.ts +14 -0
- package/dist/esm/reportPrepare.js +4 -2
- package/dist/esm/resolveCliffConfigPath.d.ts +10 -0
- package/dist/esm/resolveCommandTags.d.ts +13 -1
- package/dist/esm/resolveReleaseNotesConfig.d.ts +14 -0
- package/dist/esm/resolveReleaseTags.d.ts +22 -0
- package/dist/esm/runGitCliff.d.ts +37 -1
- package/dist/esm/runGitCliff.js +4 -10
- package/dist/esm/showTagPrefixesCommand.d.ts +11 -0
- package/dist/esm/stripScope.d.ts +7 -0
- package/dist/esm/sync-labels/generateCommand.d.ts +17 -0
- package/dist/esm/sync-labels/initCommand.d.ts +9 -0
- package/dist/esm/sync-labels/presets.d.ts +6 -0
- package/dist/esm/sync-labels/resolveLabels.d.ts +10 -0
- package/dist/esm/sync-labels/retiredConfig.d.ts +8 -0
- package/dist/esm/sync-labels/syncCommand.d.ts +6 -0
- package/dist/esm/sync-labels/templates.d.ts +14 -0
- package/dist/esm/sync-labels/types.d.ts +4 -0
- package/dist/esm/syncWorkTypes.d.ts +18 -0
- package/dist/esm/tagCommand.d.ts +1 -0
- package/dist/esm/typeGuards.d.ts +2 -0
- package/dist/esm/types.d.ts +302 -0
- package/dist/esm/validateConfig.d.ts +14 -1
- package/dist/esm/validateOnlyExcludesStrandedDependents.d.ts +21 -0
- package/dist/esm/validateOverridesCommand.d.ts +30 -0
- package/dist/esm/workTypesData.d.ts +27 -0
- package/dist/esm/workTypesUtils.d.ts +17 -0
- package/package.json +12 -11
|
@@ -1,18 +1,5 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
2
|
import { isRecord, isUnknownArray } from "./typeGuards.js";
|
|
3
|
-
export function isChangelogItem(value) {
|
|
4
|
-
if (!isRecord(value))
|
|
5
|
-
return false;
|
|
6
|
-
if (typeof value['description'] !== 'string')
|
|
7
|
-
return false;
|
|
8
|
-
if (value['body'] !== undefined && typeof value['body'] !== 'string')
|
|
9
|
-
return false;
|
|
10
|
-
if (value['breaking'] !== undefined && typeof value['breaking'] !== 'boolean')
|
|
11
|
-
return false;
|
|
12
|
-
if (value['hash'] !== undefined && typeof value['hash'] !== 'string')
|
|
13
|
-
return false;
|
|
14
|
-
return true;
|
|
15
|
-
}
|
|
16
3
|
export function isChangelogEntry(value) {
|
|
17
4
|
return (isRecord(value) &&
|
|
18
5
|
typeof value['version'] === 'string' &&
|
|
@@ -1,53 +1,196 @@
|
|
|
1
1
|
import type { ChangelogEntry, ChangelogOverride, WorkspaceConfig } from './types.js';
|
|
2
|
+
/** Result of loading an override file: either parsed overrides or a list of structured errors. */
|
|
2
3
|
export type LoadChangelogOverridesResult = {
|
|
3
4
|
overrides: Map<string, ChangelogOverride>;
|
|
4
5
|
} | {
|
|
5
6
|
errors: string[];
|
|
6
7
|
};
|
|
8
|
+
/**
|
|
9
|
+
* Load and validate the editorial overrides file at `path`.
|
|
10
|
+
*
|
|
11
|
+
* - Missing file resolves to an empty map (no-op default; matches "absent file → unchanged behavior").
|
|
12
|
+
* - Malformed JSON, wrong top-level shape, or any per-entry validation failure surfaces as
|
|
13
|
+
* structured errors. Callers decide how to surface them.
|
|
14
|
+
*
|
|
15
|
+
* Returns either `{ overrides: Map }` on success or `{ errors: string[] }` on failure. Pure
|
|
16
|
+
* except for the single file read; performs no other I/O.
|
|
17
|
+
*/
|
|
7
18
|
export declare function loadChangelogOverrides(path: string): LoadChangelogOverridesResult;
|
|
19
|
+
/**
|
|
20
|
+
* Validate a parsed override record. Returns the parsed `Map` along with any error messages.
|
|
21
|
+
*
|
|
22
|
+
* Each error names the offending key (e.g. `overrides['abc']: 'audience' must be one of …`)
|
|
23
|
+
* so the consumer can locate it in their override file.
|
|
24
|
+
*/
|
|
8
25
|
export declare function validateChangelogOverrides(raw: unknown): {
|
|
9
26
|
overrides: Map<string, ChangelogOverride>;
|
|
10
27
|
errors: string[];
|
|
11
28
|
};
|
|
29
|
+
/**
|
|
30
|
+
* Format the standard "stale override key" warning. Callers compute the set of stale keys
|
|
31
|
+
* (keys that didn't match anywhere) and use this helper to surface them uniformly. Centralized
|
|
32
|
+
* so single-package and monorepo flows produce identical warning text.
|
|
33
|
+
*/
|
|
12
34
|
export declare function formatStaleOverrideKeyWarning(key: string): string;
|
|
35
|
+
/**
|
|
36
|
+
* Apply overrides to a `ChangelogEntry[]`, returning a new array. Pure: no mutation, no I/O.
|
|
37
|
+
*
|
|
38
|
+
* Match algorithm: each override key is treated as a string-prefix against `ChangelogItem.hash`.
|
|
39
|
+
* - 0 matches → key is recorded as unmatched in this batch (no warning emitted here).
|
|
40
|
+
* - 1 match → apply each present override field to the matched item, record key as matched.
|
|
41
|
+
* - 2+ matches → error (ambiguous prefix).
|
|
42
|
+
*
|
|
43
|
+
* `matchedKeys` lists the override keys that resolved to exactly one item in this batch.
|
|
44
|
+
* Callers are responsible for computing stale-key warnings: in a monorepo run, an override
|
|
45
|
+
* may target a commit that lives in another workspace, so the per-batch zero-match signal is
|
|
46
|
+
* insufficient on its own. Single-package and monorepo orchestrators format warnings using
|
|
47
|
+
* `formatStaleOverrideKeyWarning` after aggregating `matchedKeys` across all apply calls.
|
|
48
|
+
*
|
|
49
|
+
* v1 audience semantics:
|
|
50
|
+
* - `'skip'` removes the matched item from its containing section. Empty sections are pruned.
|
|
51
|
+
* Versions with zero sections still appear (matches existing "empty workspace" behavior).
|
|
52
|
+
* - `'all'` and `'dev'` are validated out before reaching the applier.
|
|
53
|
+
*
|
|
54
|
+
* Items without a `hash` (synthetic propagation entries) are never matched and pass through.
|
|
55
|
+
*
|
|
56
|
+
* The function does not throw; warnings/errors accumulate and are returned alongside the
|
|
57
|
+
* transformed entries so the caller decides whether to abort or log-and-continue.
|
|
58
|
+
*/
|
|
13
59
|
export declare function applyChangelogOverrides(entries: ChangelogEntry[], overrides: Map<string, ChangelogOverride>): {
|
|
14
60
|
entries: ChangelogEntry[];
|
|
15
61
|
warnings: string[];
|
|
16
62
|
errors: string[];
|
|
17
63
|
matchedKeys: string[];
|
|
18
64
|
};
|
|
65
|
+
/**
|
|
66
|
+
* Resolve the conventional override-file path for a given scope root.
|
|
67
|
+
*
|
|
68
|
+
* `scopeRoot` is the directory at which a scope's other artifacts live (e.g., `'.'` for the
|
|
69
|
+
* project, `'packages/foo'` for a workspace). The returned path is repo-relative.
|
|
70
|
+
*/
|
|
19
71
|
export declare function resolveOverridePath(scopeRoot: string): string;
|
|
72
|
+
/** Result of {@link loadOverridesForScopes}: per-scope maps plus accumulated load/validation errors. */
|
|
20
73
|
export interface LoadOverridesForScopesResult {
|
|
74
|
+
/** Project-tier (root) overrides. Empty map when the project file is absent. */
|
|
21
75
|
project: Map<string, ChangelogOverride>;
|
|
76
|
+
/** Workspace-tier overrides keyed by `workspacePath` (e.g., `'packages/foo'`). Empty map when absent. */
|
|
22
77
|
perWorkspace: Map<string, Map<string, ChangelogOverride>>;
|
|
78
|
+
/** All load and validation errors across every requested scope, prefixed with the offending file path. */
|
|
23
79
|
errors: string[];
|
|
24
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Load and validate every requested override file in one pass.
|
|
83
|
+
*
|
|
84
|
+
* Iterates the configured scope roots, calls {@link loadChangelogOverrides} for each, and
|
|
85
|
+
* aggregates errors across all files (rather than throwing on the first failure) so a
|
|
86
|
+
* consumer who edits multiple files at once sees every problem in one report. Missing files
|
|
87
|
+
* resolve to empty maps — matches the existing single-file behavior.
|
|
88
|
+
*
|
|
89
|
+
* The caller is expected to surface a combined error when `errors.length > 0` and abort the
|
|
90
|
+
* release before any workspace begins writing.
|
|
91
|
+
*/
|
|
25
92
|
export declare function loadOverridesForScopes(scopes: {
|
|
26
93
|
project?: string;
|
|
27
94
|
workspaces?: string[];
|
|
28
95
|
}): LoadOverridesForScopesResult;
|
|
96
|
+
/**
|
|
97
|
+
* Compose root and workspace override maps into a single effective map for one workspace.
|
|
98
|
+
*
|
|
99
|
+
* Byte-equal-key shadowing: when a workspace key string-equals a root key, the workspace
|
|
100
|
+
* entry wins entirely (no field-level merge) and supplants the root entry in the result.
|
|
101
|
+
* Different-prefix keys that happen to resolve to the same commit do NOT shadow here — they
|
|
102
|
+
* fall through to the existing ambiguous-prefix error in {@link applyChangelogOverrides}.
|
|
103
|
+
*
|
|
104
|
+
* Pure: never mutates inputs.
|
|
105
|
+
*/
|
|
29
106
|
export declare function composeOverrides(rootEntries: Map<string, ChangelogOverride>, workspaceEntries: Map<string, ChangelogOverride> | undefined): Map<string, ChangelogOverride>;
|
|
107
|
+
/**
|
|
108
|
+
* Shared override-application context threaded through the per-workspace and project apply
|
|
109
|
+
* sites. Bundles the loaded per-scope maps with the run-scoped warning aggregators so each
|
|
110
|
+
* call site can both consume the maps it needs and report into the same warning channel.
|
|
111
|
+
*
|
|
112
|
+
* `globalMatchedRootKeys` tracks ROOT keys matched in any apply call. Workspace-sourced
|
|
113
|
+
* matched keys are not added here — they're tracked locally per workspace because their
|
|
114
|
+
* stale-key semantics are local (a workspace key that doesn't match in its own workspace is
|
|
115
|
+
* unambiguously stale and is warned immediately, not aggregated to end-of-run).
|
|
116
|
+
*/
|
|
30
117
|
export interface OverrideContext {
|
|
31
118
|
project: Map<string, ChangelogOverride>;
|
|
32
119
|
perWorkspace: Map<string, Map<string, ChangelogOverride>>;
|
|
33
120
|
overrideWarnings: string[];
|
|
34
121
|
globalMatchedRootKeys: Set<string>;
|
|
35
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* Load all per-scope override files (root + every workspace) in one upfront pass, validate
|
|
125
|
+
* them, and bundle the results with run-scoped warning aggregators. Aborts the release with
|
|
126
|
+
* a clear error when any file is malformed — checked-in editorial config that does not parse
|
|
127
|
+
* is a bug, and we want the prepare run to fail before any workspace begins writing.
|
|
128
|
+
*/
|
|
36
129
|
export declare function createOverrideContext(workspaces: WorkspaceConfig[]): OverrideContext;
|
|
130
|
+
/** Per-scope input to {@link validateAllChangelogOverrides}. */
|
|
37
131
|
export interface ChangelogOverrideScope {
|
|
132
|
+
/** Path to the override file (relative to the repo root). Used to load the file and to attribute findings. */
|
|
38
133
|
filePath: string;
|
|
134
|
+
/** Commit hashes in this scope's history window. Each override key is matched against these. */
|
|
39
135
|
hashes: readonly string[];
|
|
40
136
|
}
|
|
137
|
+
/** Inputs to {@link validateAllChangelogOverrides}. */
|
|
41
138
|
export interface ValidateAllChangelogOverridesInputs {
|
|
139
|
+
/**
|
|
140
|
+
* Project-tier scope (the override file at the repo root).
|
|
141
|
+
*
|
|
142
|
+
* The file at `filePath` is loaded once and used in two ways:
|
|
143
|
+
* - Its overrides are composed into every workspace's apply (root-tier overrides apply globally).
|
|
144
|
+
* - When `hashes` is provided, the project map is also applied directly to that hash universe
|
|
145
|
+
* (project release in monorepo mode, or the package's history in single-package mode).
|
|
146
|
+
*
|
|
147
|
+
* Omit when no project file exists (rare — most repos have a root file even if empty).
|
|
148
|
+
*/
|
|
42
149
|
project?: {
|
|
43
150
|
filePath: string;
|
|
44
151
|
hashes?: readonly string[];
|
|
45
152
|
};
|
|
153
|
+
/** Per-workspace scopes. Each workspace's file applies only to its own hash universe. */
|
|
46
154
|
workspaces?: readonly ChangelogOverrideScope[];
|
|
47
155
|
}
|
|
156
|
+
/** Result of {@link validateAllChangelogOverrides}: aggregated errors and warnings, each prefixed with the file path it pertains to. */
|
|
48
157
|
export interface ValidateAllChangelogOverridesResult {
|
|
49
158
|
errors: string[];
|
|
50
159
|
warnings: string[];
|
|
51
160
|
}
|
|
161
|
+
/**
|
|
162
|
+
* End-to-end health check across every override file and scope. Pure: takes already-collected
|
|
163
|
+
* hash universes and returns aggregated findings. The CLI command and any other consumer
|
|
164
|
+
* (programmatic library callers, future composite checks) wrap this with discovery and I/O.
|
|
165
|
+
*
|
|
166
|
+
* When invoked via the standard `validateOverridesCommand` entry point, each scope's
|
|
167
|
+
* `hashes` is built by `buildChangelogEntries` — the same path `release-kit prepare` walks —
|
|
168
|
+
* so the match-set is byte-equal to what `prepare` would compute. The tier asymmetry is part
|
|
169
|
+
* of that contract: workspace-tier keys are stale if they don't match in their own workspace;
|
|
170
|
+
* root-tier keys are stale only if they don't match in any scope (no workspace AND not the
|
|
171
|
+
* project release window). Library callers that construct `inputs` directly are responsible
|
|
172
|
+
* for supplying the same hash universes if they want this guarantee.
|
|
173
|
+
*
|
|
174
|
+
* Every returned string is prefixed with the relative override-file path it pertains to so
|
|
175
|
+
* consumers can locate the offending file without further structuring.
|
|
176
|
+
*/
|
|
52
177
|
export declare function validateAllChangelogOverrides(inputs: ValidateAllChangelogOverridesInputs): ValidateAllChangelogOverridesResult;
|
|
178
|
+
/**
|
|
179
|
+
* Apply the composed (root + workspace) override map to a workspace's changelog entries and
|
|
180
|
+
* report stale-key warnings tier-by-tier.
|
|
181
|
+
*
|
|
182
|
+
* The composed map is applied in a single {@link applyChangelogOverrides} call. Matched keys
|
|
183
|
+
* are demultiplexed by source via `Map.has` lookups on the original (uncomposed) maps so the
|
|
184
|
+
* stale-key semantics stay tier-aware:
|
|
185
|
+
*
|
|
186
|
+
* - Workspace-sourced keys (those present in the per-workspace map, regardless of whether
|
|
187
|
+
* the root map also has the same byte-equal key) that did NOT match are unambiguously
|
|
188
|
+
* stale in their own apply context — push an immediate stale warning naming the key.
|
|
189
|
+
* - Root-sourced matched keys (present in root, absent from this workspace's map) are added
|
|
190
|
+
* to `globalMatchedRootKeys` so the orchestrator's end-of-run loop can dedupe across
|
|
191
|
+
* batches and warn only on root keys that matched nowhere.
|
|
192
|
+
*
|
|
193
|
+
* Throws when any apply call surfaces an error (e.g. ambiguous prefix). Returns the applied
|
|
194
|
+
* result so the caller can consume `applied.entries` for downstream rendering.
|
|
195
|
+
*/
|
|
53
196
|
export declare function applyWorkspaceOverrides(newEntries: ChangelogEntry[], workspacePath: string, overrideContext: OverrideContext): ReturnType<typeof applyChangelogOverrides>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { describeError } from '@williamthorsen/toolbelt.errors';
|
|
4
|
+
import { extractMigration } from "./extractMigration.js";
|
|
4
5
|
import { isRecord } from "./typeGuards.js";
|
|
5
6
|
const OVERRIDES_FILENAME = '.meta/changelog-overrides.json';
|
|
6
7
|
const VALID_AUDIENCE_VALUES = new Set(['all', 'dev', 'skip']);
|
|
@@ -206,6 +207,13 @@ function applyOverrideToItem(item, override) {
|
|
|
206
207
|
}
|
|
207
208
|
if (override.body !== undefined) {
|
|
208
209
|
result.body = override.body;
|
|
210
|
+
const migration = extractMigration(override.body);
|
|
211
|
+
if (migration === undefined) {
|
|
212
|
+
delete result.migration;
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
result.migration = migration;
|
|
216
|
+
}
|
|
209
217
|
}
|
|
210
218
|
if (override.breaking !== undefined) {
|
|
211
219
|
result.breaking = override.breaking;
|
|
@@ -1,11 +1,36 @@
|
|
|
1
|
+
/** URL of the upstream canonical `work-types.json` published by codeassembly. */
|
|
1
2
|
export declare const UPSTREAM_WORK_TYPES_URL = "https://raw.githubusercontent.com/williamthorsen/codeassembly/main/packages/agents/content/skills/_data/work-types.json";
|
|
3
|
+
/** Outcome of a drift check, paired with a human-readable message. */
|
|
2
4
|
export interface DriftCheckResult {
|
|
5
|
+
/**
|
|
6
|
+
* Process exit code semantics:
|
|
7
|
+
* - `0` — match (or upstream missing/transitional, with a warning).
|
|
8
|
+
* - `1` — drift detected.
|
|
9
|
+
* - `2` — network error.
|
|
10
|
+
* - `3` — schema mismatch (upstream JSON does not parse or fails the schema invariants).
|
|
11
|
+
*/
|
|
3
12
|
exitCode: 0 | 1 | 2 | 3;
|
|
4
13
|
message: string;
|
|
5
14
|
}
|
|
15
|
+
/** Minimal injection seam so unit tests can substitute a deterministic fetcher. */
|
|
6
16
|
export interface CheckWorkTypesDriftDependencies {
|
|
17
|
+
/** Absolute path of the local `work-types.json`. Defaults to the bundled file. */
|
|
7
18
|
localPath?: string;
|
|
19
|
+
/** HTTP fetcher. Defaults to global `fetch` (Node 18+). */
|
|
8
20
|
fetch?: typeof globalThis.fetch;
|
|
21
|
+
/** Override the upstream URL (used by tests; production callers should leave default). */
|
|
9
22
|
upstreamUrl?: string;
|
|
10
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Compare the bundled `work-types.json` against the upstream codeassembly canonical and
|
|
26
|
+
* report drift.
|
|
27
|
+
*
|
|
28
|
+
* Failure modes:
|
|
29
|
+
* - Network error → exit 2 with a diagnostic.
|
|
30
|
+
* - Upstream 404 → exit 0 with a transitional warning (codeassembly hasn't published the
|
|
31
|
+
* JSON yet; the check is informational while migration is in flight).
|
|
32
|
+
* - Schema mismatch → exit 3 with a diagnostic.
|
|
33
|
+
* - Drift → exit 1 with a unified-diff-style message.
|
|
34
|
+
* - Match → exit 0.
|
|
35
|
+
*/
|
|
11
36
|
export declare function checkWorkTypesDrift(dependencies?: CheckWorkTypesDriftDependencies): Promise<DriftCheckResult>;
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import type { PolicyViolationHandler } from './parseCommitMessage.js';
|
|
2
2
|
import type { PolicyViolation } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Build a fresh `policyViolations` accumulator paired with the `onPolicyViolation` callback
|
|
5
|
+
* that pushes structured entries into it.
|
|
6
|
+
*
|
|
7
|
+
* Used by all three release-prepare orchestrators (`releasePrepare`, `releasePrepareMono`,
|
|
8
|
+
* `releasePrepareProject`) to collect parser-side `!`-policy violations into a result-attachable
|
|
9
|
+
* array. Centralizing the callback shape keeps the `commitSubject` extraction rule (`firstLine
|
|
10
|
+
* post-split`) consistent across orchestrators.
|
|
11
|
+
*/
|
|
3
12
|
export declare function createPolicyViolationCollector(): {
|
|
4
13
|
violations: PolicyViolation[];
|
|
5
14
|
onPolicyViolation: PolicyViolationHandler;
|
|
@@ -1 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Return true when `target` is strictly greater than `current`, comparing major, minor, then patch.
|
|
3
|
+
*
|
|
4
|
+
* Equal versions return false. Comparison is numeric (not lexical), so `0.10.0` is greater than `0.9.0`.
|
|
5
|
+
*
|
|
6
|
+
* @throws If either version is not canonical `N.N.N` semver.
|
|
7
|
+
*/
|
|
1
8
|
export declare function isForwardVersion(current: string, target: string): boolean;
|
|
@@ -1,24 +1,54 @@
|
|
|
1
|
+
/** Options for creating a GitHub Release. */
|
|
1
2
|
export interface CreateGithubReleaseOptions {
|
|
2
3
|
tag: string;
|
|
3
4
|
changelogJsonPath: string;
|
|
4
5
|
dryRun: boolean;
|
|
6
|
+
/** Section titles in priority order. When omitted, entry order is preserved. */
|
|
5
7
|
sectionOrder?: string[];
|
|
6
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* Discriminated reason a single tag was skipped.
|
|
11
|
+
*
|
|
12
|
+
* `'no-entry'` is the umbrella for all "data missing" sub-cases (changelog file not found,
|
|
13
|
+
* JSON unparseable, version not in changelog) — distinguishing them programmatically adds no
|
|
14
|
+
* value to the consumer, while the existing `console.warn` messages already discriminate them
|
|
15
|
+
* for human diagnostics.
|
|
16
|
+
*/
|
|
7
17
|
export type CreateReleaseSkipReason = 'no-entry' | 'no-audience-content' | 'empty-body';
|
|
18
|
+
/** Discriminated outcome of attempting to create a single GitHub Release. */
|
|
8
19
|
export type CreateReleaseResult = {
|
|
9
20
|
status: 'created';
|
|
10
21
|
} | {
|
|
11
22
|
status: 'skipped';
|
|
12
23
|
reason: CreateReleaseSkipReason;
|
|
13
24
|
};
|
|
25
|
+
/**
|
|
26
|
+
* Create a GitHub Release from changelog.json using the `gh` CLI.
|
|
27
|
+
*
|
|
28
|
+
* Reads the changelog JSON, finds the entry matching the tag's version, renders all-audience
|
|
29
|
+
* release notes, and creates the release. Returns a discriminated `{status: 'skipped', reason}`
|
|
30
|
+
* (with a warning) when the changelog entry is missing, the entry has no all-audience content,
|
|
31
|
+
* or the rendered body is empty. Throws when the `gh` CLI invocation itself fails so callers
|
|
32
|
+
* can surface the failure rather than exit 0 silently.
|
|
33
|
+
*/
|
|
14
34
|
export declare function createGithubRelease(options: CreateGithubReleaseOptions): CreateReleaseResult;
|
|
35
|
+
/** Outcome of a `createGithubReleases` invocation. */
|
|
15
36
|
export interface CreateGithubReleasesOutcome {
|
|
37
|
+
/** Tags for which a Release was created (or would be, under `--dry-run`). */
|
|
16
38
|
created: string[];
|
|
39
|
+
/** Tags that were skipped, paired with the discriminated reason for each skip. */
|
|
17
40
|
skipped: Array<{
|
|
18
41
|
tag: string;
|
|
19
42
|
reason: CreateReleaseSkipReason;
|
|
20
43
|
}>;
|
|
21
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Create GitHub Releases for each provided tag.
|
|
47
|
+
*
|
|
48
|
+
* Per-tag soft-fails (missing changelog entry, no all-audience content, empty rendered body) are
|
|
49
|
+
* recorded in `skipped` with their discriminated reason and do not throw. Hard failures from the
|
|
50
|
+
* `gh` CLI itself throw and short-circuit the loop so callers can surface them.
|
|
51
|
+
*/
|
|
22
52
|
export declare function createGithubReleases(tags: Array<{
|
|
23
53
|
tag: string;
|
|
24
54
|
workspacePath: string;
|
|
@@ -1 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orchestrate the CLI `create-github-release` command: Create GitHub Releases from changelog.json
|
|
3
|
+
* for tags on HEAD (or a comma-separated `--tags` subset), without requiring npm publish.
|
|
4
|
+
*
|
|
5
|
+
* Private/unpublishable workspaces are skipped with a warning and never get a Release, matching
|
|
6
|
+
* `release-kit publish`; an all-private tag set is a clean no-op.
|
|
7
|
+
*/
|
|
1
8
|
export declare function createGithubReleaseCommand(argv: string[]): Promise<void>;
|
package/dist/esm/createTags.d.ts
CHANGED
|
@@ -2,4 +2,9 @@ export interface CreateTagsOptions {
|
|
|
2
2
|
dryRun: boolean;
|
|
3
3
|
noGitChecks: boolean;
|
|
4
4
|
}
|
|
5
|
+
/**
|
|
6
|
+
* Read tag names from the tags file produced by `prepare` and create annotated git tags.
|
|
7
|
+
*
|
|
8
|
+
* Returns the list of tag names that were created (or would be created in dry-run mode).
|
|
9
|
+
*/
|
|
5
10
|
export declare function createTags(options: CreateTagsOptions): string[];
|
|
@@ -1,19 +1,30 @@
|
|
|
1
1
|
import { type PolicyViolationHandler } from './parseCommitMessage.js';
|
|
2
2
|
import type { Commit, ReleaseType, VersionPatterns, WorkTypeConfig } from './types.js';
|
|
3
|
+
/** Inputs to the unified release decision used by both pipelines. */
|
|
3
4
|
export interface DecideReleaseArgs {
|
|
4
5
|
commits: readonly Commit[];
|
|
6
|
+
/** True when `--force` was passed; treats absence of a natural bump as patch. Defaults to false. */
|
|
5
7
|
force?: boolean | undefined;
|
|
8
|
+
/** Explicit `--bump=X` override. When set, the level is X regardless of the natural bump. */
|
|
6
9
|
bumpOverride: ReleaseType | undefined;
|
|
7
10
|
workTypes: Record<string, WorkTypeConfig>;
|
|
8
11
|
versionPatterns: VersionPatterns;
|
|
9
12
|
scopeAliases: Record<string, string> | undefined;
|
|
13
|
+
/** Per-canonical-type breaking-policy lookup. When provided, drives `!` policy enforcement in `parseCommitMessage`. */
|
|
10
14
|
breakingPolicies?: Record<string, 'forbidden' | 'optional' | 'required'>;
|
|
15
|
+
/** Receives policy-violation notifications from `parseCommitMessage`. */
|
|
11
16
|
onPolicyViolation?: PolicyViolationHandler;
|
|
17
|
+
/**
|
|
18
|
+
* Skip wordings to use when no commits exist (`noCommits`) or when commits exist but
|
|
19
|
+
* none parse to a bump-worthy work type (`noBumpWorthy`). Both pipelines pass their
|
|
20
|
+
* own pre-rendered wordings (with `{name}` / `since` substitutions already applied).
|
|
21
|
+
*/
|
|
12
22
|
skipReasons: {
|
|
13
23
|
noCommits: string;
|
|
14
24
|
noBumpWorthy: string;
|
|
15
25
|
};
|
|
16
26
|
}
|
|
27
|
+
/** Outcome of `decideRelease`: either release at a chosen level or skip with a reason. */
|
|
17
28
|
export type DecideReleaseResult = {
|
|
18
29
|
outcome: 'release';
|
|
19
30
|
releaseType: ReleaseType;
|
|
@@ -25,4 +36,30 @@ export type DecideReleaseResult = {
|
|
|
25
36
|
parsedCommitCount: number;
|
|
26
37
|
unparseableCommits: Commit[] | undefined;
|
|
27
38
|
};
|
|
39
|
+
/**
|
|
40
|
+
* Apply the unified release-decision algorithm shared by both `releasePrepareProject`
|
|
41
|
+
* and the per-workspace path in `releasePrepareMono`.
|
|
42
|
+
*
|
|
43
|
+
* Algorithm:
|
|
44
|
+
* shouldRelease = naturalBump !== undefined OR force === true
|
|
45
|
+
* releaseLevel = bumpOverride ?? naturalBump ?? 'patch'
|
|
46
|
+
*
|
|
47
|
+
* "natural bump" is the raw output of `determineBumpType` over the parsed commits — it
|
|
48
|
+
* is `undefined` when no commits exist or when none of the parsed commits map to a
|
|
49
|
+
* bump-worthy work type. Note that this differs from `determineBumpFromCommits`, which
|
|
50
|
+
* applies a patch floor whenever any commits exist; the patch floor is intentionally
|
|
51
|
+
* not applied here so that `--bump=X` and `--force` remain orthogonal (the floor is
|
|
52
|
+
* applied only when `--force` is set, by virtue of the `naturalBump ?? 'patch'`
|
|
53
|
+
* fallback in the release-level expression above).
|
|
54
|
+
*
|
|
55
|
+
* `parsedCommitCount` and `unparseableCommits` are returned in both branches so callers
|
|
56
|
+
* can surface diagnostic data uniformly regardless of skip/release outcome.
|
|
57
|
+
*
|
|
58
|
+
* Scope: this is the canonical algorithm for the orthogonal-flag model in the
|
|
59
|
+
* monorepo path (`releasePrepareProject` + per-workspace `determineDirectBumps`). The
|
|
60
|
+
* single-package executor (`releasePrepare`) deliberately retains
|
|
61
|
+
* `determineBumpFromCommits` and the legacy patch-floor semantics; `prepareCommand`
|
|
62
|
+
* rejects `--force` without `--bump` in single-package mode to surface that gap. A
|
|
63
|
+
* future ticket can unify the single-package path; see #313's external plan.
|
|
64
|
+
*/
|
|
28
65
|
export declare function decideRelease(args: DecideReleaseArgs): DecideReleaseResult;
|
package/dist/esm/defaults.d.ts
CHANGED
|
@@ -1,13 +1,38 @@
|
|
|
1
1
|
import type { ChangelogJsonConfig, ReleaseNotesConfig, VersionPatterns, WorkTypeConfig } from './types.js';
|
|
2
|
+
/** Re-export the runtime taxonomy so consumers don't have to depend on `workTypesData.ts` directly. */
|
|
2
3
|
export type { WorkTypesData } from './workTypesData.js';
|
|
3
4
|
export { WORK_TYPES_DATA } from './workTypesData.js';
|
|
5
|
+
/**
|
|
6
|
+
* Compose the rendered section heading for a work-type entry as `${emoji} ${label}`.
|
|
7
|
+
*
|
|
8
|
+
* Single-sourced here so callers (DEFAULT_WORK_TYPES derivation, devOnlySections
|
|
9
|
+
* derivation, cliff-template drift comparison) cannot disagree on the composition rule.
|
|
10
|
+
*/
|
|
4
11
|
export declare function composeHeader(entry: {
|
|
5
12
|
emoji: string;
|
|
6
13
|
label: string;
|
|
7
14
|
}): string;
|
|
15
|
+
/**
|
|
16
|
+
* Default work types ordered by canonical priority.
|
|
17
|
+
*
|
|
18
|
+
* Derived from `work-types.json` (the canonical SSOT, mirrored at runtime by
|
|
19
|
+
* `workTypesData.ts`). To change the taxonomy, edit `work-types.json` and update
|
|
20
|
+
* `workTypesData.ts` to match — a drift test enforces lockstep.
|
|
21
|
+
*/
|
|
8
22
|
export declare const DEFAULT_WORK_TYPES: Record<string, WorkTypeConfig>;
|
|
23
|
+
/**
|
|
24
|
+
* Per-canonical-type breaking-policy lookup derived from the canonical taxonomy.
|
|
25
|
+
*
|
|
26
|
+
* Pass this to `parseCommitMessage` (or an equivalent caller) so the parser knows which
|
|
27
|
+
* types tolerate `!` and which trigger a policy-violation warning. Missing entries default
|
|
28
|
+
* to `'optional'` to preserve back-compat for consumers that supply custom work-types.
|
|
29
|
+
*/
|
|
9
30
|
export declare const DEFAULT_BREAKING_POLICIES: Record<string, 'forbidden' | 'optional' | 'required'>;
|
|
31
|
+
/** Default version bump patterns. */
|
|
10
32
|
export declare const DEFAULT_VERSION_PATTERNS: VersionPatterns;
|
|
33
|
+
/** Default configuration for structured changelog JSON generation. */
|
|
11
34
|
export declare const DEFAULT_CHANGELOG_JSON_CONFIG: ChangelogJsonConfig;
|
|
35
|
+
/** Default configuration for release notes consumption. */
|
|
12
36
|
export declare const DEFAULT_RELEASE_NOTES_CONFIG: ReleaseNotesConfig;
|
|
37
|
+
/** Default tag prefix for project-level releases. */
|
|
13
38
|
export declare const DEFAULT_PROJECT_TAG_PREFIX = "v";
|
|
@@ -1,3 +1,12 @@
|
|
|
1
1
|
import type { ReleaseKitConfig } from './types.js';
|
|
2
2
|
export type { LabelSpec, ReleaseKitConfig, RepoLabelsConfig } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Type-safe identity function for configuration files.
|
|
5
|
+
*
|
|
6
|
+
* Usage in `.config/release-kit.config.ts`:
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { defineConfig } from '@williamthorsen/release-kit/config';
|
|
9
|
+
* export default defineConfig({ ... });
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
3
12
|
export declare function defineConfig(config: ReleaseKitConfig): ReleaseKitConfig;
|
|
@@ -1,2 +1,11 @@
|
|
|
1
1
|
import type { WorkspaceConfig } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Derives a workspace configuration from a workspace-relative path.
|
|
4
|
+
*
|
|
5
|
+
* Reads `package.json` at the workspace path to derive the tag identifier from the
|
|
6
|
+
* package's `name` field (with any leading `@scope/` stripped). The `dir` field remains
|
|
7
|
+
* the basename of the path — it is the stable internal identifier used for `--only`,
|
|
8
|
+
* config overrides, and dependency-graph lookups. The `tagPrefix` is `${unscopedName}-v`,
|
|
9
|
+
* so tags reflect the package identity rather than the directory layout.
|
|
10
|
+
*/
|
|
2
11
|
export declare function deriveWorkspaceConfig(workspacePath: string): WorkspaceConfig;
|
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
export type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'yarn-berry';
|
|
2
|
+
/**
|
|
3
|
+
* Detect the repo's package manager by checking the `packageManager` field in root `package.json`,
|
|
4
|
+
* then falling back to lockfile detection, then defaulting to `npm`.
|
|
5
|
+
*
|
|
6
|
+
* Yarn v2+ is returned as `'yarn-berry'` to distinguish it from Yarn Classic.
|
|
7
|
+
*/
|
|
2
8
|
export declare function detectPackageManager(): PackageManager;
|
|
@@ -1,7 +1,25 @@
|
|
|
1
|
+
/** A candidate tag prefix found in the repo that is not in the known-prefix set. */
|
|
1
2
|
export interface UndeclaredTagPrefix {
|
|
3
|
+
/** The extracted prefix, including the trailing `-v` (e.g., `'core-v'`). */
|
|
2
4
|
prefix: string;
|
|
5
|
+
/** Count of tags matching this prefix. */
|
|
3
6
|
tagCount: number;
|
|
7
|
+
/** Up to `EXAMPLE_TAG_LIMIT` example tag names under this prefix. */
|
|
4
8
|
exampleTags: string[];
|
|
9
|
+
/**
|
|
10
|
+
* Heuristic `dir` to suggest when offering a paste-ready config snippet; the prefix with
|
|
11
|
+
* the trailing `-v` stripped. The operator may need to remap this to the actual workspace
|
|
12
|
+
* directory basename.
|
|
13
|
+
*/
|
|
5
14
|
suggestedDir: string;
|
|
6
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Scan local git tags for release-shaped tags whose prefix is not in the known set.
|
|
18
|
+
*
|
|
19
|
+
* Reads only the local tag list; callers expecting to see recently-fetched remote tags
|
|
20
|
+
* should `git fetch --tags` first. Returns an empty array when the repo has no tags
|
|
21
|
+
* or no candidate-shaped tags outside the known set.
|
|
22
|
+
*
|
|
23
|
+
* @param knownPrefixes - Union of derived and declared prefixes across all workspaces.
|
|
24
|
+
*/
|
|
7
25
|
export declare function detectUndeclaredTagPrefixes(knownPrefixes: readonly string[]): UndeclaredTagPrefix[];
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import { type PolicyViolationHandler } from './parseCommitMessage.js';
|
|
2
2
|
import type { Commit, ReleaseType, VersionPatterns, WorkTypeConfig } from './types.js';
|
|
3
|
+
/** Aggregate result of parsing commits and determining the bump type. */
|
|
3
4
|
export interface BumpDetermination {
|
|
4
5
|
releaseType: ReleaseType | undefined;
|
|
5
6
|
parsedCommitCount: number;
|
|
6
7
|
unparseableCommits: Commit[] | undefined;
|
|
7
8
|
}
|
|
9
|
+
/** Optional configuration for parser-policy plumbing. */
|
|
8
10
|
export interface DetermineBumpOptions {
|
|
11
|
+
/** Per-canonical-type breaking-policy lookup (drives `!` policy enforcement). */
|
|
9
12
|
breakingPolicies?: Record<string, 'forbidden' | 'optional' | 'required'>;
|
|
13
|
+
/** Receives policy-violation notifications from `parseCommitMessage`. */
|
|
10
14
|
onPolicyViolation?: PolicyViolationHandler;
|
|
11
15
|
}
|
|
16
|
+
/** Parse commits, determine bump type, and apply patch floor when commits exist but none parsed. */
|
|
12
17
|
export declare function determineBumpFromCommits(commits: Commit[], workTypes: Record<string, WorkTypeConfig>, versionPatterns: VersionPatterns, scopeAliases: Record<string, string> | undefined, options?: DetermineBumpOptions): BumpDetermination;
|
|
@@ -1,2 +1,14 @@
|
|
|
1
1
|
import type { ParsedCommit, ReleaseType, VersionPatterns, WorkTypeConfig } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Determines the overall bump type from a set of parsed commits.
|
|
4
|
+
*
|
|
5
|
+
* Uses `versionPatterns` to decide which commit types trigger major/minor bumps.
|
|
6
|
+
* The `'!'` sentinel in `versionPatterns.major` means "any breaking commit triggers major".
|
|
7
|
+
* Any recognized commit type not listed in major or minor patterns defaults to patch.
|
|
8
|
+
*
|
|
9
|
+
* @param commits - The parsed commits to analyze.
|
|
10
|
+
* @param workTypes - The work type configurations to verify recognized types.
|
|
11
|
+
* @param versionPatterns - Rules for determining major and minor bumps.
|
|
12
|
+
* @returns The determined release type, or undefined if no commits match a known work type.
|
|
13
|
+
*/
|
|
2
14
|
export declare function determineBumpType(commits: readonly ParsedCommit[], workTypes: Record<string, WorkTypeConfig>, versionPatterns: VersionPatterns): ReleaseType | undefined;
|
|
@@ -1 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads `pnpm-workspace.yaml` and resolves its `packages` globs to discover workspace directories.
|
|
3
|
+
*
|
|
4
|
+
* Returns an array of workspace-relative directory paths (e.g., `['packages/arrays', 'packages/strings']`).
|
|
5
|
+
* Only directories containing a `package.json` are included.
|
|
6
|
+
*
|
|
7
|
+
* Note: The returned paths are full relative paths from the repo root (e.g., `packages/arrays`,
|
|
8
|
+
* `libs/core`). These paths are passed directly to `deriveWorkspaceConfig()`, which uses them for all
|
|
9
|
+
* file path construction and derives the display name via `path.basename()`.
|
|
10
|
+
*
|
|
11
|
+
* @returns The discovered workspace paths, or `undefined` if no workspace config is found.
|
|
12
|
+
*/
|
|
1
13
|
export declare function discoverWorkspaces(): Promise<string[] | undefined>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracts the instruction from a commit body's `Migration:` paragraph.
|
|
3
|
+
*
|
|
4
|
+
* The first paragraph opening with the label wins: the lede doctrine specifies one labeled
|
|
5
|
+
* paragraph per body, so a second is ignored rather than appended. The match is anchored and
|
|
6
|
+
* case-sensitive, so `migration:` and `**Migration:**` yield nothing; the doctrine calls the
|
|
7
|
+
* label literal, and tolerating variants would let the form drift.
|
|
8
|
+
*
|
|
9
|
+
* Newlines inside the paragraph are preserved. The first character is capitalized, which is
|
|
10
|
+
* inert for the imperative the doctrine requires and repairs the lowercase continuation of a
|
|
11
|
+
* paragraph written before it. Returns `undefined` when no paragraph carries the label, or when
|
|
12
|
+
* the label is followed by nothing.
|
|
13
|
+
*/
|
|
14
|
+
export declare function extractMigration(body: string | undefined): string | undefined;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const PARAGRAPH_SEPARATOR = /\n(?:[ \t]*\n)+/;
|
|
2
|
+
const MIGRATION_LABEL = /^Migration:[ \t]*/;
|
|
3
|
+
export function extractMigration(body) {
|
|
4
|
+
if (body === undefined) {
|
|
5
|
+
return undefined;
|
|
6
|
+
}
|
|
7
|
+
for (const paragraph of body.split(PARAGRAPH_SEPARATOR)) {
|
|
8
|
+
if (!MIGRATION_LABEL.test(paragraph)) {
|
|
9
|
+
continue;
|
|
10
|
+
}
|
|
11
|
+
const instruction = paragraph.replace(MIGRATION_LABEL, '').trim();
|
|
12
|
+
if (instruction.length === 0) {
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
return instruction.charAt(0).toUpperCase() + instruction.slice(1);
|
|
16
|
+
}
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
package/dist/esm/format.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/** Wrap text in ANSI bold. */
|
|
1
2
|
export declare function bold(text: string): string;
|
|
3
|
+
/** Wrap text in ANSI dim. */
|
|
2
4
|
export declare function dim(text: string): string;
|
|
5
|
+
/** Render a section header for separating workspaces in CLI output. */
|
|
3
6
|
export declare function sectionHeader(name: string): string;
|