@williamthorsen/release-kit 18.2.0 → 18.3.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 +90 -0
- package/.readyup/kits/default.js +2 -2
- package/.readyup/manifest.json +13 -13
- package/CHANGELOG.md +26 -0
- package/README.md +11 -12
- package/dist/esm/assertCleanWorkingTree.d.ts +2 -1
- package/dist/esm/assertCleanWorkingTree.js +4 -8
- package/dist/esm/assertReleasesOnNpm.js +2 -9
- package/dist/esm/assertTarballsComplete.js +2 -9
- package/dist/esm/buildChangelogEntries.d.ts +5 -3
- package/dist/esm/buildChangelogEntries.js +9 -4
- package/dist/esm/buildChangelogItem.d.ts +1 -1
- package/dist/esm/buildDependencyGraph.js +2 -16
- package/dist/esm/buildReleasedResult.d.ts +15 -3
- package/dist/esm/buildReleasedResult.js +23 -2
- package/dist/esm/changelogJsonFile.d.ts +3 -2
- package/dist/esm/changelogJsonFile.js +14 -17
- package/dist/esm/changelogJsonUtils.d.ts +22 -2
- package/dist/esm/changelogJsonUtils.js +19 -10
- package/dist/esm/commitCommand.d.ts +2 -1
- package/dist/esm/commitCommand.js +8 -11
- package/dist/esm/configSchema.d.ts +3 -1
- package/dist/esm/configSchema.js +1 -0
- package/dist/esm/createGithubRelease.d.ts +13 -10
- package/dist/esm/createGithubRelease.js +9 -13
- package/dist/esm/createGithubReleaseCommand.d.ts +1 -1
- package/dist/esm/createGithubReleaseCommand.js +25 -3
- package/dist/esm/createTags.d.ts +2 -1
- package/dist/esm/createTags.js +12 -12
- package/dist/esm/decideDirectReleases.d.ts +2 -1
- package/dist/esm/decideDirectReleases.js +5 -5
- package/dist/esm/decideRelease.d.ts +1 -1
- package/dist/esm/defaults.d.ts +4 -2
- package/dist/esm/defaults.js +1 -0
- package/dist/esm/deriveDirectoryConfig.js +5 -4
- package/dist/esm/deriveWorkspaceConfig.js +2 -9
- package/dist/esm/detectUndeclaredTagPrefixes.d.ts +2 -1
- package/dist/esm/detectUndeclaredTagPrefixes.js +4 -13
- package/dist/esm/determineBumpType.d.ts +2 -1
- package/dist/esm/determineBumpType.js +5 -0
- package/dist/esm/enumerateReleaseWindows.d.ts +3 -11
- package/dist/esm/enumerateReleaseWindows.js +17 -60
- package/dist/esm/findUnroutedEntryScopes.d.ts +1 -1
- package/dist/esm/git.d.ts +61 -0
- package/dist/esm/git.js +101 -0
- package/dist/esm/init/checks.d.ts +2 -1
- package/dist/esm/init/checks.js +5 -10
- package/dist/esm/init/eligibility.d.ts +12 -0
- package/dist/esm/init/eligibility.js +50 -0
- package/dist/esm/init/initCommand.d.ts +0 -2
- package/dist/esm/init/initCommand.js +4 -45
- package/dist/esm/init/templates.js +2 -2
- package/dist/esm/init/updateTemplatesCommand.js +4 -31
- package/dist/esm/injectReleaseNotesIntoReadme.d.ts +29 -7
- package/dist/esm/injectReleaseNotesIntoReadme.js +13 -21
- package/dist/esm/loadConfig.js +3 -16
- package/dist/esm/mergeConfig.d.ts +2 -1
- package/dist/esm/packFromCleanCheckout.js +3 -9
- package/dist/esm/planVersionBump.js +2 -16
- package/dist/esm/prepareCommand.js +2 -1
- package/dist/esm/prepareComposite.js +1 -1
- package/dist/esm/prepareReleaseTargets.d.ts +2 -1
- package/dist/esm/prepareReleaseTargets.js +3 -2
- package/dist/esm/prepareRunContext.d.ts +2 -0
- package/dist/esm/prepareTarget.d.ts +6 -4
- package/dist/esm/prepareTarget.js +9 -3
- package/dist/esm/previewTagPrefixes.d.ts +2 -1
- package/dist/esm/previewTagPrefixes.js +16 -21
- package/dist/esm/publishCommand.d.ts +1 -1
- package/dist/esm/publishCommand.js +27 -2
- package/dist/esm/pushRelease.d.ts +2 -1
- package/dist/esm/pushRelease.js +11 -11
- package/dist/esm/readJsonFile.d.ts +2 -0
- package/dist/esm/readJsonFile.js +17 -0
- package/dist/esm/reportPrepare.js +68 -114
- package/dist/esm/resolveReleaseTags.d.ts +2 -1
- package/dist/esm/resolveReleaseTags.js +4 -12
- package/dist/esm/types.d.ts +8 -2
- package/docs/configuration.md +12 -3
- package/docs/labels.md +2 -0
- package/docs/releasing.md +3 -2
- package/docs/work-types.md +2 -0
- package/package.json +3 -3
- package/presets/labels/common.yaml +14 -0
|
@@ -19,42 +19,12 @@ function formatSingleWorkspace(result, options) {
|
|
|
19
19
|
if (workspace === undefined || workspace.kind === 'composite') {
|
|
20
20
|
return '';
|
|
21
21
|
}
|
|
22
|
-
const sinceLabel = workspace.previousTag
|
|
23
|
-
lines
|
|
24
|
-
if (workspace.parsedCommitCount !== undefined) {
|
|
25
|
-
lines.push(dim(` Parsed ${workspace.parsedCommitCount} typed commits`));
|
|
26
|
-
}
|
|
27
|
-
formatUnparseableWarning(lines, workspace, style);
|
|
28
|
-
formatPolicyViolations(lines, workspace.policyViolations, style);
|
|
22
|
+
const sinceLabel = `since ${workspace.previousTag ?? 'the beginning'}`;
|
|
23
|
+
formatTargetSection(lines, workspace, { indent: '', sinceLabel }, isDryRun, style);
|
|
29
24
|
if (workspace.status === 'skipped') {
|
|
30
|
-
formatChangeRecordWarnings(lines, workspace, style);
|
|
31
|
-
lines.push(formatStatusLine(style, 'skipped', workspace.skipReason));
|
|
32
25
|
formatWarnings(lines, result, style);
|
|
33
26
|
return lines.join('\n');
|
|
34
27
|
}
|
|
35
|
-
if (workspace.versionOverride !== undefined) {
|
|
36
|
-
lines.push(` Using version override: ${workspace.versionOverride}`);
|
|
37
|
-
}
|
|
38
|
-
else if (workspace.bumpOverride !== undefined) {
|
|
39
|
-
lines.push(` Using bump override: ${workspace.bumpOverride}`);
|
|
40
|
-
}
|
|
41
|
-
if (workspace.releaseType !== undefined) {
|
|
42
|
-
lines.push(dim(`Bumping versions (${workspace.releaseType})...`));
|
|
43
|
-
}
|
|
44
|
-
else if (workspace.versionOverride !== undefined) {
|
|
45
|
-
lines.push(dim(`Bumping versions (version override)...`));
|
|
46
|
-
}
|
|
47
|
-
if (workspace.versionOverride !== undefined) {
|
|
48
|
-
lines.push(formatGlyphLine(RELEASE_GLYPHS, style, 'bump', `${workspace.currentVersion} → ${bold(workspace.newVersion)} (version override)`));
|
|
49
|
-
}
|
|
50
|
-
else if (workspace.releaseType !== undefined) {
|
|
51
|
-
lines.push(formatGlyphLine(RELEASE_GLYPHS, style, 'bump', `${workspace.currentVersion} → ${bold(workspace.newVersion)} (${workspace.releaseType})`));
|
|
52
|
-
}
|
|
53
|
-
formatChangeRecordWarnings(lines, workspace, style);
|
|
54
|
-
formatBumpFiles(lines, workspace, isDryRun);
|
|
55
|
-
lines.push(dim('Generating changelogs...'));
|
|
56
|
-
formatChangelogFiles(lines, workspace, isDryRun, style);
|
|
57
|
-
formatPreviewFiles(lines, workspace, isDryRun);
|
|
58
28
|
formatFormatCommand(lines, result, options);
|
|
59
29
|
formatWarnings(lines, result, style);
|
|
60
30
|
lines.push(formatStatusLine(style, 'passed', 'Release preparation complete.'), ` ${formatGlyphLine(RELEASE_GLYPHS, style, 'tag', bold(workspace.tag))}`);
|
|
@@ -65,11 +35,14 @@ function formatMultiWorkspace(result, options) {
|
|
|
65
35
|
const { style } = options;
|
|
66
36
|
const lines = [];
|
|
67
37
|
for (const target of result.targets) {
|
|
68
|
-
|
|
69
|
-
|
|
38
|
+
const title = getSectionTitle(target);
|
|
39
|
+
if (title !== undefined) {
|
|
40
|
+
lines.push(`\n${renderSectionHeader(title)}`);
|
|
70
41
|
}
|
|
71
|
-
|
|
72
|
-
|
|
42
|
+
const sinceLabel = target.previousTag === undefined ? '(no previous release found)' : `since ${target.previousTag}`;
|
|
43
|
+
formatTargetSection(lines, target, { indent: ' ', sinceLabel }, isDryRun, style);
|
|
44
|
+
if (target.status === 'released') {
|
|
45
|
+
lines.push(` ${formatGlyphLine(RELEASE_GLYPHS, style, 'tag', bold(target.tag))}`);
|
|
73
46
|
}
|
|
74
47
|
}
|
|
75
48
|
formatFormatCommand(lines, result, options);
|
|
@@ -85,98 +58,79 @@ function formatMultiWorkspace(result, options) {
|
|
|
85
58
|
}
|
|
86
59
|
return lines.join('\n');
|
|
87
60
|
}
|
|
88
|
-
function
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
lines.push(dim(` Found ${project.commitCount} commits ${sinceLabel}`));
|
|
92
|
-
formatPolicyViolations(lines, project.policyViolations, style, ' ');
|
|
93
|
-
if (project.status === 'skipped') {
|
|
94
|
-
formatUnparseableWarning(lines, project, style, ' ');
|
|
95
|
-
formatChangeRecordWarnings(lines, project, style, ' ');
|
|
96
|
-
lines.push(` ${formatStatusLine(style, 'skipped', project.skipReason)}`);
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
const { releaseType, currentVersion, newVersion, tag } = project;
|
|
100
|
-
if (project.parsedCommitCount > 0) {
|
|
101
|
-
lines.push(dim(` Parsed ${project.parsedCommitCount} typed commits`));
|
|
61
|
+
function getSectionTitle(target) {
|
|
62
|
+
if (target.kind === 'composite') {
|
|
63
|
+
return target.targetId === PROJECT_TARGET_ID ? 'project' : target.targetId;
|
|
102
64
|
}
|
|
103
|
-
|
|
104
|
-
lines.push(` Using bump override: ${project.bumpOverride}`);
|
|
105
|
-
}
|
|
106
|
-
formatUnparseableWarning(lines, project, style, ' ');
|
|
107
|
-
formatChangeRecordWarnings(lines, project, style, ' ');
|
|
108
|
-
lines.push(dim(` Bumping versions (${releaseType})...`), ` ${formatGlyphLine(RELEASE_GLYPHS, style, 'bump', `${currentVersion} → ${bold(newVersion)} (${releaseType})`)}`);
|
|
109
|
-
for (const file of project.bumpedFiles) {
|
|
110
|
-
if (isDryRun) {
|
|
111
|
-
lines.push(dim(` [dry-run] Would bump ${file}`));
|
|
112
|
-
}
|
|
113
|
-
else {
|
|
114
|
-
lines.push(dim(` Bumped ${file}`));
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
lines.push(dim(' Generating changelogs...'));
|
|
118
|
-
formatChangelogFiles(lines, project, isDryRun, style, ' ');
|
|
119
|
-
formatPreviewFiles(lines, project, isDryRun, ' ');
|
|
120
|
-
lines.push(` ${formatGlyphLine(RELEASE_GLYPHS, style, 'tag', bold(tag))}`);
|
|
65
|
+
return target.name;
|
|
121
66
|
}
|
|
122
|
-
function
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
if (workspace.status === 'skipped') {
|
|
129
|
-
formatUnparseableWarning(lines, workspace, style, ' ');
|
|
130
|
-
formatPolicyViolations(lines, workspace.policyViolations, style, ' ');
|
|
131
|
-
formatChangeRecordWarnings(lines, workspace, style, ' ');
|
|
132
|
-
lines.push(` ${formatStatusLine(style, 'skipped', workspace.skipReason)}`);
|
|
67
|
+
function formatTargetSection(lines, target, layout, isDryRun, style) {
|
|
68
|
+
const { indent, sinceLabel } = layout;
|
|
69
|
+
lines.push(dim(`${indent}Found ${target.commitCount} commits ${sinceLabel}`));
|
|
70
|
+
if (target.status === 'skipped') {
|
|
71
|
+
formatTargetWarnings(lines, target, style, indent);
|
|
72
|
+
lines.push(`${indent}${formatStatusLine(style, 'skipped', target.skipReason)}`);
|
|
133
73
|
return;
|
|
134
74
|
}
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
lines.
|
|
75
|
+
const origin = describeBumpOrigin(target);
|
|
76
|
+
formatCommitSummary(lines, target, origin);
|
|
77
|
+
formatTargetWarnings(lines, target, style, indent);
|
|
78
|
+
formatBumpLabels(lines, target, origin, indent);
|
|
79
|
+
formatVersionLine(lines, target, origin, indent, style);
|
|
80
|
+
formatBumpFiles(lines, target, isDryRun, indent);
|
|
81
|
+
lines.push(dim(`${indent}Generating changelogs...`));
|
|
82
|
+
formatChangelogFiles(lines, target, isDryRun, style, indent);
|
|
83
|
+
formatPreviewFiles(lines, target, isDryRun, indent);
|
|
84
|
+
}
|
|
85
|
+
function formatTargetWarnings(lines, target, style, indent) {
|
|
86
|
+
formatUnparseableWarning(lines, target, style, indent);
|
|
87
|
+
formatPolicyViolations(lines, target.policyViolations, style, indent);
|
|
88
|
+
formatChangeRecordWarnings(lines, target, style, indent);
|
|
89
|
+
}
|
|
90
|
+
function describeBumpOrigin(target) {
|
|
91
|
+
if (target.kind === 'composite') {
|
|
92
|
+
return { propagatedFrom: undefined, isPropagatedOnly: false, versionOverride: undefined };
|
|
93
|
+
}
|
|
94
|
+
if (target.kind === 'directory') {
|
|
95
|
+
return { propagatedFrom: undefined, isPropagatedOnly: false, versionOverride: target.versionOverride };
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
propagatedFrom: target.propagatedFrom,
|
|
99
|
+
isPropagatedOnly: target.propagatedOnly === true,
|
|
100
|
+
versionOverride: target.versionOverride,
|
|
101
|
+
};
|
|
148
102
|
}
|
|
149
|
-
function formatCommitSummary(lines,
|
|
150
|
-
if (isPropagatedOnly && propagatedFrom !== undefined) {
|
|
151
|
-
const dependencyNames = propagatedFrom.map((p) => p.packageName).join(', ');
|
|
103
|
+
function formatCommitSummary(lines, target, origin) {
|
|
104
|
+
if (origin.isPropagatedOnly && origin.propagatedFrom !== undefined) {
|
|
105
|
+
const dependencyNames = origin.propagatedFrom.map((p) => p.packageName).join(', ');
|
|
152
106
|
lines.push(dim(` Bumped via dependency: ${dependencyNames}`));
|
|
153
107
|
}
|
|
154
|
-
else if (
|
|
155
|
-
lines.push(dim(` Parsed ${
|
|
108
|
+
else if (target.parsedCommitCount !== undefined && target.parsedCommitCount > 0) {
|
|
109
|
+
lines.push(dim(` Parsed ${target.parsedCommitCount} typed commits`));
|
|
156
110
|
}
|
|
157
111
|
}
|
|
158
|
-
function formatBumpLabels(lines,
|
|
159
|
-
if (
|
|
160
|
-
lines.push(` Using version override: ${
|
|
112
|
+
function formatBumpLabels(lines, target, origin, indent) {
|
|
113
|
+
if (origin.versionOverride !== undefined) {
|
|
114
|
+
lines.push(` Using version override: ${origin.versionOverride}`);
|
|
161
115
|
}
|
|
162
|
-
else if (
|
|
163
|
-
lines.push(` Using bump override: ${
|
|
116
|
+
else if (target.bumpOverride !== undefined && !origin.isPropagatedOnly) {
|
|
117
|
+
lines.push(` Using bump override: ${target.bumpOverride}`);
|
|
164
118
|
}
|
|
165
|
-
if (
|
|
166
|
-
lines.push(dim(
|
|
119
|
+
if (target.releaseType !== undefined) {
|
|
120
|
+
lines.push(dim(`${indent}Bumping versions (${target.releaseType})...`));
|
|
167
121
|
}
|
|
168
|
-
else if (
|
|
169
|
-
lines.push(dim(
|
|
122
|
+
else if (origin.versionOverride !== undefined) {
|
|
123
|
+
lines.push(dim(`${indent}Bumping versions (version override)...`));
|
|
170
124
|
}
|
|
171
125
|
}
|
|
172
|
-
function formatVersionLine(lines,
|
|
173
|
-
const versions = `${
|
|
174
|
-
if (
|
|
175
|
-
lines.push(
|
|
176
|
-
}
|
|
177
|
-
else if (
|
|
178
|
-
const suffix = isPropagatedOnly ? formatPropagationSuffix(propagatedFrom) : '';
|
|
179
|
-
lines.push(
|
|
126
|
+
function formatVersionLine(lines, target, origin, indent, style) {
|
|
127
|
+
const versions = `${target.currentVersion} → ${bold(target.newVersion)}`;
|
|
128
|
+
if (origin.versionOverride !== undefined) {
|
|
129
|
+
lines.push(`${indent}${formatGlyphLine(RELEASE_GLYPHS, style, 'bump', `${versions} (version override)`)}`);
|
|
130
|
+
}
|
|
131
|
+
else if (target.releaseType !== undefined) {
|
|
132
|
+
const suffix = origin.isPropagatedOnly ? formatPropagationSuffix(origin.propagatedFrom) : '';
|
|
133
|
+
lines.push(`${indent}${formatGlyphLine(RELEASE_GLYPHS, style, 'bump', `${versions} (${target.releaseType}${suffix})`)}`);
|
|
180
134
|
}
|
|
181
135
|
}
|
|
182
136
|
function formatPropagationSuffix(propagatedFrom) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type Git } from './git.js';
|
|
1
2
|
import type { DirectoryConfig, ResolvedProjectConfig, WorkspaceConfig } from './types.js';
|
|
2
3
|
export interface ResolvedTag {
|
|
3
4
|
tag: string;
|
|
@@ -41,5 +42,5 @@ type ResolveReleaseTagsArgs = {
|
|
|
41
42
|
* matching without needing `isPublishable` propagation; resolved tags default to
|
|
42
43
|
* `isPublishable: true`. Production callers should pass one of the named forms.
|
|
43
44
|
*/
|
|
44
|
-
export declare function resolveReleaseTags(args?: ResolveReleaseTagsArgs): ResolvedTag[];
|
|
45
|
+
export declare function resolveReleaseTags(args?: ResolveReleaseTagsArgs, git?: Git): ResolvedTag[];
|
|
45
46
|
export {};
|
|
@@ -1,25 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { GIT_OUTPUT_LIMIT_BYTES } from '@williamthorsen/nmr-core';
|
|
1
|
+
import { realGit } from "./git.js";
|
|
3
2
|
import { getTargetName } from "./resolveReleaseDeclaration.js";
|
|
4
3
|
import { PROJECT_TARGET_ID } from "./resolveReleaseTargets.js";
|
|
5
4
|
import { asUserError } from "./user-error-chaining.js";
|
|
6
5
|
const VERSION_PATTERN = /^v\d+\.\d+\.\d+/;
|
|
7
6
|
const SEMVER_SUFFIX_PATTERN = /^\d+\.\d+\.\d+/;
|
|
8
|
-
export function resolveReleaseTags(args) {
|
|
9
|
-
let
|
|
7
|
+
export function resolveReleaseTags(args, git = realGit) {
|
|
8
|
+
let tags;
|
|
10
9
|
try {
|
|
11
|
-
|
|
12
|
-
encoding: 'utf8',
|
|
13
|
-
maxBuffer: GIT_OUTPUT_LIMIT_BYTES,
|
|
14
|
-
});
|
|
10
|
+
tags = git.listTagsAtHead();
|
|
15
11
|
}
|
|
16
12
|
catch (error) {
|
|
17
13
|
throw asUserError(error);
|
|
18
14
|
}
|
|
19
|
-
const tags = output
|
|
20
|
-
.split('\n')
|
|
21
|
-
.map((line) => line.trim())
|
|
22
|
-
.filter((line) => line.length > 0);
|
|
23
15
|
if (args === undefined) {
|
|
24
16
|
return resolveSinglePackageTags(tags);
|
|
25
17
|
}
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -355,8 +355,9 @@ export interface WorkTypeConfig {
|
|
|
355
355
|
excludedFromChangelog?: boolean | undefined;
|
|
356
356
|
}
|
|
357
357
|
/**
|
|
358
|
-
* Defines which commit types trigger major or minor version bumps.
|
|
359
|
-
* Any recognized commit type not listed defaults to a
|
|
358
|
+
* Defines which commit types trigger major or minor version bumps, and which trigger none.
|
|
359
|
+
* Any recognized commit type not listed in `major`, `minor`, or `none` (the default list when omitted) defaults to a
|
|
360
|
+
* patch bump.
|
|
360
361
|
* The sentinel `'!'` in `major` means "any breaking commit triggers a major bump".
|
|
361
362
|
*/
|
|
362
363
|
export interface VersionPatterns {
|
|
@@ -364,6 +365,11 @@ export interface VersionPatterns {
|
|
|
364
365
|
major: string[];
|
|
365
366
|
/** Commit types that trigger a minor bump. */
|
|
366
367
|
minor: string[];
|
|
368
|
+
/**
|
|
369
|
+
* Commit types that do not trigger a bump unless breaking. Defaults to `DEFAULT_VERSION_PATTERNS.none` when omitted;
|
|
370
|
+
* `[]` gives every unlisted type a patch bump.
|
|
371
|
+
*/
|
|
372
|
+
none?: string[] | undefined;
|
|
367
373
|
}
|
|
368
374
|
/** A raw commit from the git log. */
|
|
369
375
|
export interface Commit {
|
package/docs/configuration.md
CHANGED
|
@@ -22,7 +22,7 @@ The two paths differ in what an absent file means. An absent default path means
|
|
|
22
22
|
| `workspaces` | `WorkspaceOverride[]` | Override or exclude discovered workspaces (matched by `dir`) |
|
|
23
23
|
| `devExportConditions` | `string[]` | Export conditions that resolve only inside the repo, such as one that points at unpublished source; the [tarball check](releasing.md#packages-whose-tarball-would-lack-a-manifest-file) does not require their targets in the tarball. `source` is exempt without being listed |
|
|
24
24
|
| `formatCommand` | `string` | Shell command to run after changelog generation; modified file paths are appended as arguments |
|
|
25
|
-
| `versionPatterns` | `VersionPatterns` | Rules for which commit types trigger major
|
|
25
|
+
| `versionPatterns` | `VersionPatterns` | Rules for which commit types trigger major, minor, or no bumps |
|
|
26
26
|
| `scopeAliases` | `Record<string, string>` | Maps shorthand scope names to canonical names in commit titles and in change-record entry `scopes`, which [route items to workspaces](changelogs.md#routing-to-workspaces). A renamed workspace directory or [release target](#releases) needs an entry from its old name to its new one |
|
|
27
27
|
| `workTypes` | `Record<string, WorkTypeConfig>` | Work type definitions, merged with defaults by key |
|
|
28
28
|
| `breakingPolicies` | `Record<string, 'forbidden' \| 'optional'>` | Per-type `!`-policy lookup. Defaults to `DEFAULT_BREAKING_POLICIES`. Replaces the default entirely when provided. Set to `{}` to disable enforcement |
|
|
@@ -170,16 +170,25 @@ In single-package mode, prints a single block for `.` with the derived prefix `v
|
|
|
170
170
|
|
|
171
171
|
## `VersionPatterns`
|
|
172
172
|
|
|
173
|
-
Defines which work types trigger major or minor bumps. `prepare` applies it to each changelog item of the unreleased window and takes the highest level. An item of a type not listed bumps patch.
|
|
173
|
+
Defines which work types trigger major or minor bumps, and which trigger none. `prepare` applies it to each changelog item of the unreleased window and takes the highest level. An item of a type that `none` lists doesn't bump, and an item of any other type not listed bumps patch. A window whose items don't call for any bump doesn't release unless `--force` is passed, and its items wait in the unreleased window for the next release.
|
|
174
174
|
|
|
175
175
|
```typescript
|
|
176
176
|
interface VersionPatterns {
|
|
177
177
|
major: string[]; // Patterns triggering a major bump ('!' = any breaking change)
|
|
178
178
|
minor: string[]; // Commit types triggering a minor bump
|
|
179
|
+
none?: string[]; // Commit types triggering no bump unless breaking
|
|
179
180
|
}
|
|
180
181
|
```
|
|
181
182
|
|
|
182
|
-
Default: `{ major: ['!'], minor: ['feat'] }`
|
|
183
|
+
Default: `{ major: ['!'], minor: ['feat'], none: ['ai', 'ci', 'docs', 'tests', 'tooling'] }`
|
|
184
|
+
|
|
185
|
+
The default `none` types don't change the code that a consumer runs. `refactor`, `internal`, and `deps` bump patch, because they change shipped code or installed dependencies. A `docs` change to a file that the package publishes reaches the registry with the next release.
|
|
186
|
+
|
|
187
|
+
A config that sets `versionPatterns` replaces `major` and `minor`, but an omitted `none` keeps the default list. To give every type not listed in `major` or `minor` a patch bump, as release-kit did before `none` existed, set `none: []`:
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
versionPatterns: { major: ['!'], minor: ['feat'], none: [] },
|
|
191
|
+
```
|
|
183
192
|
|
|
184
193
|
## Output style
|
|
185
194
|
|
package/docs/labels.md
CHANGED
|
@@ -38,6 +38,8 @@ The bundled file's `confidence:` family grades how advisable a recommendation is
|
|
|
38
38
|
|
|
39
39
|
The `urgency:` family states how soon an item needs attention, apart from how valuable it is, which the `value:` family states. Its labels replace the earlier `priority:` family and name the old labels in `aliases`, so a repository that has `priority:` labels has them renamed in place by the first sync after it regenerates `.github/labels.yaml` (see [Renaming a label](#renaming-a-label)).
|
|
40
40
|
|
|
41
|
+
The `effort:` family states an item's size in points, apart from its urgency and value: one label for each value of the scale 1, 2, 3, 5, 8, and 13, from `effort:1` to `effort:13`.
|
|
42
|
+
|
|
41
43
|
The `status:` family marks where an item stands in its work: `status:in-progress` once work on it has started, `status:blocked` while it waits on another item, and `status:on-hold` while it is deliberately paused.
|
|
42
44
|
|
|
43
45
|
Names match case-insensitively, as GitHub matches them: `Bug` in the `labels` record replaces a preset's `bug`, and `Bug: null` removes it. A label takes the spelling of the last layer to write it.
|
package/docs/releasing.md
CHANGED
|
@@ -31,13 +31,14 @@ The workflows are managed files: release-kit renders them, and a change made by
|
|
|
31
31
|
|
|
32
32
|
Runs release preparation with automatic workspace discovery.
|
|
33
33
|
|
|
34
|
-
`--only` names the release targets from which the release starts, by target name: a workspace's directory name (e.g., `arrays`, `release-kit`) unless a [`releases`](configuration.md#releases) entry renames it, or a `releases` composite's name. A named composite releases from its own window, whether or not the run includes its members; a run narrowed by `--only` skips every composite that it doesn't name. The run also releases every workspace that depends on one of them, directly or transitively: A dependent
|
|
34
|
+
`--only` names the release targets from which the release starts, by target name: a workspace's directory name (e.g., `arrays`, `release-kit`) unless a [`releases`](configuration.md#releases) entry renames it, or a `releases` composite's name. A named composite releases from its own window, whether or not the run includes its members; a run narrowed by `--only` skips every composite that it doesn't name. The run also releases every workspace that depends on one of them, directly or transitively: A dependent whose commits call for a bump releases at its own bump, and one whose commits don't releases at a propagated patch bump, so that it publishes against the new version; its changelog entry lists its own items, if any, with the dependencies. Workspaces outside that set are left out of the run.
|
|
35
35
|
|
|
36
36
|
`prepare` reads each target's history once and builds the changelog items of its unreleased commits. The bump is the highest level that those items call for, under [`versionPatterns`](configuration.md#versionpatterns), so the bump and the changelog describe the same release: A `feat` entry in a [change-record block](changelogs.md#change-record-blocks) bumps minor under a `docs:` title, and a breaking item bumps major.
|
|
37
37
|
|
|
38
38
|
- A commit that doesn't yield an item doesn't bump anything: one without a ticket-ID prefix, one of a type excluded from the changelog (such as `fmt`), and one whose change-record entries are all undeclared or excluded.
|
|
39
39
|
- A `BREAKING CHANGE:` footer doesn't raise a major bump. Only a subject's `!` and an entry's `breaking: true` mark an item breaking; on a type whose policy forbids `!`, the footer is reported as a [policy violation](work-types.md#policy-enforcement).
|
|
40
|
-
-
|
|
40
|
+
- An item of a type that [`versionPatterns.none`](configuration.md#versionpatterns) lists, such as `tests` or `ci` by default, doesn't bump anything unless it is breaking.
|
|
41
|
+
- A target whose items don't call for a bump is skipped, and so is one whose commits don't yield an item. The prepare report lists the commits that could not be parsed and the change-record diagnostics, skipped targets included.
|
|
41
42
|
|
|
42
43
|
`--bump` and `--force` are orthogonal in every mode, single-package included: `--bump` is purely a level chooser; `--force` is purely a release trigger. Examples:
|
|
43
44
|
|
package/docs/work-types.md
CHANGED
|
@@ -28,6 +28,8 @@ release-kit reads the taxonomy from `CANONICAL_TAXONOMY` in [`@williamthorsen/ch
|
|
|
28
28
|
- **`internal`**: Dev-only. `internal`-tier sections appear in dev changelogs but not in public-facing release notes.
|
|
29
29
|
- **`process`**: Dev-only. Same audience treatment as `internal`.
|
|
30
30
|
|
|
31
|
+
Tiers decide the audience, not the bump: [`versionPatterns`](configuration.md#versionpatterns) decides which types bump and which don't, and by default some `internal`- and `process`-tier types bump patch while others don't bump at all.
|
|
32
|
+
|
|
31
33
|
Section render order is **tier order (`public` → `internal` → `process`), then row order within tier**. It comes from the declaration order of `CANONICAL_TAXONOMY`: `CANONICAL_SECTION_ORDER` in `buildChangelogEntries.ts` indexes each header by its row, and `transformReleases` sorts a release's sections by that index whatever order the commits arrived in.
|
|
32
34
|
|
|
33
35
|
## Subject forms
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@williamthorsen/release-kit",
|
|
3
|
-
"version": "18.
|
|
3
|
+
"version": "18.3.0",
|
|
4
4
|
"description": "Version-bumping and changelog-generation toolkit for release workflows",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"changelog",
|
|
@@ -61,8 +61,8 @@
|
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@types/semver": "7.8.0",
|
|
64
|
-
"@williamthorsen/nmr": "2.2.
|
|
65
|
-
"@williamthorsen/toolbelt.filesystem": "0.
|
|
64
|
+
"@williamthorsen/nmr": "2.2.2",
|
|
65
|
+
"@williamthorsen/toolbelt.filesystem": "0.11.0",
|
|
66
66
|
"@williamthorsen/toolbelt.testing": "0.8.3",
|
|
67
67
|
"@williamthorsen/toolbelt.vitest": "0.13.5",
|
|
68
68
|
"actionlint": "2.0.6",
|
|
@@ -44,6 +44,20 @@
|
|
|
44
44
|
color: cfd3d7
|
|
45
45
|
aliases: ['priority:low']
|
|
46
46
|
|
|
47
|
+
# Effort
|
|
48
|
+
- name: 'effort:1'
|
|
49
|
+
color: dbe9ff
|
|
50
|
+
- name: 'effort:2'
|
|
51
|
+
color: b9d4ff
|
|
52
|
+
- name: 'effort:3'
|
|
53
|
+
color: 8fb8fb
|
|
54
|
+
- name: 'effort:5'
|
|
55
|
+
color: 5b93f0
|
|
56
|
+
- name: 'effort:8'
|
|
57
|
+
color: '3470e0'
|
|
58
|
+
- name: 'effort:13'
|
|
59
|
+
color: 1d4ed8
|
|
60
|
+
|
|
47
61
|
# Status
|
|
48
62
|
- name: 'status:blocked'
|
|
49
63
|
color: b83280
|