@williamthorsen/release-kit 5.0.0 → 5.2.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 +149 -49
- package/README.md +275 -78
- package/cliff.toml.template +26 -17
- package/dist/esm/.cache +1 -1
- package/dist/esm/assertCleanWorkingTree.js +1 -1
- package/dist/esm/bin/release-kit.js +97 -4
- package/dist/esm/buildChangelogEntries.d.ts +4 -0
- package/dist/esm/buildChangelogEntries.js +173 -0
- 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/checkWorkTypesDrift.d.ts +11 -0
- package/dist/esm/checkWorkTypesDrift.js +110 -0
- package/dist/esm/collectPolicyViolations.d.ts +6 -0
- package/dist/esm/collectPolicyViolations.js +15 -0
- package/dist/esm/createGithubRelease.d.ts +12 -2
- package/dist/esm/createGithubRelease.js +12 -8
- package/dist/esm/createGithubReleaseCommand.js +10 -6
- package/dist/esm/decideRelease.d.ts +28 -0
- package/dist/esm/decideRelease.js +44 -0
- package/dist/esm/defaults.d.ts +8 -0
- package/dist/esm/defaults.js +43 -20
- package/dist/esm/deriveWorkspaceConfig.js +3 -0
- package/dist/esm/determineBumpFromCommits.d.ts +6 -1
- package/dist/esm/determineBumpFromCommits.js +9 -3
- package/dist/esm/generateChangelogs.js +14 -29
- 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 +110 -24
- package/dist/esm/parseCommitMessage.d.ts +8 -2
- package/dist/esm/parseCommitMessage.js +32 -3
- 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 +31 -3
- package/dist/esm/releasePrepare.js +109 -41
- package/dist/esm/releasePrepareMono.js +156 -87
- package/dist/esm/releasePrepareProject.d.ts +9 -0
- package/dist/esm/releasePrepareProject.js +121 -0
- package/dist/esm/renderReleaseNotes.js +2 -1
- package/dist/esm/reportPrepare.js +88 -24
- package/dist/esm/resolveCommandTags.js +16 -6
- package/dist/esm/resolveReleaseTags.d.ts +8 -1
- package/dist/esm/resolveReleaseTags.js +11 -7
- package/dist/esm/runGitCliff.d.ts +2 -0
- package/dist/esm/runGitCliff.js +27 -0
- package/dist/esm/stripEmojiPrefix.d.ts +1 -0
- package/dist/esm/stripEmojiPrefix.js +7 -0
- package/dist/esm/syncWorkTypes.d.ts +10 -0
- package/dist/esm/syncWorkTypes.js +90 -0
- package/dist/esm/types.d.ts +72 -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/work-types.json +127 -0
- package/dist/esm/work-types.schema.json +73 -0
- package/dist/esm/workTypesData.d.ts +14 -0
- package/dist/esm/workTypesData.js +59 -0
- package/dist/esm/workTypesUtils.d.ts +5 -0
- package/dist/esm/workTypesUtils.js +16 -0
- package/package.json +9 -3
- package/presets/labels/common.yaml +9 -6
- package/schemas/label-map.json +24 -0
- package/dist/esm/generateChangelogJson.d.ts +0 -7
- package/dist/esm/generateChangelogJson.js +0 -232
- package/dist/esm/version.d.ts +0 -1
- package/dist/esm/version.js +0 -4
|
@@ -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[];
|
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
import { execFileSync } from "node:child_process";
|
|
2
|
-
import { copyFileSync, existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
|
-
import { dirname, join } from "node:path";
|
|
5
|
-
import stringify from "json-stringify-pretty-compact";
|
|
6
|
-
import { extractVersion, isChangelogEntry } from "./changelogJsonUtils.js";
|
|
7
|
-
import { resolveCliffConfigPath } from "./resolveCliffConfigPath.js";
|
|
8
|
-
import { isRecord, isUnknownArray } from "./typeGuards.js";
|
|
9
|
-
function generateChangelogJson(config, changelogPath, tag, dryRun, options) {
|
|
10
|
-
const outputFile = join(changelogPath, config.changelogJson.outputPath);
|
|
11
|
-
if (dryRun) {
|
|
12
|
-
return [outputFile];
|
|
13
|
-
}
|
|
14
|
-
const resolvedConfigPath = resolveCliffConfigPath(config.cliffConfigPath, import.meta.url);
|
|
15
|
-
let cliffConfigPath = resolvedConfigPath;
|
|
16
|
-
let tempDir;
|
|
17
|
-
if (resolvedConfigPath.endsWith(".template")) {
|
|
18
|
-
tempDir = mkdtempSync(join(tmpdir(), "cliff-"));
|
|
19
|
-
cliffConfigPath = join(tempDir, "cliff.toml");
|
|
20
|
-
copyFileSync(resolvedConfigPath, cliffConfigPath);
|
|
21
|
-
}
|
|
22
|
-
const args = ["--config", cliffConfigPath, "--context", "--tag", tag];
|
|
23
|
-
if (options?.tagPattern !== void 0) {
|
|
24
|
-
args.push("--tag-pattern", options.tagPattern);
|
|
25
|
-
}
|
|
26
|
-
for (const includePath of options?.includePaths ?? []) {
|
|
27
|
-
args.push("--include-path", includePath);
|
|
28
|
-
}
|
|
29
|
-
try {
|
|
30
|
-
const contextJson = execFileSync("npx", ["--yes", "git-cliff", ...args], {
|
|
31
|
-
encoding: "utf8",
|
|
32
|
-
stdio: ["pipe", "pipe", "inherit"]
|
|
33
|
-
});
|
|
34
|
-
const releases = parseCliffContext(contextJson);
|
|
35
|
-
const devOnlySections = new Set(config.changelogJson.devOnlySections);
|
|
36
|
-
const entries = transformReleases(releases, devOnlySections);
|
|
37
|
-
const existingEntries = readExistingEntries(outputFile);
|
|
38
|
-
const merged = mergeEntries(entries, existingEntries);
|
|
39
|
-
mkdirSync(dirname(outputFile), { recursive: true });
|
|
40
|
-
writeFileSync(outputFile, stringify(merged, { maxLength: 100 }) + "\n", "utf8");
|
|
41
|
-
return [outputFile];
|
|
42
|
-
} catch (error) {
|
|
43
|
-
throw new Error(
|
|
44
|
-
`Failed to generate changelog JSON for ${outputFile}: ${error instanceof Error ? error.message : String(error)}`
|
|
45
|
-
);
|
|
46
|
-
} finally {
|
|
47
|
-
if (tempDir !== void 0) {
|
|
48
|
-
rmSync(tempDir, { recursive: true, force: true });
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
function generateSyntheticChangelogJson(config, changelogPath, newVersion, date, propagatedFrom, dryRun) {
|
|
53
|
-
const outputFile = join(changelogPath, config.changelogJson.outputPath);
|
|
54
|
-
if (dryRun) {
|
|
55
|
-
return [outputFile];
|
|
56
|
-
}
|
|
57
|
-
const items = propagatedFrom.map((dep) => ({
|
|
58
|
-
description: `Bumped \`${dep.packageName}\` to ${dep.newVersion}`
|
|
59
|
-
}));
|
|
60
|
-
const entry = {
|
|
61
|
-
version: newVersion,
|
|
62
|
-
date,
|
|
63
|
-
sections: [{ title: "Dependency updates", audience: "dev", items }]
|
|
64
|
-
};
|
|
65
|
-
const existingEntries = readExistingEntries(outputFile);
|
|
66
|
-
const merged = mergeEntries([entry], existingEntries);
|
|
67
|
-
mkdirSync(dirname(outputFile), { recursive: true });
|
|
68
|
-
writeFileSync(outputFile, stringify(merged, { maxLength: 100 }) + "\n", "utf8");
|
|
69
|
-
return [outputFile];
|
|
70
|
-
}
|
|
71
|
-
function parseCliffContext(json) {
|
|
72
|
-
const parsed = JSON.parse(json);
|
|
73
|
-
if (!isUnknownArray(parsed)) {
|
|
74
|
-
throw new TypeError("Expected git-cliff --context output to be an array");
|
|
75
|
-
}
|
|
76
|
-
return parsed.map(toCliffContextRelease);
|
|
77
|
-
}
|
|
78
|
-
function toCliffContextRelease(value) {
|
|
79
|
-
if (!isRecord(value)) {
|
|
80
|
-
return {};
|
|
81
|
-
}
|
|
82
|
-
const release = {};
|
|
83
|
-
if (typeof value.version === "string") {
|
|
84
|
-
release.version = value.version;
|
|
85
|
-
}
|
|
86
|
-
if (typeof value.timestamp === "number") {
|
|
87
|
-
release.timestamp = value.timestamp;
|
|
88
|
-
}
|
|
89
|
-
if (isUnknownArray(value.commits)) {
|
|
90
|
-
release.commits = value.commits.map(toCliffContextCommit);
|
|
91
|
-
}
|
|
92
|
-
return release;
|
|
93
|
-
}
|
|
94
|
-
function toCliffContextCommit(value) {
|
|
95
|
-
if (!isRecord(value)) {
|
|
96
|
-
return { message: "" };
|
|
97
|
-
}
|
|
98
|
-
const commit = {
|
|
99
|
-
message: typeof value.message === "string" ? value.message : ""
|
|
100
|
-
};
|
|
101
|
-
if (typeof value.group === "string") {
|
|
102
|
-
commit.group = value.group;
|
|
103
|
-
}
|
|
104
|
-
return commit;
|
|
105
|
-
}
|
|
106
|
-
function transformReleases(releases, devOnlySections) {
|
|
107
|
-
const entries = [];
|
|
108
|
-
for (const release of releases) {
|
|
109
|
-
if (release.version === void 0) {
|
|
110
|
-
continue;
|
|
111
|
-
}
|
|
112
|
-
const version = extractVersion(release.version);
|
|
113
|
-
const date = release.timestamp !== void 0 ? new Date(release.timestamp * 1e3).toISOString().slice(0, 10) : "unreleased";
|
|
114
|
-
const sectionMap = /* @__PURE__ */ new Map();
|
|
115
|
-
for (const commit of release.commits ?? []) {
|
|
116
|
-
const group = commit.group ?? "Other";
|
|
117
|
-
const description = extractDescription(commit.message);
|
|
118
|
-
const body = extractBody(commit.message);
|
|
119
|
-
let items = sectionMap.get(group);
|
|
120
|
-
if (items === void 0) {
|
|
121
|
-
items = [];
|
|
122
|
-
sectionMap.set(group, items);
|
|
123
|
-
}
|
|
124
|
-
const item = { description };
|
|
125
|
-
if (body !== void 0) {
|
|
126
|
-
item.body = body;
|
|
127
|
-
}
|
|
128
|
-
items.push(item);
|
|
129
|
-
}
|
|
130
|
-
const sections = [];
|
|
131
|
-
for (const [title, items] of sectionMap) {
|
|
132
|
-
if (items.length === 0) {
|
|
133
|
-
continue;
|
|
134
|
-
}
|
|
135
|
-
sections.push({
|
|
136
|
-
title,
|
|
137
|
-
audience: devOnlySections.has(title) ? "dev" : "all",
|
|
138
|
-
items
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
if (sections.length > 0) {
|
|
142
|
-
entries.push({ version, date, sections });
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
return entries;
|
|
146
|
-
}
|
|
147
|
-
function extractDescription(message) {
|
|
148
|
-
const firstLine = message.split("\n")[0] ?? message;
|
|
149
|
-
const afterColon = firstLine.split(": ").slice(1).join(": ");
|
|
150
|
-
if (afterColon.length > 0) {
|
|
151
|
-
return afterColon.charAt(0).toUpperCase() + afterColon.slice(1);
|
|
152
|
-
}
|
|
153
|
-
return firstLine;
|
|
154
|
-
}
|
|
155
|
-
const TRAILER_PATTERNS = [
|
|
156
|
-
/^Signed-off-by:/i,
|
|
157
|
-
/^Co-authored-by:/i,
|
|
158
|
-
/^(Closes|Fixes|Resolves)\s+#\d+\s*$/i,
|
|
159
|
-
/^https?:\/\/\S+\/pull\/\d+\/?\s*$/
|
|
160
|
-
];
|
|
161
|
-
function extractBody(message) {
|
|
162
|
-
const lines = message.split("\n").slice(1);
|
|
163
|
-
let start = 0;
|
|
164
|
-
while (start < lines.length && (lines[start] ?? "").trim() === "") {
|
|
165
|
-
start += 1;
|
|
166
|
-
}
|
|
167
|
-
let end = lines.length;
|
|
168
|
-
while (end > start) {
|
|
169
|
-
const line = lines[end - 1] ?? "";
|
|
170
|
-
const trimmed = line.trim();
|
|
171
|
-
if (trimmed === "") {
|
|
172
|
-
end -= 1;
|
|
173
|
-
continue;
|
|
174
|
-
}
|
|
175
|
-
if (TRAILER_PATTERNS.some((pattern) => pattern.test(trimmed))) {
|
|
176
|
-
end -= 1;
|
|
177
|
-
continue;
|
|
178
|
-
}
|
|
179
|
-
break;
|
|
180
|
-
}
|
|
181
|
-
if (end <= start) {
|
|
182
|
-
return void 0;
|
|
183
|
-
}
|
|
184
|
-
return lines.slice(start, end).join("\n").trim();
|
|
185
|
-
}
|
|
186
|
-
function readExistingEntries(filePath) {
|
|
187
|
-
if (!existsSync(filePath)) {
|
|
188
|
-
return [];
|
|
189
|
-
}
|
|
190
|
-
try {
|
|
191
|
-
const content = readFileSync(filePath, "utf8");
|
|
192
|
-
const parsed = JSON.parse(content);
|
|
193
|
-
if (!isUnknownArray(parsed)) {
|
|
194
|
-
return [];
|
|
195
|
-
}
|
|
196
|
-
return parsed.filter(isChangelogEntry);
|
|
197
|
-
} catch (error) {
|
|
198
|
-
console.warn(
|
|
199
|
-
`Warning: could not parse existing ${filePath}: ${error instanceof Error ? error.message : String(error)}; treating as empty`
|
|
200
|
-
);
|
|
201
|
-
return [];
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
function mergeEntries(newEntries, existingEntries) {
|
|
205
|
-
const versionMap = /* @__PURE__ */ new Map();
|
|
206
|
-
for (const entry of existingEntries) {
|
|
207
|
-
versionMap.set(entry.version, entry);
|
|
208
|
-
}
|
|
209
|
-
for (const entry of newEntries) {
|
|
210
|
-
versionMap.set(entry.version, entry);
|
|
211
|
-
}
|
|
212
|
-
return [...versionMap.values()].sort((a, b) => compareVersionsDescending(a.version, b.version));
|
|
213
|
-
}
|
|
214
|
-
function parseVersionParts(version) {
|
|
215
|
-
return version.split(".").map((s) => {
|
|
216
|
-
const n = Number(s);
|
|
217
|
-
return Number.isNaN(n) ? 0 : n;
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
function compareVersionsDescending(a, b) {
|
|
221
|
-
const partsA = parseVersionParts(a);
|
|
222
|
-
const partsB = parseVersionParts(b);
|
|
223
|
-
for (let i = 0; i < 3; i++) {
|
|
224
|
-
const diff = (partsB[i] ?? 0) - (partsA[i] ?? 0);
|
|
225
|
-
if (diff !== 0) return diff;
|
|
226
|
-
}
|
|
227
|
-
return 0;
|
|
228
|
-
}
|
|
229
|
-
export {
|
|
230
|
-
generateChangelogJson,
|
|
231
|
-
generateSyntheticChangelogJson
|
|
232
|
-
};
|
package/dist/esm/version.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const VERSION = "5.0.0";
|
package/dist/esm/version.js
DELETED