@releasekit/release 0.7.12 → 0.7.14
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/dist/cli.js +47438 -14
- package/dist/dispatcher.js +47446 -39
- package/dist/index.js +47340 -7
- package/package.json +6 -6
- package/dist/aggregator-IUQUAVJC-OQZ5KHNS.js +0 -18
- package/dist/baseError-DQHIJACF-4NWA3LJM.js +0 -12
- package/dist/chunk-275AVVZE.js +0 -382
- package/dist/chunk-3AKDKIIQ.js +0 -78
- package/dist/chunk-6UI4L62T.js +0 -1096
- package/dist/chunk-FEMWVXXM.js +0 -78
- package/dist/chunk-NOZSTVTV.js +0 -55
- package/dist/chunk-QDGNHERK.js +0 -1983
- package/dist/chunk-QUY54CTL.js +0 -25427
- package/dist/chunk-TC44YA6X.js +0 -25
- package/dist/chunk-TJ2FXMEO.js +0 -14177
- package/dist/chunk-YG3UFSB6.js +0 -2001
- package/dist/commandExecutor-E44ID5U4-P3RGRKGM.js +0 -14
- package/dist/dist-4RETAAT2.js +0 -42
- package/dist/dist-7RSHM4ZO.js +0 -37
- package/dist/dist-HVRDLODI.js +0 -59
- package/dist/dist-OP3T7BV6.js +0 -114
- package/dist/dist-TLL55DUA.js +0 -448
package/dist/chunk-6UI4L62T.js
DELETED
|
@@ -1,1096 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
init_esm_shims
|
|
3
|
-
} from "./chunk-NOZSTVTV.js";
|
|
4
|
-
|
|
5
|
-
// ../core/dist/index.js
|
|
6
|
-
init_esm_shims();
|
|
7
|
-
import * as fs from "fs";
|
|
8
|
-
import * as path from "path";
|
|
9
|
-
import { fileURLToPath } from "url";
|
|
10
|
-
import chalk from "chalk";
|
|
11
|
-
function readPackageVersion(importMetaUrl) {
|
|
12
|
-
try {
|
|
13
|
-
const dir = path.dirname(fileURLToPath(importMetaUrl));
|
|
14
|
-
const packageJsonPath = path.resolve(dir, "../package.json");
|
|
15
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
16
|
-
return packageJson.version ?? "0.0.0";
|
|
17
|
-
} catch {
|
|
18
|
-
return "0.0.0";
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
var LOG_LEVELS = {
|
|
22
|
-
error: 0,
|
|
23
|
-
warn: 1,
|
|
24
|
-
info: 2,
|
|
25
|
-
debug: 3,
|
|
26
|
-
trace: 4
|
|
27
|
-
};
|
|
28
|
-
var PREFIXES = {
|
|
29
|
-
error: "[ERROR]",
|
|
30
|
-
warn: "[WARN]",
|
|
31
|
-
info: "[INFO]",
|
|
32
|
-
debug: "[DEBUG]",
|
|
33
|
-
trace: "[TRACE]"
|
|
34
|
-
};
|
|
35
|
-
var COLORS = {
|
|
36
|
-
error: chalk.red,
|
|
37
|
-
warn: chalk.yellow,
|
|
38
|
-
info: chalk.blue,
|
|
39
|
-
debug: chalk.gray,
|
|
40
|
-
trace: chalk.dim
|
|
41
|
-
};
|
|
42
|
-
var currentLevel = "info";
|
|
43
|
-
var quietMode = false;
|
|
44
|
-
function setLogLevel(level) {
|
|
45
|
-
currentLevel = level;
|
|
46
|
-
}
|
|
47
|
-
function setQuietMode(quiet) {
|
|
48
|
-
quietMode = quiet;
|
|
49
|
-
}
|
|
50
|
-
function setJsonMode(_json) {
|
|
51
|
-
}
|
|
52
|
-
function shouldLog(level) {
|
|
53
|
-
if (quietMode && level !== "error") return false;
|
|
54
|
-
return LOG_LEVELS[level] <= LOG_LEVELS[currentLevel];
|
|
55
|
-
}
|
|
56
|
-
function log(message, level = "info") {
|
|
57
|
-
if (!shouldLog(level)) return;
|
|
58
|
-
const formatted = COLORS[level](`${PREFIXES[level]} ${message}`);
|
|
59
|
-
console.error(formatted);
|
|
60
|
-
}
|
|
61
|
-
function error(message) {
|
|
62
|
-
log(message, "error");
|
|
63
|
-
}
|
|
64
|
-
function warn(message) {
|
|
65
|
-
log(message, "warn");
|
|
66
|
-
}
|
|
67
|
-
function info(message) {
|
|
68
|
-
log(message, "info");
|
|
69
|
-
}
|
|
70
|
-
function success(message) {
|
|
71
|
-
if (!shouldLog("info")) return;
|
|
72
|
-
console.error(chalk.green(`[SUCCESS] ${message}`));
|
|
73
|
-
}
|
|
74
|
-
var ReleaseKitError = class _ReleaseKitError extends Error {
|
|
75
|
-
constructor(message) {
|
|
76
|
-
super(message);
|
|
77
|
-
this.name = this.constructor.name;
|
|
78
|
-
}
|
|
79
|
-
logError() {
|
|
80
|
-
log(this.message, "error");
|
|
81
|
-
if (this.suggestions.length > 0) {
|
|
82
|
-
log("\nSuggested solutions:", "info");
|
|
83
|
-
for (const [i, suggestion] of this.suggestions.entries()) {
|
|
84
|
-
log(`${i + 1}. ${suggestion}`, "info");
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
static isReleaseKitError(error2) {
|
|
89
|
-
return error2 instanceof _ReleaseKitError;
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
var EXIT_CODES = {
|
|
93
|
-
SUCCESS: 0,
|
|
94
|
-
GENERAL_ERROR: 1,
|
|
95
|
-
CONFIG_ERROR: 2,
|
|
96
|
-
INPUT_ERROR: 3,
|
|
97
|
-
TEMPLATE_ERROR: 4,
|
|
98
|
-
LLM_ERROR: 5,
|
|
99
|
-
GITHUB_ERROR: 6,
|
|
100
|
-
GIT_ERROR: 7,
|
|
101
|
-
VERSION_ERROR: 8,
|
|
102
|
-
PUBLISH_ERROR: 9
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
// src/release.ts
|
|
106
|
-
init_esm_shims();
|
|
107
|
-
import { execSync } from "child_process";
|
|
108
|
-
|
|
109
|
-
// ../config/dist/index.js
|
|
110
|
-
init_esm_shims();
|
|
111
|
-
import * as TOML from "smol-toml";
|
|
112
|
-
import * as fs3 from "fs";
|
|
113
|
-
import * as path3 from "path";
|
|
114
|
-
import { z as z2 } from "zod";
|
|
115
|
-
import { z } from "zod";
|
|
116
|
-
import * as fs2 from "fs";
|
|
117
|
-
import * as os from "os";
|
|
118
|
-
import * as path2 from "path";
|
|
119
|
-
var ConfigError = class extends ReleaseKitError {
|
|
120
|
-
code = "CONFIG_ERROR";
|
|
121
|
-
suggestions;
|
|
122
|
-
constructor(message, suggestions) {
|
|
123
|
-
super(message);
|
|
124
|
-
this.suggestions = suggestions ?? [
|
|
125
|
-
"Check that releasekit.config.json exists and is valid JSON",
|
|
126
|
-
"Run with --verbose for more details"
|
|
127
|
-
];
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
var MAX_JSONC_LENGTH = 1e5;
|
|
131
|
-
function parseJsonc(content) {
|
|
132
|
-
if (content.length > MAX_JSONC_LENGTH) {
|
|
133
|
-
throw new Error(`JSONC content too long: ${content.length} characters (max ${MAX_JSONC_LENGTH})`);
|
|
134
|
-
}
|
|
135
|
-
try {
|
|
136
|
-
return JSON.parse(content);
|
|
137
|
-
} catch {
|
|
138
|
-
const cleaned = content.replace(/\/\/[^\r\n]{0,10000}$/gm, "").replace(/\/\*[\s\S]{0,50000}?\*\//g, "").trim();
|
|
139
|
-
return JSON.parse(cleaned);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
var GitConfigSchema = z.object({
|
|
143
|
-
remote: z.string().default("origin"),
|
|
144
|
-
branch: z.string().default("main"),
|
|
145
|
-
pushMethod: z.enum(["auto", "ssh", "https"]).default("auto"),
|
|
146
|
-
/**
|
|
147
|
-
* Optional env var name containing a GitHub token for HTTPS pushes.
|
|
148
|
-
* When set, publish steps can use this token without mutating git remotes.
|
|
149
|
-
*/
|
|
150
|
-
httpsTokenEnv: z.string().optional(),
|
|
151
|
-
push: z.boolean().optional(),
|
|
152
|
-
skipHooks: z.boolean().optional()
|
|
153
|
-
});
|
|
154
|
-
var MonorepoConfigSchema = z.object({
|
|
155
|
-
mode: z.enum(["root", "packages", "both"]).optional(),
|
|
156
|
-
rootPath: z.string().optional(),
|
|
157
|
-
packagesPath: z.string().optional(),
|
|
158
|
-
mainPackage: z.string().optional()
|
|
159
|
-
});
|
|
160
|
-
var BranchPatternSchema = z.object({
|
|
161
|
-
pattern: z.string(),
|
|
162
|
-
releaseType: z.enum(["major", "minor", "patch", "prerelease"])
|
|
163
|
-
});
|
|
164
|
-
var VersionCargoConfigSchema = z.object({
|
|
165
|
-
enabled: z.boolean().default(true),
|
|
166
|
-
paths: z.array(z.string()).optional()
|
|
167
|
-
});
|
|
168
|
-
var VersionConfigSchema = z.object({
|
|
169
|
-
tagTemplate: z.string().default("v{version}"),
|
|
170
|
-
packageSpecificTags: z.boolean().default(false),
|
|
171
|
-
preset: z.string().default("conventional"),
|
|
172
|
-
sync: z.boolean().default(true),
|
|
173
|
-
packages: z.array(z.string()).default([]),
|
|
174
|
-
mainPackage: z.string().optional(),
|
|
175
|
-
updateInternalDependencies: z.enum(["major", "minor", "patch", "no-internal-update"]).default("minor"),
|
|
176
|
-
skip: z.array(z.string()).optional(),
|
|
177
|
-
commitMessage: z.string().optional(),
|
|
178
|
-
versionStrategy: z.enum(["branchPattern", "commitMessage"]).default("commitMessage"),
|
|
179
|
-
branchPatterns: z.array(BranchPatternSchema).optional(),
|
|
180
|
-
defaultReleaseType: z.enum(["major", "minor", "patch", "prerelease"]).optional(),
|
|
181
|
-
mismatchStrategy: z.enum(["error", "warn", "ignore", "prefer-package", "prefer-git"]).default("warn"),
|
|
182
|
-
versionPrefix: z.string().default(""),
|
|
183
|
-
prereleaseIdentifier: z.string().optional(),
|
|
184
|
-
strictReachable: z.boolean().default(false),
|
|
185
|
-
cargo: VersionCargoConfigSchema.optional()
|
|
186
|
-
});
|
|
187
|
-
var NpmConfigSchema = z.object({
|
|
188
|
-
enabled: z.boolean().default(true),
|
|
189
|
-
auth: z.enum(["auto", "oidc", "token"]).default("auto"),
|
|
190
|
-
provenance: z.boolean().default(true),
|
|
191
|
-
access: z.enum(["public", "restricted"]).default("public"),
|
|
192
|
-
registry: z.string().default("https://registry.npmjs.org"),
|
|
193
|
-
copyFiles: z.array(z.string()).default(["LICENSE"]),
|
|
194
|
-
tag: z.string().default("latest")
|
|
195
|
-
});
|
|
196
|
-
var CargoPublishConfigSchema = z.object({
|
|
197
|
-
enabled: z.boolean().default(false),
|
|
198
|
-
noVerify: z.boolean().default(false),
|
|
199
|
-
publishOrder: z.array(z.string()).default([]),
|
|
200
|
-
clean: z.boolean().default(false)
|
|
201
|
-
});
|
|
202
|
-
var PublishGitConfigSchema = z.object({
|
|
203
|
-
push: z.boolean().default(true),
|
|
204
|
-
pushMethod: z.enum(["auto", "ssh", "https"]).optional(),
|
|
205
|
-
remote: z.string().optional(),
|
|
206
|
-
branch: z.string().optional(),
|
|
207
|
-
httpsTokenEnv: z.string().optional(),
|
|
208
|
-
skipHooks: z.boolean().optional()
|
|
209
|
-
});
|
|
210
|
-
var GitHubReleaseConfigSchema = z.object({
|
|
211
|
-
enabled: z.boolean().default(true),
|
|
212
|
-
draft: z.boolean().default(true),
|
|
213
|
-
perPackage: z.boolean().default(true),
|
|
214
|
-
prerelease: z.union([z.literal("auto"), z.boolean()]).default("auto"),
|
|
215
|
-
/**
|
|
216
|
-
* Controls the source for the GitHub release body.
|
|
217
|
-
* - 'auto': Use release notes if enabled, else changelog, else GitHub auto-generated.
|
|
218
|
-
* - 'releaseNotes': Use LLM-generated release notes (requires notes.releaseNotes.enabled: true).
|
|
219
|
-
* - 'changelog': Use formatted changelog entries.
|
|
220
|
-
* - 'generated': Use GitHub's auto-generated notes.
|
|
221
|
-
* - 'none': No body.
|
|
222
|
-
*/
|
|
223
|
-
body: z.enum(["auto", "releaseNotes", "changelog", "generated", "none"]).default("auto"),
|
|
224
|
-
/**
|
|
225
|
-
* Template string for the GitHub release title when a package name is resolved.
|
|
226
|
-
* Available variables: ${packageName} (original scoped name), ${version} (e.g. "v1.0.0").
|
|
227
|
-
* Version-only tags (e.g. "v1.0.0") always use the tag as-is.
|
|
228
|
-
*/
|
|
229
|
-
/* biome-ignore lint/suspicious/noTemplateCurlyInString: default template value */
|
|
230
|
-
titleTemplate: z.string().default("${packageName}: ${version}")
|
|
231
|
-
});
|
|
232
|
-
var VerifyRegistryConfigSchema = z.object({
|
|
233
|
-
enabled: z.boolean().default(true),
|
|
234
|
-
maxAttempts: z.number().int().positive().default(5),
|
|
235
|
-
initialDelay: z.number().int().positive().default(15e3),
|
|
236
|
-
backoffMultiplier: z.number().positive().default(2)
|
|
237
|
-
});
|
|
238
|
-
var VerifyConfigSchema = z.object({
|
|
239
|
-
npm: VerifyRegistryConfigSchema.default({
|
|
240
|
-
enabled: true,
|
|
241
|
-
maxAttempts: 5,
|
|
242
|
-
initialDelay: 15e3,
|
|
243
|
-
backoffMultiplier: 2
|
|
244
|
-
}),
|
|
245
|
-
cargo: VerifyRegistryConfigSchema.default({
|
|
246
|
-
enabled: true,
|
|
247
|
-
maxAttempts: 10,
|
|
248
|
-
initialDelay: 3e4,
|
|
249
|
-
backoffMultiplier: 2
|
|
250
|
-
})
|
|
251
|
-
});
|
|
252
|
-
var PublishConfigSchema = z.object({
|
|
253
|
-
git: PublishGitConfigSchema.optional(),
|
|
254
|
-
npm: NpmConfigSchema.default({
|
|
255
|
-
enabled: true,
|
|
256
|
-
auth: "auto",
|
|
257
|
-
provenance: true,
|
|
258
|
-
access: "public",
|
|
259
|
-
registry: "https://registry.npmjs.org",
|
|
260
|
-
copyFiles: ["LICENSE"],
|
|
261
|
-
tag: "latest"
|
|
262
|
-
}),
|
|
263
|
-
cargo: CargoPublishConfigSchema.default({
|
|
264
|
-
enabled: false,
|
|
265
|
-
noVerify: false,
|
|
266
|
-
publishOrder: [],
|
|
267
|
-
clean: false
|
|
268
|
-
}),
|
|
269
|
-
githubRelease: GitHubReleaseConfigSchema.default({
|
|
270
|
-
enabled: true,
|
|
271
|
-
draft: true,
|
|
272
|
-
perPackage: true,
|
|
273
|
-
prerelease: "auto",
|
|
274
|
-
body: "auto",
|
|
275
|
-
/* biome-ignore lint/suspicious/noTemplateCurlyInString: default template value */
|
|
276
|
-
titleTemplate: "${packageName}: ${version}"
|
|
277
|
-
}),
|
|
278
|
-
verify: VerifyConfigSchema.default({
|
|
279
|
-
npm: {
|
|
280
|
-
enabled: true,
|
|
281
|
-
maxAttempts: 5,
|
|
282
|
-
initialDelay: 15e3,
|
|
283
|
-
backoffMultiplier: 2
|
|
284
|
-
},
|
|
285
|
-
cargo: {
|
|
286
|
-
enabled: true,
|
|
287
|
-
maxAttempts: 10,
|
|
288
|
-
initialDelay: 3e4,
|
|
289
|
-
backoffMultiplier: 2
|
|
290
|
-
}
|
|
291
|
-
})
|
|
292
|
-
});
|
|
293
|
-
var TemplateConfigSchema = z.object({
|
|
294
|
-
path: z.string().optional(),
|
|
295
|
-
engine: z.enum(["handlebars", "liquid", "ejs"]).optional()
|
|
296
|
-
});
|
|
297
|
-
var LocationModeSchema = z.enum(["root", "packages", "both"]);
|
|
298
|
-
var ChangelogConfigSchema = z.object({
|
|
299
|
-
mode: LocationModeSchema.optional(),
|
|
300
|
-
file: z.string().optional(),
|
|
301
|
-
templates: TemplateConfigSchema.optional()
|
|
302
|
-
});
|
|
303
|
-
var LLMOptionsSchema = z.object({
|
|
304
|
-
timeout: z.number().optional(),
|
|
305
|
-
maxTokens: z.number().optional(),
|
|
306
|
-
temperature: z.number().optional()
|
|
307
|
-
});
|
|
308
|
-
var LLMRetryConfigSchema = z.object({
|
|
309
|
-
maxAttempts: z.number().int().positive().optional(),
|
|
310
|
-
initialDelay: z.number().nonnegative().optional(),
|
|
311
|
-
maxDelay: z.number().positive().optional(),
|
|
312
|
-
backoffFactor: z.number().positive().optional()
|
|
313
|
-
});
|
|
314
|
-
var LLMTasksConfigSchema = z.object({
|
|
315
|
-
summarize: z.boolean().optional(),
|
|
316
|
-
enhance: z.boolean().optional(),
|
|
317
|
-
categorize: z.boolean().optional(),
|
|
318
|
-
releaseNotes: z.boolean().optional()
|
|
319
|
-
});
|
|
320
|
-
var LLMCategorySchema = z.object({
|
|
321
|
-
name: z.string(),
|
|
322
|
-
description: z.string(),
|
|
323
|
-
scopes: z.array(z.string()).optional()
|
|
324
|
-
});
|
|
325
|
-
var ScopeRulesSchema = z.object({
|
|
326
|
-
allowed: z.array(z.string()).optional(),
|
|
327
|
-
caseSensitive: z.boolean().default(false),
|
|
328
|
-
invalidScopeAction: z.enum(["remove", "keep", "fallback"]).default("remove"),
|
|
329
|
-
fallbackScope: z.string().optional()
|
|
330
|
-
});
|
|
331
|
-
var ScopeConfigSchema = z.object({
|
|
332
|
-
mode: z.enum(["restricted", "packages", "none", "unrestricted"]).default("unrestricted"),
|
|
333
|
-
rules: ScopeRulesSchema.optional()
|
|
334
|
-
});
|
|
335
|
-
var LLMPromptOverridesSchema = z.object({
|
|
336
|
-
enhance: z.string().optional(),
|
|
337
|
-
categorize: z.string().optional(),
|
|
338
|
-
enhanceAndCategorize: z.string().optional(),
|
|
339
|
-
summarize: z.string().optional(),
|
|
340
|
-
releaseNotes: z.string().optional()
|
|
341
|
-
});
|
|
342
|
-
var LLMPromptsConfigSchema = z.object({
|
|
343
|
-
instructions: LLMPromptOverridesSchema.optional(),
|
|
344
|
-
templates: LLMPromptOverridesSchema.optional()
|
|
345
|
-
});
|
|
346
|
-
var LLMConfigSchema = z.object({
|
|
347
|
-
provider: z.string(),
|
|
348
|
-
model: z.string(),
|
|
349
|
-
baseURL: z.string().optional(),
|
|
350
|
-
apiKey: z.string().optional(),
|
|
351
|
-
options: LLMOptionsSchema.optional(),
|
|
352
|
-
concurrency: z.number().int().positive().optional(),
|
|
353
|
-
retry: LLMRetryConfigSchema.optional(),
|
|
354
|
-
tasks: LLMTasksConfigSchema.optional(),
|
|
355
|
-
categories: z.array(LLMCategorySchema).optional(),
|
|
356
|
-
style: z.string().optional(),
|
|
357
|
-
scopes: ScopeConfigSchema.optional(),
|
|
358
|
-
prompts: LLMPromptsConfigSchema.optional()
|
|
359
|
-
});
|
|
360
|
-
var ReleaseNotesConfigSchema = z.object({
|
|
361
|
-
mode: LocationModeSchema.optional(),
|
|
362
|
-
file: z.string().optional(),
|
|
363
|
-
templates: TemplateConfigSchema.optional(),
|
|
364
|
-
llm: LLMConfigSchema.optional()
|
|
365
|
-
});
|
|
366
|
-
var NotesInputConfigSchema = z.object({
|
|
367
|
-
source: z.string().optional(),
|
|
368
|
-
file: z.string().optional()
|
|
369
|
-
});
|
|
370
|
-
var NotesConfigSchema = z.object({
|
|
371
|
-
changelog: z.union([z.literal(false), ChangelogConfigSchema]).optional(),
|
|
372
|
-
releaseNotes: z.union([z.literal(false), ReleaseNotesConfigSchema]).optional(),
|
|
373
|
-
updateStrategy: z.enum(["prepend", "regenerate"]).optional()
|
|
374
|
-
});
|
|
375
|
-
var CILabelsConfigSchema = z.object({
|
|
376
|
-
stable: z.string().default("release:stable"),
|
|
377
|
-
prerelease: z.string().default("release:prerelease"),
|
|
378
|
-
skip: z.string().default("release:skip"),
|
|
379
|
-
major: z.string().default("release:major"),
|
|
380
|
-
minor: z.string().default("release:minor"),
|
|
381
|
-
patch: z.string().default("release:patch")
|
|
382
|
-
});
|
|
383
|
-
var CIConfigSchema = z.object({
|
|
384
|
-
releaseStrategy: z.enum(["manual", "direct", "standing-pr", "scheduled"]).default("direct"),
|
|
385
|
-
releaseTrigger: z.enum(["commit", "label"]).default("label"),
|
|
386
|
-
prPreview: z.boolean().default(true),
|
|
387
|
-
autoRelease: z.boolean().default(false),
|
|
388
|
-
/**
|
|
389
|
-
* Commit message prefixes that should not trigger a release.
|
|
390
|
-
* Defaults to `['chore: release ']` to match the release commit template
|
|
391
|
-
* (`chore: release ${packageName} v${version}`) and provide a
|
|
392
|
-
* secondary loop-prevention guard alongside `[skip ci]`.
|
|
393
|
-
*/
|
|
394
|
-
skipPatterns: z.array(z.string()).default(["chore: release "]),
|
|
395
|
-
minChanges: z.number().int().positive().default(1),
|
|
396
|
-
labels: CILabelsConfigSchema.default({
|
|
397
|
-
stable: "release:stable",
|
|
398
|
-
prerelease: "release:prerelease",
|
|
399
|
-
skip: "release:skip",
|
|
400
|
-
major: "release:major",
|
|
401
|
-
minor: "release:minor",
|
|
402
|
-
patch: "release:patch"
|
|
403
|
-
})
|
|
404
|
-
});
|
|
405
|
-
var ReleaseCIConfigSchema = z.object({
|
|
406
|
-
skipPatterns: z.array(z.string().min(1)).optional(),
|
|
407
|
-
minChanges: z.number().int().positive().optional(),
|
|
408
|
-
/** Set to `false` to disable GitHub release creation in CI. */
|
|
409
|
-
githubRelease: z.literal(false).optional(),
|
|
410
|
-
/** Set to `false` to disable changelog generation in CI. */
|
|
411
|
-
notes: z.literal(false).optional()
|
|
412
|
-
});
|
|
413
|
-
var ReleaseConfigSchema = z.object({
|
|
414
|
-
/**
|
|
415
|
-
* Optional steps to enable. The version step always runs; only 'notes' and
|
|
416
|
-
* 'publish' can be opted out. Omitting a step is equivalent to --skip-<step>.
|
|
417
|
-
*/
|
|
418
|
-
steps: z.array(z.enum(["notes", "publish"])).min(1).optional(),
|
|
419
|
-
ci: ReleaseCIConfigSchema.optional()
|
|
420
|
-
});
|
|
421
|
-
var ReleaseKitConfigSchema = z.object({
|
|
422
|
-
git: GitConfigSchema.optional(),
|
|
423
|
-
monorepo: MonorepoConfigSchema.optional(),
|
|
424
|
-
version: VersionConfigSchema.optional(),
|
|
425
|
-
publish: PublishConfigSchema.optional(),
|
|
426
|
-
notes: NotesConfigSchema.optional(),
|
|
427
|
-
ci: CIConfigSchema.optional(),
|
|
428
|
-
release: ReleaseConfigSchema.optional()
|
|
429
|
-
});
|
|
430
|
-
var MAX_INPUT_LENGTH = 1e4;
|
|
431
|
-
function substituteVariables(value) {
|
|
432
|
-
if (value.length > MAX_INPUT_LENGTH) {
|
|
433
|
-
throw new Error(`Input too long: ${value.length} characters (max ${MAX_INPUT_LENGTH})`);
|
|
434
|
-
}
|
|
435
|
-
const envPattern = /\{env:([^}]{1,1000})\}/g;
|
|
436
|
-
const filePattern = /\{file:([^}]{1,1000})\}/g;
|
|
437
|
-
let result = value;
|
|
438
|
-
result = result.replace(envPattern, (_, varName) => {
|
|
439
|
-
return process.env[varName] ?? "";
|
|
440
|
-
});
|
|
441
|
-
result = result.replace(filePattern, (_, filePath) => {
|
|
442
|
-
const expandedPath = filePath.startsWith("~") ? path2.join(os.homedir(), filePath.slice(1)) : filePath;
|
|
443
|
-
try {
|
|
444
|
-
return fs2.readFileSync(expandedPath, "utf-8").trim();
|
|
445
|
-
} catch {
|
|
446
|
-
return "";
|
|
447
|
-
}
|
|
448
|
-
});
|
|
449
|
-
return result;
|
|
450
|
-
}
|
|
451
|
-
var SOLE_REFERENCE_PATTERN = /^\{(?:env|file):[^}]+\}$/;
|
|
452
|
-
function substituteInObject(obj) {
|
|
453
|
-
if (typeof obj === "string") {
|
|
454
|
-
const result = substituteVariables(obj);
|
|
455
|
-
if (result === "" && SOLE_REFERENCE_PATTERN.test(obj)) {
|
|
456
|
-
return void 0;
|
|
457
|
-
}
|
|
458
|
-
return result;
|
|
459
|
-
}
|
|
460
|
-
if (Array.isArray(obj)) {
|
|
461
|
-
return obj.map((item) => substituteInObject(item));
|
|
462
|
-
}
|
|
463
|
-
if (obj && typeof obj === "object") {
|
|
464
|
-
const result = {};
|
|
465
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
466
|
-
result[key] = substituteInObject(value);
|
|
467
|
-
}
|
|
468
|
-
return result;
|
|
469
|
-
}
|
|
470
|
-
return obj;
|
|
471
|
-
}
|
|
472
|
-
var AUTH_DIR = path2.join(os.homedir(), ".config", "releasekit");
|
|
473
|
-
var AUTH_FILE = path2.join(AUTH_DIR, "auth.json");
|
|
474
|
-
var CONFIG_FILE = "releasekit.config.json";
|
|
475
|
-
function loadConfigFile(configPath) {
|
|
476
|
-
if (!fs3.existsSync(configPath)) {
|
|
477
|
-
return {};
|
|
478
|
-
}
|
|
479
|
-
try {
|
|
480
|
-
const content = fs3.readFileSync(configPath, "utf-8");
|
|
481
|
-
const parsed = parseJsonc(content);
|
|
482
|
-
const substituted = substituteInObject(parsed);
|
|
483
|
-
return ReleaseKitConfigSchema.parse(substituted);
|
|
484
|
-
} catch (error2) {
|
|
485
|
-
if (error2 instanceof z2.ZodError) {
|
|
486
|
-
const issues = error2.issues.map((i) => ` ${i.path.join(".")}: ${i.message}`).join("\n");
|
|
487
|
-
throw new ConfigError(`Config validation errors:
|
|
488
|
-
${issues}`);
|
|
489
|
-
}
|
|
490
|
-
if (error2 instanceof SyntaxError) {
|
|
491
|
-
throw new ConfigError(`Invalid JSON in config file: ${error2.message}`);
|
|
492
|
-
}
|
|
493
|
-
throw error2;
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
function loadConfig(options) {
|
|
497
|
-
const cwd = options?.cwd ?? process.cwd();
|
|
498
|
-
const configPath = options?.configPath ?? path3.join(cwd, CONFIG_FILE);
|
|
499
|
-
return loadConfigFile(configPath);
|
|
500
|
-
}
|
|
501
|
-
function loadCIConfig(options) {
|
|
502
|
-
const config = loadConfig(options);
|
|
503
|
-
return config.ci;
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
// src/release.ts
|
|
507
|
-
function getHeadCommitMessage(cwd) {
|
|
508
|
-
try {
|
|
509
|
-
return execSync("git log -1 --pretty=%s", { encoding: "utf-8", cwd }).trim();
|
|
510
|
-
} catch {
|
|
511
|
-
return null;
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
async function runRelease(inputOptions) {
|
|
515
|
-
const options = { ...inputOptions };
|
|
516
|
-
if (options.verbose) setLogLevel("debug");
|
|
517
|
-
if (options.quiet) setQuietMode(true);
|
|
518
|
-
if (options.json) setJsonMode(true);
|
|
519
|
-
let releaseKitConfig;
|
|
520
|
-
try {
|
|
521
|
-
releaseKitConfig = loadConfig({ cwd: options.projectDir, configPath: options.config });
|
|
522
|
-
} catch (err) {
|
|
523
|
-
error(`Failed to load release config: ${err instanceof Error ? err.message : String(err)}`);
|
|
524
|
-
throw err;
|
|
525
|
-
}
|
|
526
|
-
const releaseConfig = releaseKitConfig.release;
|
|
527
|
-
if (releaseConfig?.ci?.skipPatterns?.length) {
|
|
528
|
-
const headCommit = getHeadCommitMessage(options.projectDir);
|
|
529
|
-
if (headCommit) {
|
|
530
|
-
const matchedPattern = releaseConfig.ci.skipPatterns.find((p) => headCommit.startsWith(p));
|
|
531
|
-
if (matchedPattern) {
|
|
532
|
-
info(`Skipping release: commit message matches skip pattern "${matchedPattern}"`);
|
|
533
|
-
return null;
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
if (releaseConfig?.steps) {
|
|
538
|
-
if (!releaseConfig.steps.includes("notes") && !options.skipNotes) {
|
|
539
|
-
options.skipNotes = true;
|
|
540
|
-
}
|
|
541
|
-
if (!releaseConfig.steps.includes("publish") && !options.skipPublish) {
|
|
542
|
-
options.skipPublish = true;
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
if (releaseConfig?.ci?.notes === false && !options.skipNotes) {
|
|
546
|
-
options.skipNotes = true;
|
|
547
|
-
}
|
|
548
|
-
if (releaseConfig?.ci?.githubRelease === false && !options.skipGithubRelease) {
|
|
549
|
-
options.skipGithubRelease = true;
|
|
550
|
-
}
|
|
551
|
-
info("Running version analysis...");
|
|
552
|
-
const versionOutput = await runVersionStep({ ...options, dryRun: true });
|
|
553
|
-
versionOutput.dryRun = options.dryRun ?? false;
|
|
554
|
-
if (versionOutput.updates.length === 0) {
|
|
555
|
-
info("No releasable changes found");
|
|
556
|
-
return null;
|
|
557
|
-
}
|
|
558
|
-
if (releaseConfig?.ci?.minChanges !== void 0 && versionOutput.updates.length < releaseConfig.ci.minChanges) {
|
|
559
|
-
info(
|
|
560
|
-
`Skipping release: ${versionOutput.updates.length} package(s) to update, minimum is ${releaseConfig.ci.minChanges}`
|
|
561
|
-
);
|
|
562
|
-
return null;
|
|
563
|
-
}
|
|
564
|
-
if (!options.dryRun) {
|
|
565
|
-
const { flushPendingWrites } = await import("./dist-7RSHM4ZO.js");
|
|
566
|
-
flushPendingWrites();
|
|
567
|
-
}
|
|
568
|
-
info(`Found ${versionOutput.updates.length} package update(s)`);
|
|
569
|
-
for (const update of versionOutput.updates) {
|
|
570
|
-
info(` ${update.packageName} \u2192 ${update.newVersion}`);
|
|
571
|
-
}
|
|
572
|
-
let notesGenerated = false;
|
|
573
|
-
let packageNotes;
|
|
574
|
-
let releaseNotes;
|
|
575
|
-
let notesFiles = [];
|
|
576
|
-
if (!options.skipNotes) {
|
|
577
|
-
info("Generating release notes...");
|
|
578
|
-
const notesResult = await runNotesStep(versionOutput, options);
|
|
579
|
-
packageNotes = notesResult.packageNotes;
|
|
580
|
-
releaseNotes = notesResult.releaseNotes;
|
|
581
|
-
notesFiles = notesResult.files;
|
|
582
|
-
notesGenerated = true;
|
|
583
|
-
success("Release notes generated");
|
|
584
|
-
}
|
|
585
|
-
let publishOutput;
|
|
586
|
-
if (!options.skipPublish) {
|
|
587
|
-
info("Publishing...");
|
|
588
|
-
publishOutput = await runPublishStep(versionOutput, options, releaseNotes, notesFiles);
|
|
589
|
-
success("Publish complete");
|
|
590
|
-
}
|
|
591
|
-
return { versionOutput, notesGenerated, packageNotes, releaseNotes, publishOutput };
|
|
592
|
-
}
|
|
593
|
-
async function runVersionStep(options) {
|
|
594
|
-
const { loadConfig: loadConfig2, VersionEngine, enableJsonOutput, getJsonData } = await import("./dist-7RSHM4ZO.js");
|
|
595
|
-
enableJsonOutput(options.dryRun);
|
|
596
|
-
const config = loadConfig2({ cwd: options.projectDir, configPath: options.config });
|
|
597
|
-
if (options.dryRun) config.dryRun = true;
|
|
598
|
-
if (options.sync) config.sync = true;
|
|
599
|
-
if (options.bump) config.type = options.bump;
|
|
600
|
-
if (options.prerelease) {
|
|
601
|
-
config.prereleaseIdentifier = options.prerelease === true ? "next" : options.prerelease;
|
|
602
|
-
config.isPrerelease = true;
|
|
603
|
-
}
|
|
604
|
-
const cliTargets = options.target ? options.target.split(",").map((t) => t.trim()) : [];
|
|
605
|
-
if (cliTargets.length > 0) {
|
|
606
|
-
config.packages = cliTargets;
|
|
607
|
-
}
|
|
608
|
-
const engine = new VersionEngine(config);
|
|
609
|
-
const pkgsResult = await engine.getWorkspacePackages();
|
|
610
|
-
const resolvedCount = pkgsResult.packages.length;
|
|
611
|
-
if (resolvedCount === 0) {
|
|
612
|
-
throw new Error("No packages found in workspace");
|
|
613
|
-
}
|
|
614
|
-
if (config.sync) {
|
|
615
|
-
engine.setStrategy("sync");
|
|
616
|
-
await engine.run(pkgsResult);
|
|
617
|
-
} else if (resolvedCount === 1) {
|
|
618
|
-
engine.setStrategy("single");
|
|
619
|
-
await engine.run(pkgsResult);
|
|
620
|
-
} else {
|
|
621
|
-
engine.setStrategy("async");
|
|
622
|
-
await engine.run(pkgsResult, cliTargets);
|
|
623
|
-
}
|
|
624
|
-
return getJsonData();
|
|
625
|
-
}
|
|
626
|
-
async function runNotesStep(versionOutput, options) {
|
|
627
|
-
const { parseVersionOutput, runPipeline, loadConfig: loadConfig2 } = await import("./dist-HVRDLODI.js");
|
|
628
|
-
const config = loadConfig2(options.projectDir, options.config);
|
|
629
|
-
const input = parseVersionOutput(JSON.stringify(versionOutput));
|
|
630
|
-
const result = await runPipeline(input, config, options.dryRun);
|
|
631
|
-
return { packageNotes: result.packageNotes, releaseNotes: result.releaseNotes, files: result.files };
|
|
632
|
-
}
|
|
633
|
-
async function runPublishStep(versionOutput, options, releaseNotes, additionalFiles) {
|
|
634
|
-
const { runPipeline, loadConfig: loadConfig2 } = await import("./dist-4RETAAT2.js");
|
|
635
|
-
const config = loadConfig2({ configPath: options.config });
|
|
636
|
-
if (options.branch) {
|
|
637
|
-
config.git.branch = options.branch;
|
|
638
|
-
}
|
|
639
|
-
const publishOptions = {
|
|
640
|
-
dryRun: options.dryRun,
|
|
641
|
-
registry: "all",
|
|
642
|
-
npmAuth: options.npmAuth ?? "auto",
|
|
643
|
-
skipGit: options.skipGit,
|
|
644
|
-
skipPublish: false,
|
|
645
|
-
skipGithubRelease: options.skipGithubRelease,
|
|
646
|
-
skipVerification: options.skipVerification,
|
|
647
|
-
json: options.json,
|
|
648
|
-
verbose: options.verbose,
|
|
649
|
-
releaseNotes,
|
|
650
|
-
additionalFiles
|
|
651
|
-
};
|
|
652
|
-
return runPipeline(versionOutput, config, publishOptions);
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
// src/preview.ts
|
|
656
|
-
init_esm_shims();
|
|
657
|
-
|
|
658
|
-
// src/preview-context.ts
|
|
659
|
-
init_esm_shims();
|
|
660
|
-
import * as fs4 from "fs";
|
|
661
|
-
function resolvePreviewContext(opts) {
|
|
662
|
-
const token = process.env.GITHUB_TOKEN;
|
|
663
|
-
if (!token) {
|
|
664
|
-
throw new Error("GITHUB_TOKEN environment variable is required");
|
|
665
|
-
}
|
|
666
|
-
const prNumber = resolvePRNumber(opts.pr);
|
|
667
|
-
const { owner, repo } = resolveRepo(opts.repo);
|
|
668
|
-
return { prNumber, owner, repo, token };
|
|
669
|
-
}
|
|
670
|
-
function resolvePRNumber(cliValue) {
|
|
671
|
-
if (cliValue) {
|
|
672
|
-
const num = Number.parseInt(cliValue, 10);
|
|
673
|
-
if (Number.isNaN(num) || num <= 0) {
|
|
674
|
-
throw new Error(`Invalid PR number: ${cliValue}`);
|
|
675
|
-
}
|
|
676
|
-
return num;
|
|
677
|
-
}
|
|
678
|
-
const eventPath = process.env.GITHUB_EVENT_PATH;
|
|
679
|
-
if (eventPath && fs4.existsSync(eventPath)) {
|
|
680
|
-
try {
|
|
681
|
-
const event = JSON.parse(fs4.readFileSync(eventPath, "utf-8"));
|
|
682
|
-
if (event.pull_request?.number) {
|
|
683
|
-
return event.pull_request.number;
|
|
684
|
-
}
|
|
685
|
-
} catch {
|
|
686
|
-
}
|
|
687
|
-
}
|
|
688
|
-
throw new Error("Could not determine PR number. Use --pr <number> or run in a GitHub Actions pull_request workflow.");
|
|
689
|
-
}
|
|
690
|
-
function resolveRepo(cliValue) {
|
|
691
|
-
const repoStr = cliValue ?? process.env.GITHUB_REPOSITORY;
|
|
692
|
-
if (!repoStr) {
|
|
693
|
-
throw new Error("Could not determine repository. Use --repo <owner/repo> or run in a GitHub Actions workflow.");
|
|
694
|
-
}
|
|
695
|
-
const parts = repoStr.split("/");
|
|
696
|
-
if (parts.length !== 2 || !parts[0] || !parts[1]) {
|
|
697
|
-
throw new Error(`Invalid repository format: ${repoStr}. Expected "owner/repo".`);
|
|
698
|
-
}
|
|
699
|
-
return { owner: parts[0], repo: parts[1] };
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
// src/preview-detect.ts
|
|
703
|
-
init_esm_shims();
|
|
704
|
-
import * as fs5 from "fs";
|
|
705
|
-
import * as path4 from "path";
|
|
706
|
-
function detectPrerelease(packagePaths, projectDir) {
|
|
707
|
-
const paths = packagePaths.length > 0 ? packagePaths.map((p) => path4.join(projectDir, p, "package.json")) : [path4.join(projectDir, "package.json")];
|
|
708
|
-
for (const pkgPath of paths) {
|
|
709
|
-
if (!fs5.existsSync(pkgPath)) continue;
|
|
710
|
-
try {
|
|
711
|
-
const pkg = JSON.parse(fs5.readFileSync(pkgPath, "utf-8"));
|
|
712
|
-
const result = parsePrerelease(pkg.version);
|
|
713
|
-
if (result.isPrerelease) return result;
|
|
714
|
-
} catch {
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
return { isPrerelease: false };
|
|
718
|
-
}
|
|
719
|
-
function parsePrerelease(version) {
|
|
720
|
-
if (!version) return { isPrerelease: false };
|
|
721
|
-
const match = version.match(/-([a-zA-Z0-9][a-zA-Z0-9-]*)(?:\.\d+)*(?:\+[^\s]+)?$/);
|
|
722
|
-
if (match) {
|
|
723
|
-
return { isPrerelease: true, identifier: match[1] };
|
|
724
|
-
}
|
|
725
|
-
return { isPrerelease: false };
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
// src/preview-format.ts
|
|
729
|
-
init_esm_shims();
|
|
730
|
-
var MARKER = "<!-- releasekit-preview -->";
|
|
731
|
-
var FOOTER = "*Updated automatically by [ReleaseKit](https://github.com/goosewobbler/releasekit)*";
|
|
732
|
-
var TYPE_LABELS = {
|
|
733
|
-
added: "Added",
|
|
734
|
-
changed: "Changed",
|
|
735
|
-
fixed: "Fixed",
|
|
736
|
-
security: "Security",
|
|
737
|
-
docs: "Documentation",
|
|
738
|
-
chore: "Chores",
|
|
739
|
-
test: "Tests",
|
|
740
|
-
feat: "Features",
|
|
741
|
-
fix: "Bug Fixes",
|
|
742
|
-
perf: "Performance",
|
|
743
|
-
refactor: "Refactoring",
|
|
744
|
-
style: "Styles",
|
|
745
|
-
build: "Build",
|
|
746
|
-
ci: "CI",
|
|
747
|
-
revert: "Reverts"
|
|
748
|
-
};
|
|
749
|
-
function getNoChangesMessage(strategy) {
|
|
750
|
-
switch (strategy) {
|
|
751
|
-
case "manual":
|
|
752
|
-
return "Run the release workflow manually if a release is needed.";
|
|
753
|
-
case "direct":
|
|
754
|
-
return "Merging this PR will not trigger a release.";
|
|
755
|
-
case "standing-pr":
|
|
756
|
-
return "Merging this PR will not affect the release PR.";
|
|
757
|
-
case "scheduled":
|
|
758
|
-
return "These changes will not be included in the next scheduled release.";
|
|
759
|
-
default:
|
|
760
|
-
return "";
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
function getIntroMessage(strategy, standingPrNumber) {
|
|
764
|
-
switch (strategy) {
|
|
765
|
-
case "direct":
|
|
766
|
-
return "This PR will trigger the following release when merged:";
|
|
767
|
-
case "standing-pr":
|
|
768
|
-
return standingPrNumber ? `These changes will be added to the release PR (#${standingPrNumber}) when merged:` : "Merging this PR will create a new release PR with the following changes:";
|
|
769
|
-
case "scheduled":
|
|
770
|
-
return "These changes will be included in the next scheduled release:";
|
|
771
|
-
default:
|
|
772
|
-
return "If released, this PR would include:";
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
function getLabelBanner(labelContext) {
|
|
776
|
-
if (!labelContext) return [];
|
|
777
|
-
if (labelContext.trigger === "commit") {
|
|
778
|
-
if (labelContext.skip) {
|
|
779
|
-
return ["> **Warning:** This PR is marked to skip release.", ""];
|
|
780
|
-
}
|
|
781
|
-
if (labelContext.bumpLabel === "major") {
|
|
782
|
-
return ["> **Important:** This PR is labeled for a **major** release.", ""];
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
if (labelContext.trigger === "label") {
|
|
786
|
-
if (labelContext.noBumpLabel) {
|
|
787
|
-
const labels = labelContext.labels;
|
|
788
|
-
const labelExamples = labels ? `\`${labels.patch}\`, \`${labels.minor}\`, or \`${labels.major}\`` : "a release label (e.g., `release:patch`, `release:minor`, `release:major`)";
|
|
789
|
-
return ["> No release label detected.", `> **Note:** Add ${labelExamples} to trigger a release.`, ""];
|
|
790
|
-
}
|
|
791
|
-
if (labelContext.bumpLabel) {
|
|
792
|
-
return [`> This PR is labeled for a **${labelContext.bumpLabel}** release.`, ""];
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
return [];
|
|
796
|
-
}
|
|
797
|
-
function formatPreviewComment(result, options) {
|
|
798
|
-
const strategy = options?.strategy ?? "direct";
|
|
799
|
-
const labelContext = options?.labelContext;
|
|
800
|
-
const lines = [MARKER, ""];
|
|
801
|
-
const banner = getLabelBanner(labelContext);
|
|
802
|
-
if (!result) {
|
|
803
|
-
lines.push("<details>", "<summary><b>Release Preview</b> \u2014 no release</summary>", "");
|
|
804
|
-
lines.push(...banner);
|
|
805
|
-
if (!labelContext?.noBumpLabel) {
|
|
806
|
-
lines.push(`> **Note:** No releasable changes detected. ${getNoChangesMessage(strategy)}`);
|
|
807
|
-
}
|
|
808
|
-
lines.push("", "---", FOOTER, "</details>");
|
|
809
|
-
return lines.join("\n");
|
|
810
|
-
}
|
|
811
|
-
const { versionOutput } = result;
|
|
812
|
-
const pkgCount = versionOutput.updates.length;
|
|
813
|
-
const pkgSummary = pkgCount === 1 ? `${versionOutput.updates[0]?.packageName} ${versionOutput.updates[0]?.newVersion}` : `${pkgCount} packages`;
|
|
814
|
-
lines.push("<details>", `<summary><b>Release Preview</b> \u2014 ${pkgSummary}</summary>`, "");
|
|
815
|
-
lines.push(...banner);
|
|
816
|
-
lines.push(getIntroMessage(strategy, options?.standingPrNumber), "");
|
|
817
|
-
lines.push("### Packages", "");
|
|
818
|
-
lines.push("| Package | Version |", "|---------|---------|");
|
|
819
|
-
for (const update of versionOutput.updates) {
|
|
820
|
-
lines.push(`| \`${update.packageName}\` | ${update.newVersion} |`);
|
|
821
|
-
}
|
|
822
|
-
lines.push("");
|
|
823
|
-
const sharedEntries = versionOutput.sharedEntries?.length ? versionOutput.sharedEntries : void 0;
|
|
824
|
-
const hasPackageChangelogs = versionOutput.changelogs.some((cl) => cl.entries.length > 0);
|
|
825
|
-
if (sharedEntries || hasPackageChangelogs) {
|
|
826
|
-
lines.push("### Changelog", "");
|
|
827
|
-
if (sharedEntries) {
|
|
828
|
-
lines.push("<details>", "<summary><b>Project-wide changes</b></summary>", "");
|
|
829
|
-
lines.push(...renderEntries(sharedEntries));
|
|
830
|
-
lines.push("</details>", "");
|
|
831
|
-
}
|
|
832
|
-
for (const changelog of versionOutput.changelogs) {
|
|
833
|
-
if (changelog.entries.length > 0) {
|
|
834
|
-
lines.push(...formatPackageChangelog(changelog));
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
if (versionOutput.tags.length > 0) {
|
|
839
|
-
lines.push("### Tags", "");
|
|
840
|
-
for (const tag of versionOutput.tags) {
|
|
841
|
-
lines.push(`- \`${tag}\``);
|
|
842
|
-
}
|
|
843
|
-
lines.push("");
|
|
844
|
-
}
|
|
845
|
-
lines.push("---", FOOTER, "</details>");
|
|
846
|
-
return lines.join("\n");
|
|
847
|
-
}
|
|
848
|
-
function renderEntries(entries) {
|
|
849
|
-
const lines = [];
|
|
850
|
-
const grouped = /* @__PURE__ */ new Map();
|
|
851
|
-
for (const entry of entries) {
|
|
852
|
-
if (!grouped.has(entry.type)) grouped.set(entry.type, []);
|
|
853
|
-
grouped.get(entry.type)?.push(entry);
|
|
854
|
-
}
|
|
855
|
-
const renderedTypes = /* @__PURE__ */ new Set();
|
|
856
|
-
for (const type of Object.keys(TYPE_LABELS)) {
|
|
857
|
-
const group = grouped.get(type);
|
|
858
|
-
if (group && group.length > 0) {
|
|
859
|
-
lines.push(...formatEntryGroup(type, group));
|
|
860
|
-
renderedTypes.add(type);
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
for (const [type, group] of grouped) {
|
|
864
|
-
if (!renderedTypes.has(type) && group.length > 0) {
|
|
865
|
-
lines.push(...formatEntryGroup(type, group));
|
|
866
|
-
}
|
|
867
|
-
}
|
|
868
|
-
return lines;
|
|
869
|
-
}
|
|
870
|
-
function formatPackageChangelog(changelog) {
|
|
871
|
-
const lines = [];
|
|
872
|
-
const prevVersion = changelog.previousVersion ?? "N/A";
|
|
873
|
-
const summary = `<b>${changelog.packageName}</b> ${prevVersion} \u2192 ${changelog.version}`;
|
|
874
|
-
lines.push("<details>", `<summary>${summary}</summary>`, "");
|
|
875
|
-
lines.push(...renderEntries(changelog.entries));
|
|
876
|
-
lines.push("</details>", "");
|
|
877
|
-
return lines;
|
|
878
|
-
}
|
|
879
|
-
function formatEntryGroup(type, entries) {
|
|
880
|
-
const label = TYPE_LABELS[type] ?? capitalize(type);
|
|
881
|
-
const lines = [`#### ${label}`, ""];
|
|
882
|
-
for (const entry of entries) {
|
|
883
|
-
let line = `- ${entry.description}`;
|
|
884
|
-
if (entry.scope) {
|
|
885
|
-
line += ` (\`${entry.scope}\`)`;
|
|
886
|
-
}
|
|
887
|
-
if (entry.issueIds && entry.issueIds.length > 0) {
|
|
888
|
-
line += ` ${entry.issueIds.join(", ")}`;
|
|
889
|
-
}
|
|
890
|
-
lines.push(line);
|
|
891
|
-
}
|
|
892
|
-
lines.push("");
|
|
893
|
-
return lines;
|
|
894
|
-
}
|
|
895
|
-
function capitalize(str) {
|
|
896
|
-
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
897
|
-
}
|
|
898
|
-
|
|
899
|
-
// src/preview-github.ts
|
|
900
|
-
init_esm_shims();
|
|
901
|
-
import { Octokit } from "@octokit/rest";
|
|
902
|
-
function createOctokit(token) {
|
|
903
|
-
return new Octokit({ auth: token });
|
|
904
|
-
}
|
|
905
|
-
async function findPreviewComment(octokit, owner, repo, prNumber) {
|
|
906
|
-
const iterator = octokit.paginate.iterator(octokit.rest.issues.listComments, {
|
|
907
|
-
owner,
|
|
908
|
-
repo,
|
|
909
|
-
issue_number: prNumber,
|
|
910
|
-
per_page: 100
|
|
911
|
-
});
|
|
912
|
-
for await (const response of iterator) {
|
|
913
|
-
for (const comment of response.data) {
|
|
914
|
-
if (comment.body?.startsWith(MARKER)) {
|
|
915
|
-
return comment.id;
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
return null;
|
|
920
|
-
}
|
|
921
|
-
async function fetchPRLabels(octokit, owner, repo, prNumber) {
|
|
922
|
-
const { data } = await octokit.rest.issues.get({
|
|
923
|
-
owner,
|
|
924
|
-
repo,
|
|
925
|
-
issue_number: prNumber
|
|
926
|
-
});
|
|
927
|
-
return (data.labels ?? []).map((label) => typeof label === "string" ? label : label.name ?? "");
|
|
928
|
-
}
|
|
929
|
-
async function postOrUpdateComment(octokit, owner, repo, prNumber, body) {
|
|
930
|
-
const existingId = await findPreviewComment(octokit, owner, repo, prNumber);
|
|
931
|
-
if (existingId) {
|
|
932
|
-
await octokit.rest.issues.updateComment({
|
|
933
|
-
owner,
|
|
934
|
-
repo,
|
|
935
|
-
comment_id: existingId,
|
|
936
|
-
body
|
|
937
|
-
});
|
|
938
|
-
} else {
|
|
939
|
-
await octokit.rest.issues.createComment({
|
|
940
|
-
owner,
|
|
941
|
-
repo,
|
|
942
|
-
issue_number: prNumber,
|
|
943
|
-
body
|
|
944
|
-
});
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
|
-
|
|
948
|
-
// src/preview.ts
|
|
949
|
-
var DEFAULT_LABELS = {
|
|
950
|
-
stable: "release:stable",
|
|
951
|
-
prerelease: "release:prerelease",
|
|
952
|
-
skip: "release:skip",
|
|
953
|
-
major: "release:major",
|
|
954
|
-
minor: "release:minor",
|
|
955
|
-
patch: "release:patch"
|
|
956
|
-
};
|
|
957
|
-
async function runPreview(options) {
|
|
958
|
-
const ciConfig = loadCIConfig({ cwd: options.projectDir, configPath: options.config });
|
|
959
|
-
if (ciConfig?.prPreview === false) {
|
|
960
|
-
info("PR preview is disabled in config (ci.prPreview: false)");
|
|
961
|
-
return;
|
|
962
|
-
}
|
|
963
|
-
let context;
|
|
964
|
-
let octokit;
|
|
965
|
-
if (!options.dryRun) {
|
|
966
|
-
try {
|
|
967
|
-
context = resolvePreviewContext({ pr: options.pr, repo: options.repo });
|
|
968
|
-
octokit = createOctokit(context.token);
|
|
969
|
-
} catch (error2) {
|
|
970
|
-
warn(`Cannot post PR comment: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
const { options: effectiveOptions, labelContext } = await applyLabelOverrides(options, ciConfig, context, octokit);
|
|
974
|
-
const strategy = ciConfig?.releaseStrategy ?? "direct";
|
|
975
|
-
let result = null;
|
|
976
|
-
if (!labelContext.noBumpLabel) {
|
|
977
|
-
const releaseConfig = loadConfig({ cwd: effectiveOptions.projectDir, configPath: effectiveOptions.config });
|
|
978
|
-
const prereleaseFlag = resolvePrerelease(
|
|
979
|
-
effectiveOptions,
|
|
980
|
-
releaseConfig.version?.packages ?? [],
|
|
981
|
-
effectiveOptions.projectDir
|
|
982
|
-
);
|
|
983
|
-
info("Analyzing release...");
|
|
984
|
-
result = await runRelease({
|
|
985
|
-
config: effectiveOptions.config,
|
|
986
|
-
dryRun: true,
|
|
987
|
-
sync: false,
|
|
988
|
-
bump: effectiveOptions.bump,
|
|
989
|
-
prerelease: prereleaseFlag,
|
|
990
|
-
skipNotes: true,
|
|
991
|
-
skipPublish: true,
|
|
992
|
-
skipGit: true,
|
|
993
|
-
skipGithubRelease: true,
|
|
994
|
-
skipVerification: true,
|
|
995
|
-
json: false,
|
|
996
|
-
verbose: false,
|
|
997
|
-
quiet: true,
|
|
998
|
-
projectDir: effectiveOptions.projectDir
|
|
999
|
-
});
|
|
1000
|
-
} else {
|
|
1001
|
-
info("No release label detected \u2014 skipping version analysis");
|
|
1002
|
-
}
|
|
1003
|
-
const commentBody = formatPreviewComment(result, { strategy, labelContext });
|
|
1004
|
-
if (!context || !octokit) {
|
|
1005
|
-
console.log(commentBody);
|
|
1006
|
-
return;
|
|
1007
|
-
}
|
|
1008
|
-
info(`Posting preview comment on PR #${context.prNumber}...`);
|
|
1009
|
-
await postOrUpdateComment(octokit, context.owner, context.repo, context.prNumber, commentBody);
|
|
1010
|
-
success(`Preview comment posted on PR #${context.prNumber}`);
|
|
1011
|
-
}
|
|
1012
|
-
function resolvePrerelease(options, packagePaths, projectDir) {
|
|
1013
|
-
if (options.stable) {
|
|
1014
|
-
return void 0;
|
|
1015
|
-
}
|
|
1016
|
-
if (options.prerelease !== void 0) {
|
|
1017
|
-
return options.prerelease;
|
|
1018
|
-
}
|
|
1019
|
-
const detected = detectPrerelease(packagePaths, projectDir);
|
|
1020
|
-
if (detected.isPrerelease) {
|
|
1021
|
-
info(`Detected prerelease version (identifier: ${detected.identifier})`);
|
|
1022
|
-
return detected.identifier;
|
|
1023
|
-
}
|
|
1024
|
-
return void 0;
|
|
1025
|
-
}
|
|
1026
|
-
async function applyLabelOverrides(options, ciConfig, context, existingOctokit) {
|
|
1027
|
-
const trigger = ciConfig?.releaseTrigger ?? "label";
|
|
1028
|
-
const labels = ciConfig?.labels ?? DEFAULT_LABELS;
|
|
1029
|
-
const defaultLabelContext = { trigger, skip: false, noBumpLabel: false };
|
|
1030
|
-
if (!context) {
|
|
1031
|
-
return {
|
|
1032
|
-
options,
|
|
1033
|
-
labelContext: { ...defaultLabelContext, noBumpLabel: trigger === "label" && !options.bump, labels }
|
|
1034
|
-
};
|
|
1035
|
-
}
|
|
1036
|
-
let prLabels;
|
|
1037
|
-
const octokitToUse = existingOctokit ?? createOctokit(context.token);
|
|
1038
|
-
try {
|
|
1039
|
-
prLabels = await fetchPRLabels(octokitToUse, context.owner, context.repo, context.prNumber);
|
|
1040
|
-
} catch {
|
|
1041
|
-
warn("Could not fetch PR labels \u2014 skipping label-driven overrides");
|
|
1042
|
-
return {
|
|
1043
|
-
options,
|
|
1044
|
-
labelContext: { ...defaultLabelContext, noBumpLabel: trigger === "label", labels }
|
|
1045
|
-
};
|
|
1046
|
-
}
|
|
1047
|
-
const result = { ...options };
|
|
1048
|
-
const labelContext = { trigger, skip: false, noBumpLabel: false, labels };
|
|
1049
|
-
if (trigger === "commit") {
|
|
1050
|
-
if (prLabels.includes(labels.skip)) {
|
|
1051
|
-
info(`PR label "${labels.skip}" detected \u2014 release will be skipped`);
|
|
1052
|
-
labelContext.skip = true;
|
|
1053
|
-
}
|
|
1054
|
-
if (!labelContext.skip && prLabels.includes(labels.major)) {
|
|
1055
|
-
info(`PR label "${labels.major}" detected \u2014 forcing major release`);
|
|
1056
|
-
labelContext.bumpLabel = "major";
|
|
1057
|
-
result.bump = "major";
|
|
1058
|
-
}
|
|
1059
|
-
} else {
|
|
1060
|
-
if (prLabels.includes(labels.major)) {
|
|
1061
|
-
info(`PR label "${labels.major}" detected \u2014 major release`);
|
|
1062
|
-
labelContext.bumpLabel = "major";
|
|
1063
|
-
result.bump = "major";
|
|
1064
|
-
} else if (prLabels.includes(labels.minor)) {
|
|
1065
|
-
info(`PR label "${labels.minor}" detected \u2014 minor release`);
|
|
1066
|
-
labelContext.bumpLabel = "minor";
|
|
1067
|
-
result.bump = "minor";
|
|
1068
|
-
} else if (prLabels.includes(labels.patch)) {
|
|
1069
|
-
info(`PR label "${labels.patch}" detected \u2014 patch release`);
|
|
1070
|
-
labelContext.bumpLabel = "patch";
|
|
1071
|
-
result.bump = "patch";
|
|
1072
|
-
} else {
|
|
1073
|
-
labelContext.noBumpLabel = true;
|
|
1074
|
-
}
|
|
1075
|
-
}
|
|
1076
|
-
if (!options.stable && options.prerelease === void 0) {
|
|
1077
|
-
if (prLabels.includes(labels.stable)) {
|
|
1078
|
-
info(`PR label "${labels.stable}" detected \u2014 using stable release preview`);
|
|
1079
|
-
result.stable = true;
|
|
1080
|
-
} else if (prLabels.includes(labels.prerelease)) {
|
|
1081
|
-
info(`PR label "${labels.prerelease}" detected \u2014 using prerelease preview`);
|
|
1082
|
-
result.prerelease = true;
|
|
1083
|
-
}
|
|
1084
|
-
}
|
|
1085
|
-
return { options: result, labelContext: { ...labelContext, labels } };
|
|
1086
|
-
}
|
|
1087
|
-
|
|
1088
|
-
export {
|
|
1089
|
-
readPackageVersion,
|
|
1090
|
-
error,
|
|
1091
|
-
info,
|
|
1092
|
-
success,
|
|
1093
|
-
EXIT_CODES,
|
|
1094
|
-
runRelease,
|
|
1095
|
-
runPreview
|
|
1096
|
-
};
|