@williamthorsen/release-kit 5.0.0 → 5.1.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/CHANGELOG.md +60 -0
- package/README.md +137 -43
- package/dist/esm/.cache +1 -1
- package/dist/esm/assertCleanWorkingTree.js +1 -1
- package/dist/esm/bin/release-kit.js +1 -1
- package/dist/esm/buildChangelogEntries.d.ts +3 -0
- package/dist/esm/{generateChangelogJson.js → buildChangelogEntries.js} +7 -80
- package/dist/esm/buildDependencyGraph.d.ts +1 -0
- package/dist/esm/buildDependencyGraph.js +8 -1
- package/dist/esm/buildReleaseSummary.js +9 -1
- package/dist/esm/buildSyntheticChangelogEntry.d.ts +5 -0
- package/dist/esm/buildSyntheticChangelogEntry.js +13 -0
- package/dist/esm/changelogJsonFile.d.ts +4 -0
- package/dist/esm/changelogJsonFile.js +68 -0
- package/dist/esm/decideRelease.d.ts +25 -0
- package/dist/esm/decideRelease.js +28 -0
- package/dist/esm/defaults.d.ts +1 -0
- package/dist/esm/defaults.js +2 -0
- package/dist/esm/index.d.ts +2 -43
- package/dist/esm/index.js +0 -82
- package/dist/esm/init/templates.js +2 -2
- package/dist/esm/loadConfig.d.ts +10 -1
- package/dist/esm/loadConfig.js +96 -2
- package/dist/esm/prepareCommand.js +51 -9
- package/dist/esm/publish.d.ts +0 -1
- package/dist/esm/publish.js +3 -3
- package/dist/esm/publishCommand.js +10 -1
- package/dist/esm/releasePrepare.js +83 -39
- package/dist/esm/releasePrepareMono.js +133 -87
- package/dist/esm/releasePrepareProject.d.ts +9 -0
- package/dist/esm/releasePrepareProject.js +109 -0
- package/dist/esm/reportPrepare.js +70 -24
- package/dist/esm/types.d.ts +57 -14
- package/dist/esm/validateConfig.js +26 -0
- package/dist/esm/validateOnlyExcludesStrandedDependents.d.ts +14 -0
- package/dist/esm/validateOnlyExcludesStrandedDependents.js +109 -0
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/package.json +4 -1
- package/presets/labels/common.yaml +9 -6
- package/schemas/label-map.json +24 -0
- package/dist/esm/generateChangelogJson.d.ts +0 -7
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { bold, dim, sectionHeader } from "./format.js";
|
|
2
2
|
function reportPrepare(result) {
|
|
3
|
-
const isMultiWorkspace = result.workspaces.some((w) => w.name !== void 0);
|
|
3
|
+
const isMultiWorkspace = result.workspaces.some((w) => w.name !== void 0) || result.project !== void 0;
|
|
4
4
|
if (isMultiWorkspace) {
|
|
5
5
|
return formatMultiWorkspace(result);
|
|
6
6
|
}
|
|
@@ -19,34 +19,29 @@ function formatSingleWorkspace(result) {
|
|
|
19
19
|
}
|
|
20
20
|
formatUnparseableWarning(lines, workspace);
|
|
21
21
|
if (workspace.status === "skipped") {
|
|
22
|
-
lines.push(`\u23ED\uFE0F ${workspace.skipReason
|
|
22
|
+
lines.push(`\u23ED\uFE0F ${workspace.skipReason}`);
|
|
23
23
|
return lines.join("\n");
|
|
24
24
|
}
|
|
25
25
|
if (workspace.setVersion !== void 0) {
|
|
26
26
|
lines.push(` Using version override: ${workspace.setVersion}`);
|
|
27
|
-
} else if (workspace.
|
|
28
|
-
lines.push(` Using bump override: ${workspace.
|
|
27
|
+
} else if (workspace.bumpOverride !== void 0) {
|
|
28
|
+
lines.push(` Using bump override: ${workspace.bumpOverride}`);
|
|
29
29
|
}
|
|
30
30
|
if (workspace.releaseType !== void 0) {
|
|
31
31
|
lines.push(dim(`Bumping versions (${workspace.releaseType})...`));
|
|
32
32
|
} else if (workspace.setVersion !== void 0) {
|
|
33
33
|
lines.push(dim(`Bumping versions (version override)...`));
|
|
34
34
|
}
|
|
35
|
-
if (workspace.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
lines.push(`\u{1F4E6} ${workspace.currentVersion} \u2192 ${bold(workspace.newVersion)} (${workspace.releaseType})`);
|
|
40
|
-
}
|
|
35
|
+
if (workspace.setVersion !== void 0) {
|
|
36
|
+
lines.push(`\u{1F4E6} ${workspace.currentVersion} \u2192 ${bold(workspace.newVersion)} (version override)`);
|
|
37
|
+
} else if (workspace.releaseType !== void 0) {
|
|
38
|
+
lines.push(`\u{1F4E6} ${workspace.currentVersion} \u2192 ${bold(workspace.newVersion)} (${workspace.releaseType})`);
|
|
41
39
|
}
|
|
42
40
|
formatBumpFiles(lines, workspace, result.dryRun);
|
|
43
41
|
lines.push(dim("Generating changelogs..."));
|
|
44
42
|
formatChangelogFiles(lines, workspace, result.dryRun);
|
|
45
43
|
formatFormatCommand(lines, result);
|
|
46
|
-
lines.push(`\u2705 Release preparation complete
|
|
47
|
-
if (workspace.tag !== void 0) {
|
|
48
|
-
lines.push(` \u{1F3F7}\uFE0F ${bold(workspace.tag)}`);
|
|
49
|
-
}
|
|
44
|
+
lines.push(`\u2705 Release preparation complete.`, ` \u{1F3F7}\uFE0F ${bold(workspace.tag)}`);
|
|
50
45
|
return lines.join("\n");
|
|
51
46
|
}
|
|
52
47
|
function formatMultiWorkspace(result) {
|
|
@@ -54,6 +49,9 @@ function formatMultiWorkspace(result) {
|
|
|
54
49
|
for (const workspace of result.workspaces) {
|
|
55
50
|
formatWorkspaceSection(lines, workspace, result.dryRun);
|
|
56
51
|
}
|
|
52
|
+
if (result.project !== void 0) {
|
|
53
|
+
formatProjectSection(lines, result.project, result.dryRun);
|
|
54
|
+
}
|
|
57
55
|
formatFormatCommand(lines, result);
|
|
58
56
|
formatWarnings(lines, result);
|
|
59
57
|
if (result.tags.length > 0) {
|
|
@@ -68,6 +66,59 @@ function formatMultiWorkspace(result) {
|
|
|
68
66
|
}
|
|
69
67
|
return lines.join("\n");
|
|
70
68
|
}
|
|
69
|
+
function formatProjectSection(lines, project, dryRun) {
|
|
70
|
+
lines.push(`
|
|
71
|
+
${sectionHeader("project")}`);
|
|
72
|
+
const since = project.previousTag === void 0 ? "(no previous release found)" : `since ${project.previousTag}`;
|
|
73
|
+
lines.push(dim(` Found ${project.commitCount} commits ${since}`));
|
|
74
|
+
if (project.status === "skipped") {
|
|
75
|
+
lines.push(` \u23ED\uFE0F ${project.skipReason}`);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const { releaseType, currentVersion, newVersion, tag } = project;
|
|
79
|
+
if (project.parsedCommitCount > 0) {
|
|
80
|
+
lines.push(dim(` Parsed ${project.parsedCommitCount} typed commits`));
|
|
81
|
+
}
|
|
82
|
+
if (project.bumpOverride !== void 0) {
|
|
83
|
+
lines.push(` Using bump override: ${project.bumpOverride}`);
|
|
84
|
+
}
|
|
85
|
+
formatProjectUnparseable(lines, project);
|
|
86
|
+
lines.push(
|
|
87
|
+
dim(` Bumping versions (${releaseType})...`),
|
|
88
|
+
` \u{1F4E6} ${currentVersion} \u2192 ${bold(newVersion)} (${releaseType})`
|
|
89
|
+
);
|
|
90
|
+
for (const file of project.bumpedFiles) {
|
|
91
|
+
if (dryRun) {
|
|
92
|
+
lines.push(dim(` [dry-run] Would bump ${file}`));
|
|
93
|
+
} else {
|
|
94
|
+
lines.push(dim(` Bumped ${file}`));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
lines.push(dim(" Generating changelogs..."));
|
|
98
|
+
for (const file of project.changelogFiles) {
|
|
99
|
+
if (dryRun) {
|
|
100
|
+
lines.push(dim(` [dry-run] Would run: npx --yes git-cliff ... --output ${file}`));
|
|
101
|
+
} else {
|
|
102
|
+
lines.push(dim(` Generating changelog: ${file}`));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
lines.push(` \u{1F3F7}\uFE0F ${bold(tag)}`);
|
|
106
|
+
}
|
|
107
|
+
function formatProjectUnparseable(lines, project) {
|
|
108
|
+
const unparseable = project.unparseableCommits;
|
|
109
|
+
if (unparseable === void 0 || unparseable.length === 0) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const count = unparseable.length;
|
|
113
|
+
const isPatchFloor = project.parsedCommitCount === 0;
|
|
114
|
+
const suffix = isPatchFloor ? " (defaulting to patch bump)" : "";
|
|
115
|
+
lines.push(` \u26A0\uFE0F ${count} commit${count === 1 ? "" : "s"} could not be parsed${suffix}`);
|
|
116
|
+
for (const commit of unparseable) {
|
|
117
|
+
const shortHash = commit.hash.slice(0, 7);
|
|
118
|
+
const truncatedMessage = commit.message.length > 72 ? `${commit.message.slice(0, 69)}...` : commit.message;
|
|
119
|
+
lines.push(` \xB7 ${shortHash} ${truncatedMessage}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
71
122
|
function formatWorkspaceSection(lines, workspace, dryRun) {
|
|
72
123
|
if (workspace.name !== void 0) {
|
|
73
124
|
lines.push(`
|
|
@@ -76,7 +127,7 @@ ${sectionHeader(workspace.name)}`);
|
|
|
76
127
|
const since = workspace.previousTag === void 0 ? "(no previous release found)" : `since ${workspace.previousTag}`;
|
|
77
128
|
lines.push(dim(` Found ${workspace.commitCount} commits ${since}`));
|
|
78
129
|
if (workspace.status === "skipped") {
|
|
79
|
-
lines.push(` \u23ED\uFE0F ${workspace.skipReason
|
|
130
|
+
lines.push(` \u23ED\uFE0F ${workspace.skipReason}`);
|
|
80
131
|
return;
|
|
81
132
|
}
|
|
82
133
|
const { propagatedFrom } = workspace;
|
|
@@ -88,23 +139,21 @@ ${sectionHeader(workspace.name)}`);
|
|
|
88
139
|
formatBumpFiles(lines, workspace, dryRun, " ");
|
|
89
140
|
lines.push(dim(" Generating changelogs..."));
|
|
90
141
|
formatChangelogFiles(lines, workspace, dryRun, " ");
|
|
91
|
-
|
|
92
|
-
lines.push(` \u{1F3F7}\uFE0F ${bold(workspace.tag)}`);
|
|
93
|
-
}
|
|
142
|
+
lines.push(` \u{1F3F7}\uFE0F ${bold(workspace.tag)}`);
|
|
94
143
|
}
|
|
95
144
|
function formatCommitSummary(lines, workspace, propagatedFrom, isPropagatedOnly) {
|
|
96
145
|
if (isPropagatedOnly && propagatedFrom !== void 0) {
|
|
97
146
|
const depNames = propagatedFrom.map((p) => p.packageName).join(", ");
|
|
98
147
|
lines.push(dim(` 0 commits (bumped via dependency: ${depNames})`));
|
|
99
|
-
} else if (workspace.parsedCommitCount !== void 0) {
|
|
148
|
+
} else if (workspace.parsedCommitCount !== void 0 && workspace.parsedCommitCount > 0) {
|
|
100
149
|
lines.push(dim(` Parsed ${workspace.parsedCommitCount} typed commits`));
|
|
101
150
|
}
|
|
102
151
|
}
|
|
103
152
|
function formatBumpLabels(lines, workspace, isPropagatedOnly) {
|
|
104
153
|
if (workspace.setVersion !== void 0) {
|
|
105
154
|
lines.push(` Using version override: ${workspace.setVersion}`);
|
|
106
|
-
} else if (workspace.
|
|
107
|
-
lines.push(` Using bump override: ${workspace.
|
|
155
|
+
} else if (workspace.bumpOverride !== void 0 && !isPropagatedOnly) {
|
|
156
|
+
lines.push(` Using bump override: ${workspace.bumpOverride}`);
|
|
108
157
|
}
|
|
109
158
|
if (workspace.releaseType !== void 0) {
|
|
110
159
|
lines.push(dim(` Bumping versions (${workspace.releaseType})...`));
|
|
@@ -113,9 +162,6 @@ function formatBumpLabels(lines, workspace, isPropagatedOnly) {
|
|
|
113
162
|
}
|
|
114
163
|
}
|
|
115
164
|
function formatVersionLine(lines, workspace, propagatedFrom, isPropagatedOnly) {
|
|
116
|
-
if (workspace.currentVersion === void 0 || workspace.newVersion === void 0) {
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
165
|
if (workspace.setVersion !== void 0) {
|
|
120
166
|
lines.push(` \u{1F4E6} ${workspace.currentVersion} \u2192 ${bold(workspace.newVersion)} (version override)`);
|
|
121
167
|
} else if (workspace.releaseType !== void 0) {
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -22,6 +22,12 @@ export interface ChangelogJsonConfig {
|
|
|
22
22
|
export interface ReleaseNotesConfig {
|
|
23
23
|
shouldInjectIntoReadme: boolean;
|
|
24
24
|
}
|
|
25
|
+
export interface ProjectConfig {
|
|
26
|
+
tagPrefix?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface ResolvedProjectConfig {
|
|
29
|
+
tagPrefix: string;
|
|
30
|
+
}
|
|
25
31
|
export interface PropagationSource {
|
|
26
32
|
packageName: string;
|
|
27
33
|
newVersion: string;
|
|
@@ -31,24 +37,58 @@ export interface BumpResult {
|
|
|
31
37
|
newVersion: string;
|
|
32
38
|
files: string[];
|
|
33
39
|
}
|
|
34
|
-
export interface
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
previousTag?: string
|
|
40
|
+
export interface ReleasedWorkspaceResult {
|
|
41
|
+
status: 'released';
|
|
42
|
+
name?: string;
|
|
43
|
+
previousTag?: string;
|
|
38
44
|
commitCount: number;
|
|
39
|
-
parsedCommitCount?: number
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
45
|
+
parsedCommitCount?: number;
|
|
46
|
+
unparseableCommits?: Commit[];
|
|
47
|
+
releaseType?: ReleaseType;
|
|
48
|
+
currentVersion: string;
|
|
49
|
+
newVersion: string;
|
|
50
|
+
tag: string;
|
|
44
51
|
bumpedFiles: string[];
|
|
45
52
|
changelogFiles: string[];
|
|
46
|
-
commits?: Commit[]
|
|
47
|
-
|
|
48
|
-
propagatedFrom?: PropagationSource[]
|
|
49
|
-
|
|
50
|
-
|
|
53
|
+
commits?: Commit[];
|
|
54
|
+
bumpOverride?: ReleaseType;
|
|
55
|
+
propagatedFrom?: PropagationSource[];
|
|
56
|
+
setVersion?: string;
|
|
57
|
+
}
|
|
58
|
+
export interface SkippedWorkspaceResult {
|
|
59
|
+
status: 'skipped';
|
|
60
|
+
name?: string;
|
|
61
|
+
previousTag?: string;
|
|
62
|
+
commitCount: number;
|
|
63
|
+
parsedCommitCount?: number;
|
|
64
|
+
unparseableCommits?: Commit[];
|
|
65
|
+
skipReason: string;
|
|
66
|
+
}
|
|
67
|
+
export type WorkspacePrepareResult = ReleasedWorkspaceResult | SkippedWorkspaceResult;
|
|
68
|
+
export interface ReleasedProjectResult {
|
|
69
|
+
status: 'released';
|
|
70
|
+
previousTag?: string;
|
|
71
|
+
commitCount: number;
|
|
72
|
+
parsedCommitCount: number;
|
|
73
|
+
unparseableCommits?: Commit[];
|
|
74
|
+
releaseType: ReleaseType;
|
|
75
|
+
currentVersion: string;
|
|
76
|
+
newVersion: string;
|
|
77
|
+
tag: string;
|
|
78
|
+
bumpedFiles: string[];
|
|
79
|
+
changelogFiles: string[];
|
|
80
|
+
commits: Commit[];
|
|
81
|
+
bumpOverride?: ReleaseType;
|
|
82
|
+
}
|
|
83
|
+
export interface SkippedProjectResult {
|
|
84
|
+
status: 'skipped';
|
|
85
|
+
previousTag?: string;
|
|
86
|
+
commitCount: number;
|
|
87
|
+
parsedCommitCount: number;
|
|
88
|
+
unparseableCommits?: Commit[];
|
|
89
|
+
skipReason: string;
|
|
51
90
|
}
|
|
91
|
+
export type ProjectPrepareResult = ReleasedProjectResult | SkippedProjectResult;
|
|
52
92
|
export interface PrepareResult {
|
|
53
93
|
workspaces: WorkspacePrepareResult[];
|
|
54
94
|
tags: string[];
|
|
@@ -59,6 +99,7 @@ export interface PrepareResult {
|
|
|
59
99
|
} | undefined;
|
|
60
100
|
dryRun: boolean;
|
|
61
101
|
warnings?: string[] | undefined;
|
|
102
|
+
project?: ProjectPrepareResult | undefined;
|
|
62
103
|
}
|
|
63
104
|
export interface WorkTypeConfig {
|
|
64
105
|
header: string;
|
|
@@ -78,6 +119,7 @@ export interface ReleaseKitConfig {
|
|
|
78
119
|
changelogJson?: Partial<ChangelogJsonConfig>;
|
|
79
120
|
releaseNotes?: Partial<ReleaseNotesConfig>;
|
|
80
121
|
retiredPackages?: RetiredPackage[];
|
|
122
|
+
project?: ProjectConfig;
|
|
81
123
|
}
|
|
82
124
|
export interface LegacyIdentity {
|
|
83
125
|
name: string;
|
|
@@ -124,6 +166,7 @@ export interface MonorepoReleaseConfig {
|
|
|
124
166
|
scopeAliases?: Record<string, string>;
|
|
125
167
|
changelogJson: ChangelogJsonConfig;
|
|
126
168
|
releaseNotes: ReleaseNotesConfig;
|
|
169
|
+
project?: ResolvedProjectConfig;
|
|
127
170
|
}
|
|
128
171
|
export interface ReleaseConfig {
|
|
129
172
|
tagPrefix: string;
|
|
@@ -9,6 +9,7 @@ function validateConfig(raw) {
|
|
|
9
9
|
"changelogJson",
|
|
10
10
|
"cliffConfigPath",
|
|
11
11
|
"formatCommand",
|
|
12
|
+
"project",
|
|
12
13
|
"releaseNotes",
|
|
13
14
|
"retiredPackages",
|
|
14
15
|
"scopeAliases",
|
|
@@ -30,6 +31,7 @@ function validateConfig(raw) {
|
|
|
30
31
|
validateStringField("cliffConfigPath", raw.cliffConfigPath, config, errors);
|
|
31
32
|
validateScopeAliases(raw.scopeAliases, config, errors);
|
|
32
33
|
validateRetiredPackages(raw.retiredPackages, config, errors);
|
|
34
|
+
validateProjectConfig(raw.project, config, errors);
|
|
33
35
|
const warnings = [];
|
|
34
36
|
const changelogJsonEnabled = config.changelogJson?.enabled ?? true;
|
|
35
37
|
if (!changelogJsonEnabled && config.releaseNotes?.shouldInjectIntoReadme) {
|
|
@@ -75,6 +77,30 @@ function validateChangelogJson(value, config, errors) {
|
|
|
75
77
|
}
|
|
76
78
|
config.changelogJson = result;
|
|
77
79
|
}
|
|
80
|
+
function validateProjectConfig(value, config, errors) {
|
|
81
|
+
if (value === void 0) return;
|
|
82
|
+
if (!isRecord(value)) {
|
|
83
|
+
errors.push("'project' must be an object");
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const knownProjectFields = /* @__PURE__ */ new Set(["tagPrefix"]);
|
|
87
|
+
for (const key of Object.keys(value)) {
|
|
88
|
+
if (!knownProjectFields.has(key)) {
|
|
89
|
+
errors.push(`project: unknown field '${key}'`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const result = {};
|
|
93
|
+
if (value.tagPrefix !== void 0) {
|
|
94
|
+
if (typeof value.tagPrefix !== "string") {
|
|
95
|
+
errors.push("project.tagPrefix: must be a string");
|
|
96
|
+
} else if (value.tagPrefix === "") {
|
|
97
|
+
errors.push("project.tagPrefix: must be a non-empty string");
|
|
98
|
+
} else {
|
|
99
|
+
result.tagPrefix = value.tagPrefix;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
config.project = result;
|
|
103
|
+
}
|
|
78
104
|
function validateReleaseNotes(value, config, errors) {
|
|
79
105
|
if (value === void 0) return;
|
|
80
106
|
if (!isRecord(value)) {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DependencyGraph } from './buildDependencyGraph.ts';
|
|
2
|
+
import type { WorkspaceConfig } from './types.ts';
|
|
3
|
+
export interface CommitsProbeResult {
|
|
4
|
+
has: boolean;
|
|
5
|
+
tag: string | undefined;
|
|
6
|
+
}
|
|
7
|
+
export interface StrandedDependentViolation {
|
|
8
|
+
dir: string;
|
|
9
|
+
downstreamOf: string;
|
|
10
|
+
tag: string | undefined;
|
|
11
|
+
}
|
|
12
|
+
type CommitsProbe = (workspace: WorkspaceConfig) => CommitsProbeResult;
|
|
13
|
+
export declare function validateOnlyExcludesStrandedDependents(workspaces: readonly WorkspaceConfig[], only: readonly string[], graph: DependencyGraph, hasCommits: CommitsProbe): StrandedDependentViolation[] | undefined;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
function validateOnlyExcludesStrandedDependents(workspaces, only, graph, hasCommits) {
|
|
2
|
+
const probeCommits = memoizeCommitsProbe(hasCommits);
|
|
3
|
+
const workspaceByDir = new Map(workspaces.map((w) => [w.dir, w]));
|
|
4
|
+
const released = computeReleasedSet(only, workspaceByDir, graph, probeCommits);
|
|
5
|
+
const violations = collectStrandedViolations(released, new Set(only), graph, probeCommits);
|
|
6
|
+
if (violations.length === 0) return void 0;
|
|
7
|
+
violations.sort((a, b) => a.dir.localeCompare(b.dir));
|
|
8
|
+
return violations;
|
|
9
|
+
}
|
|
10
|
+
function memoizeCommitsProbe(probe) {
|
|
11
|
+
const cache = /* @__PURE__ */ new Map();
|
|
12
|
+
return (workspace) => {
|
|
13
|
+
const cached = cache.get(workspace.dir);
|
|
14
|
+
if (cached !== void 0) return cached;
|
|
15
|
+
const result = probe(workspace);
|
|
16
|
+
cache.set(workspace.dir, result);
|
|
17
|
+
return result;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function computeReleasedSet(only, workspaceByDir, graph, probeCommits) {
|
|
21
|
+
const released = /* @__PURE__ */ new Set();
|
|
22
|
+
for (const dir of only) {
|
|
23
|
+
const workspace = workspaceByDir.get(dir);
|
|
24
|
+
if (workspace !== void 0 && probeCommits(workspace).has) {
|
|
25
|
+
released.add(dir);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
let changed = true;
|
|
29
|
+
while (changed) {
|
|
30
|
+
changed = false;
|
|
31
|
+
for (const dir of only) {
|
|
32
|
+
if (released.has(dir)) continue;
|
|
33
|
+
if (hasDependencyIn(dir, graph, released)) {
|
|
34
|
+
released.add(dir);
|
|
35
|
+
changed = true;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return released;
|
|
40
|
+
}
|
|
41
|
+
function hasDependencyIn(dir, graph, released) {
|
|
42
|
+
const forwardDeps = graph.dependenciesOf.get(dir);
|
|
43
|
+
if (forwardDeps === void 0) return false;
|
|
44
|
+
for (const depPackageName of forwardDeps) {
|
|
45
|
+
const depDir = graph.packageNameToDir.get(depPackageName);
|
|
46
|
+
if (depDir !== void 0 && released.has(depDir)) return true;
|
|
47
|
+
}
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
function collectStrandedViolations(released, onlySet, graph, probeCommits) {
|
|
51
|
+
const violations = [];
|
|
52
|
+
const violationDirs = /* @__PURE__ */ new Set();
|
|
53
|
+
const visited = /* @__PURE__ */ new Set();
|
|
54
|
+
const queue = [];
|
|
55
|
+
for (const dir of released) {
|
|
56
|
+
const packageName = graph.dirToPackageName.get(dir);
|
|
57
|
+
if (packageName !== void 0) {
|
|
58
|
+
queue.push({ packageName, attributionRoot: dir });
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
while (queue.length > 0) {
|
|
62
|
+
const item = queue.shift();
|
|
63
|
+
if (item === void 0) break;
|
|
64
|
+
if (visited.has(item.packageName)) continue;
|
|
65
|
+
visited.add(item.packageName);
|
|
66
|
+
const dependents = graph.dependentsOf.get(item.packageName);
|
|
67
|
+
if (dependents === void 0) continue;
|
|
68
|
+
for (const dependent of dependents) {
|
|
69
|
+
visitDependent(dependent, item.attributionRoot, {
|
|
70
|
+
released,
|
|
71
|
+
onlySet,
|
|
72
|
+
graph,
|
|
73
|
+
probeCommits,
|
|
74
|
+
queue,
|
|
75
|
+
violations,
|
|
76
|
+
violationDirs
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return violations;
|
|
81
|
+
}
|
|
82
|
+
function visitDependent(dependent, attributionRoot, ctx) {
|
|
83
|
+
if (ctx.onlySet.has(dependent.dir)) {
|
|
84
|
+
if (ctx.released.has(dependent.dir)) {
|
|
85
|
+
enqueueDependent(dependent, ctx);
|
|
86
|
+
}
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const probe = ctx.probeCommits(dependent);
|
|
90
|
+
if (!probe.has) return;
|
|
91
|
+
if (!ctx.violationDirs.has(dependent.dir)) {
|
|
92
|
+
ctx.violationDirs.add(dependent.dir);
|
|
93
|
+
ctx.violations.push({
|
|
94
|
+
dir: dependent.dir,
|
|
95
|
+
downstreamOf: attributionRoot,
|
|
96
|
+
tag: probe.tag
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
enqueueDependent(dependent, ctx);
|
|
100
|
+
}
|
|
101
|
+
function enqueueDependent(dependent, ctx) {
|
|
102
|
+
const packageName = ctx.graph.dirToPackageName.get(dependent.dir);
|
|
103
|
+
if (packageName !== void 0) {
|
|
104
|
+
ctx.queue.push({ packageName, attributionRoot: dependent.dir });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
export {
|
|
108
|
+
validateOnlyExcludesStrandedDependents
|
|
109
|
+
};
|
package/dist/esm/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "5.
|
|
1
|
+
export declare const VERSION = "5.1.0";
|
package/dist/esm/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@williamthorsen/release-kit",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.1.0",
|
|
4
4
|
"description": "Version-bumping and changelog-generation toolkit for release workflows",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"homepage": "https://github.com/williamthorsen/node-monorepo-tools/tree/main/packages/release-kit#readme",
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"dist/*",
|
|
29
29
|
"cliff.toml.template",
|
|
30
30
|
"presets/**",
|
|
31
|
+
"schemas/**",
|
|
31
32
|
"CHANGELOG.md"
|
|
32
33
|
],
|
|
33
34
|
"dependencies": {
|
|
@@ -35,10 +36,12 @@
|
|
|
35
36
|
"jiti": "2.6.1",
|
|
36
37
|
"js-yaml": "4.1.1",
|
|
37
38
|
"json-stringify-pretty-compact": "4.0.0",
|
|
39
|
+
"semver": "7.7.4",
|
|
38
40
|
"@williamthorsen/nmr-core": "0.3.0"
|
|
39
41
|
},
|
|
40
42
|
"devDependencies": {
|
|
41
43
|
"@types/js-yaml": "4.0.9",
|
|
44
|
+
"@types/semver": "7.7.1",
|
|
42
45
|
"smol-toml": "1.6.1"
|
|
43
46
|
},
|
|
44
47
|
"engines": {
|
|
@@ -8,18 +8,21 @@
|
|
|
8
8
|
- name: bug
|
|
9
9
|
color: d73a4a
|
|
10
10
|
description: "Something isn't working"
|
|
11
|
-
- name: documentation
|
|
12
|
-
color: a2eeef
|
|
13
|
-
description: Improvements or additions to documentation
|
|
14
11
|
- name: deprecation
|
|
15
12
|
color: fbca04
|
|
16
13
|
description: Marks functionality for future removal
|
|
14
|
+
- name: documentation
|
|
15
|
+
color: a2eeef
|
|
16
|
+
description: Improvements or additions to documentation
|
|
17
17
|
- name: feature
|
|
18
18
|
color: '0075ca'
|
|
19
19
|
description: Added or improved external functionality
|
|
20
20
|
- name: fix
|
|
21
21
|
color: d73a4a
|
|
22
22
|
description: Fixes a bug
|
|
23
|
+
- name: operational
|
|
24
|
+
color: '000000'
|
|
25
|
+
description: Actions outside the codebase
|
|
23
26
|
- name: performance
|
|
24
27
|
color: '0075ca'
|
|
25
28
|
description: Improves performance without changing behavior
|
|
@@ -48,6 +51,9 @@
|
|
|
48
51
|
- name: dependencies
|
|
49
52
|
color: edc287
|
|
50
53
|
description: Change to dependencies
|
|
54
|
+
- name: internal
|
|
55
|
+
color: 1d76db
|
|
56
|
+
description: Internal change without external impact
|
|
51
57
|
- name: refactoring
|
|
52
58
|
color: edc287
|
|
53
59
|
description: Improvement to code without change in functionality
|
|
@@ -57,9 +63,6 @@
|
|
|
57
63
|
- name: tooling
|
|
58
64
|
color: edc287
|
|
59
65
|
description: Development tools
|
|
60
|
-
- name: utility
|
|
61
|
-
color: 1d76db
|
|
62
|
-
description: Changed internal functionality
|
|
63
66
|
|
|
64
67
|
# Priority
|
|
65
68
|
- name: 'priority:critical'
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "label-map",
|
|
4
|
+
"description": "Maps commit-prefix scopes and types to GitHub label names. Consumed by agent skills, CI tooling, and any script that needs to translate commit conventions into label operations.",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["types", "scopes"],
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"$schema": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"description": "JSON Schema reference for editor support."
|
|
12
|
+
},
|
|
13
|
+
"types": {
|
|
14
|
+
"type": "object",
|
|
15
|
+
"description": "Maps commit-type prefix (e.g., `feat`) to GitHub label name (e.g., `feature`).",
|
|
16
|
+
"additionalProperties": { "type": "string" }
|
|
17
|
+
},
|
|
18
|
+
"scopes": {
|
|
19
|
+
"type": "object",
|
|
20
|
+
"description": "Maps commit-scope prefix (e.g., `audit`) to GitHub label name (e.g., `scope:audit`).",
|
|
21
|
+
"additionalProperties": { "type": "string" }
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { GenerateChangelogOptions } from './generateChangelogs.ts';
|
|
2
|
-
import type { ReleaseConfig } from './types.ts';
|
|
3
|
-
export declare function generateChangelogJson(config: Pick<ReleaseConfig, 'cliffConfigPath' | 'changelogJson'>, changelogPath: string, tag: string, dryRun: boolean, options?: GenerateChangelogOptions): string[];
|
|
4
|
-
export declare function generateSyntheticChangelogJson(config: Pick<ReleaseConfig, 'changelogJson'>, changelogPath: string, newVersion: string, date: string, propagatedFrom: Array<{
|
|
5
|
-
packageName: string;
|
|
6
|
-
newVersion: string;
|
|
7
|
-
}>, dryRun: boolean): string[];
|