@releasekit/publish 0.2.0-next.9 → 0.2.1
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/LICENSE +21 -0
- package/README.md +15 -1
- package/dist/{chunk-Y7Y6GQ6R.js → chunk-PJUNQA6B.js} +817 -193
- package/dist/cli.d.ts +9 -0
- package/dist/cli.js +5 -3
- package/dist/index.d.ts +9 -162
- package/dist/index.js +1 -1
- package/package.json +38 -33
- package/dist/cli.cjs +0 -1186
- package/dist/cli.d.cts +0 -1
- package/dist/index.cjs +0 -1197
- package/dist/index.d.cts +0 -162
|
@@ -1,5 +1,456 @@
|
|
|
1
|
-
//
|
|
2
|
-
import
|
|
1
|
+
// ../core/dist/index.js
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
var LOG_LEVELS = {
|
|
4
|
+
error: 0,
|
|
5
|
+
warn: 1,
|
|
6
|
+
info: 2,
|
|
7
|
+
debug: 3,
|
|
8
|
+
trace: 4
|
|
9
|
+
};
|
|
10
|
+
var PREFIXES = {
|
|
11
|
+
error: "[ERROR]",
|
|
12
|
+
warn: "[WARN]",
|
|
13
|
+
info: "[INFO]",
|
|
14
|
+
debug: "[DEBUG]",
|
|
15
|
+
trace: "[TRACE]"
|
|
16
|
+
};
|
|
17
|
+
var COLORS = {
|
|
18
|
+
error: chalk.red,
|
|
19
|
+
warn: chalk.yellow,
|
|
20
|
+
info: chalk.blue,
|
|
21
|
+
debug: chalk.gray,
|
|
22
|
+
trace: chalk.dim
|
|
23
|
+
};
|
|
24
|
+
var currentLevel = "info";
|
|
25
|
+
var quietMode = false;
|
|
26
|
+
function setLogLevel(level) {
|
|
27
|
+
currentLevel = level;
|
|
28
|
+
}
|
|
29
|
+
function setJsonMode(_json) {
|
|
30
|
+
}
|
|
31
|
+
function shouldLog(level) {
|
|
32
|
+
if (quietMode && level !== "error") return false;
|
|
33
|
+
return LOG_LEVELS[level] <= LOG_LEVELS[currentLevel];
|
|
34
|
+
}
|
|
35
|
+
function log(message, level = "info") {
|
|
36
|
+
if (!shouldLog(level)) return;
|
|
37
|
+
const formatted = COLORS[level](`${PREFIXES[level]} ${message}`);
|
|
38
|
+
console.error(formatted);
|
|
39
|
+
}
|
|
40
|
+
function warn(message) {
|
|
41
|
+
log(message, "warn");
|
|
42
|
+
}
|
|
43
|
+
function info(message) {
|
|
44
|
+
log(message, "info");
|
|
45
|
+
}
|
|
46
|
+
function success(message) {
|
|
47
|
+
if (!shouldLog("info")) return;
|
|
48
|
+
console.error(chalk.green(`[SUCCESS] ${message}`));
|
|
49
|
+
}
|
|
50
|
+
function debug(message) {
|
|
51
|
+
log(message, "debug");
|
|
52
|
+
}
|
|
53
|
+
var ReleaseKitError = class _ReleaseKitError extends Error {
|
|
54
|
+
constructor(message) {
|
|
55
|
+
super(message);
|
|
56
|
+
this.name = this.constructor.name;
|
|
57
|
+
}
|
|
58
|
+
logError() {
|
|
59
|
+
log(this.message, "error");
|
|
60
|
+
if (this.suggestions.length > 0) {
|
|
61
|
+
log("\nSuggested solutions:", "info");
|
|
62
|
+
for (const [i, suggestion] of this.suggestions.entries()) {
|
|
63
|
+
log(`${i + 1}. ${suggestion}`, "info");
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
static isReleaseKitError(error2) {
|
|
68
|
+
return error2 instanceof _ReleaseKitError;
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
var EXIT_CODES = {
|
|
72
|
+
SUCCESS: 0,
|
|
73
|
+
GENERAL_ERROR: 1,
|
|
74
|
+
CONFIG_ERROR: 2,
|
|
75
|
+
INPUT_ERROR: 3,
|
|
76
|
+
TEMPLATE_ERROR: 4,
|
|
77
|
+
LLM_ERROR: 5,
|
|
78
|
+
GITHUB_ERROR: 6,
|
|
79
|
+
GIT_ERROR: 7,
|
|
80
|
+
VERSION_ERROR: 8,
|
|
81
|
+
PUBLISH_ERROR: 9
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// ../config/dist/index.js
|
|
85
|
+
import * as fs from "fs";
|
|
86
|
+
import * as path from "path";
|
|
87
|
+
import * as TOML from "smol-toml";
|
|
88
|
+
import * as fs3 from "fs";
|
|
89
|
+
import * as path3 from "path";
|
|
90
|
+
import { z as z2 } from "zod";
|
|
91
|
+
import { z } from "zod";
|
|
92
|
+
import * as fs2 from "fs";
|
|
93
|
+
import * as os from "os";
|
|
94
|
+
import * as path2 from "path";
|
|
95
|
+
function parseCargoToml(cargoPath) {
|
|
96
|
+
const content = fs.readFileSync(cargoPath, "utf-8");
|
|
97
|
+
return TOML.parse(content);
|
|
98
|
+
}
|
|
99
|
+
var ConfigError = class extends ReleaseKitError {
|
|
100
|
+
code = "CONFIG_ERROR";
|
|
101
|
+
suggestions;
|
|
102
|
+
constructor(message, suggestions) {
|
|
103
|
+
super(message);
|
|
104
|
+
this.suggestions = suggestions ?? [
|
|
105
|
+
"Check that releasekit.config.json exists and is valid JSON",
|
|
106
|
+
"Run with --verbose for more details"
|
|
107
|
+
];
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
function mergeGitConfig(topLevel, packageLevel) {
|
|
111
|
+
if (!topLevel && !packageLevel) return void 0;
|
|
112
|
+
const base = topLevel ?? {
|
|
113
|
+
remote: "origin",
|
|
114
|
+
branch: "main",
|
|
115
|
+
pushMethod: "auto"
|
|
116
|
+
};
|
|
117
|
+
if (!packageLevel) return base;
|
|
118
|
+
return {
|
|
119
|
+
remote: packageLevel.remote ?? base.remote,
|
|
120
|
+
branch: packageLevel.branch ?? base.branch,
|
|
121
|
+
pushMethod: packageLevel.pushMethod ?? base.pushMethod,
|
|
122
|
+
httpsTokenEnv: packageLevel.httpsTokenEnv ?? base.httpsTokenEnv,
|
|
123
|
+
push: packageLevel.push,
|
|
124
|
+
skipHooks: packageLevel.skipHooks ?? base.skipHooks
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
var MAX_JSONC_LENGTH = 1e5;
|
|
128
|
+
function parseJsonc(content) {
|
|
129
|
+
if (content.length > MAX_JSONC_LENGTH) {
|
|
130
|
+
throw new Error(`JSONC content too long: ${content.length} characters (max ${MAX_JSONC_LENGTH})`);
|
|
131
|
+
}
|
|
132
|
+
try {
|
|
133
|
+
return JSON.parse(content);
|
|
134
|
+
} catch {
|
|
135
|
+
const cleaned = content.replace(/\/\/[^\r\n]{0,10000}$/gm, "").replace(/\/\*[\s\S]{0,50000}?\*\//g, "").trim();
|
|
136
|
+
return JSON.parse(cleaned);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
var GitConfigSchema = z.object({
|
|
140
|
+
remote: z.string().default("origin"),
|
|
141
|
+
branch: z.string().default("main"),
|
|
142
|
+
pushMethod: z.enum(["auto", "ssh", "https"]).default("auto"),
|
|
143
|
+
/**
|
|
144
|
+
* Optional env var name containing a GitHub token for HTTPS pushes.
|
|
145
|
+
* When set, publish steps can use this token without mutating git remotes.
|
|
146
|
+
*/
|
|
147
|
+
httpsTokenEnv: z.string().optional(),
|
|
148
|
+
push: z.boolean().optional(),
|
|
149
|
+
skipHooks: z.boolean().optional()
|
|
150
|
+
});
|
|
151
|
+
var MonorepoConfigSchema = z.object({
|
|
152
|
+
mode: z.enum(["root", "packages", "both"]).optional(),
|
|
153
|
+
rootPath: z.string().optional(),
|
|
154
|
+
packagesPath: z.string().optional(),
|
|
155
|
+
mainPackage: z.string().optional()
|
|
156
|
+
});
|
|
157
|
+
var BranchPatternSchema = z.object({
|
|
158
|
+
pattern: z.string(),
|
|
159
|
+
releaseType: z.enum(["major", "minor", "patch", "prerelease"])
|
|
160
|
+
});
|
|
161
|
+
var VersionCargoConfigSchema = z.object({
|
|
162
|
+
enabled: z.boolean().default(true),
|
|
163
|
+
paths: z.array(z.string()).optional()
|
|
164
|
+
});
|
|
165
|
+
var VersionConfigSchema = z.object({
|
|
166
|
+
tagTemplate: z.string().default("v{version}"),
|
|
167
|
+
packageSpecificTags: z.boolean().default(false),
|
|
168
|
+
preset: z.string().default("conventional"),
|
|
169
|
+
sync: z.boolean().default(true),
|
|
170
|
+
packages: z.array(z.string()).default([]),
|
|
171
|
+
mainPackage: z.string().optional(),
|
|
172
|
+
updateInternalDependencies: z.enum(["major", "minor", "patch", "no-internal-update"]).default("minor"),
|
|
173
|
+
skip: z.array(z.string()).optional(),
|
|
174
|
+
commitMessage: z.string().optional(),
|
|
175
|
+
versionStrategy: z.enum(["branchPattern", "commitMessage"]).default("commitMessage"),
|
|
176
|
+
branchPatterns: z.array(BranchPatternSchema).optional(),
|
|
177
|
+
defaultReleaseType: z.enum(["major", "minor", "patch", "prerelease"]).optional(),
|
|
178
|
+
mismatchStrategy: z.enum(["error", "warn", "ignore", "prefer-package", "prefer-git"]).default("warn"),
|
|
179
|
+
versionPrefix: z.string().default(""),
|
|
180
|
+
prereleaseIdentifier: z.string().optional(),
|
|
181
|
+
strictReachable: z.boolean().default(false),
|
|
182
|
+
cargo: VersionCargoConfigSchema.optional()
|
|
183
|
+
});
|
|
184
|
+
var NpmConfigSchema = z.object({
|
|
185
|
+
enabled: z.boolean().default(true),
|
|
186
|
+
auth: z.enum(["auto", "oidc", "token"]).default("auto"),
|
|
187
|
+
provenance: z.boolean().default(true),
|
|
188
|
+
access: z.enum(["public", "restricted"]).default("public"),
|
|
189
|
+
registry: z.string().default("https://registry.npmjs.org"),
|
|
190
|
+
copyFiles: z.array(z.string()).default(["LICENSE"]),
|
|
191
|
+
tag: z.string().default("latest")
|
|
192
|
+
});
|
|
193
|
+
var CargoPublishConfigSchema = z.object({
|
|
194
|
+
enabled: z.boolean().default(false),
|
|
195
|
+
noVerify: z.boolean().default(false),
|
|
196
|
+
publishOrder: z.array(z.string()).default([]),
|
|
197
|
+
clean: z.boolean().default(false)
|
|
198
|
+
});
|
|
199
|
+
var PublishGitConfigSchema = z.object({
|
|
200
|
+
push: z.boolean().default(true),
|
|
201
|
+
pushMethod: z.enum(["auto", "ssh", "https"]).optional(),
|
|
202
|
+
remote: z.string().optional(),
|
|
203
|
+
branch: z.string().optional(),
|
|
204
|
+
httpsTokenEnv: z.string().optional(),
|
|
205
|
+
skipHooks: z.boolean().optional()
|
|
206
|
+
});
|
|
207
|
+
var GitHubReleaseConfigSchema = z.object({
|
|
208
|
+
enabled: z.boolean().default(true),
|
|
209
|
+
draft: z.boolean().default(true),
|
|
210
|
+
perPackage: z.boolean().default(true),
|
|
211
|
+
prerelease: z.union([z.literal("auto"), z.boolean()]).default("auto"),
|
|
212
|
+
/**
|
|
213
|
+
* Controls how release notes are sourced for GitHub releases.
|
|
214
|
+
* - 'auto': Use RELEASE_NOTES.md if it exists, then per-package changelog
|
|
215
|
+
* data from the version output, then GitHub's auto-generated notes.
|
|
216
|
+
* - 'github': Always use GitHub's auto-generated notes.
|
|
217
|
+
* - 'none': No notes body.
|
|
218
|
+
* - Any other string: Treated as a file path to read notes from.
|
|
219
|
+
*/
|
|
220
|
+
releaseNotes: z.union([z.literal("auto"), z.literal("github"), z.literal("none"), z.string()]).default("auto")
|
|
221
|
+
});
|
|
222
|
+
var VerifyRegistryConfigSchema = z.object({
|
|
223
|
+
enabled: z.boolean().default(true),
|
|
224
|
+
maxAttempts: z.number().int().positive().default(5),
|
|
225
|
+
initialDelay: z.number().int().positive().default(15e3),
|
|
226
|
+
backoffMultiplier: z.number().positive().default(2)
|
|
227
|
+
});
|
|
228
|
+
var VerifyConfigSchema = z.object({
|
|
229
|
+
npm: VerifyRegistryConfigSchema.default({
|
|
230
|
+
enabled: true,
|
|
231
|
+
maxAttempts: 5,
|
|
232
|
+
initialDelay: 15e3,
|
|
233
|
+
backoffMultiplier: 2
|
|
234
|
+
}),
|
|
235
|
+
cargo: VerifyRegistryConfigSchema.default({
|
|
236
|
+
enabled: true,
|
|
237
|
+
maxAttempts: 10,
|
|
238
|
+
initialDelay: 3e4,
|
|
239
|
+
backoffMultiplier: 2
|
|
240
|
+
})
|
|
241
|
+
});
|
|
242
|
+
var PublishConfigSchema = z.object({
|
|
243
|
+
git: PublishGitConfigSchema.optional(),
|
|
244
|
+
npm: NpmConfigSchema.default({
|
|
245
|
+
enabled: true,
|
|
246
|
+
auth: "auto",
|
|
247
|
+
provenance: true,
|
|
248
|
+
access: "public",
|
|
249
|
+
registry: "https://registry.npmjs.org",
|
|
250
|
+
copyFiles: ["LICENSE"],
|
|
251
|
+
tag: "latest"
|
|
252
|
+
}),
|
|
253
|
+
cargo: CargoPublishConfigSchema.default({
|
|
254
|
+
enabled: false,
|
|
255
|
+
noVerify: false,
|
|
256
|
+
publishOrder: [],
|
|
257
|
+
clean: false
|
|
258
|
+
}),
|
|
259
|
+
githubRelease: GitHubReleaseConfigSchema.default({
|
|
260
|
+
enabled: true,
|
|
261
|
+
draft: true,
|
|
262
|
+
perPackage: true,
|
|
263
|
+
prerelease: "auto",
|
|
264
|
+
releaseNotes: "auto"
|
|
265
|
+
}),
|
|
266
|
+
verify: VerifyConfigSchema.default({
|
|
267
|
+
npm: {
|
|
268
|
+
enabled: true,
|
|
269
|
+
maxAttempts: 5,
|
|
270
|
+
initialDelay: 15e3,
|
|
271
|
+
backoffMultiplier: 2
|
|
272
|
+
},
|
|
273
|
+
cargo: {
|
|
274
|
+
enabled: true,
|
|
275
|
+
maxAttempts: 10,
|
|
276
|
+
initialDelay: 3e4,
|
|
277
|
+
backoffMultiplier: 2
|
|
278
|
+
}
|
|
279
|
+
})
|
|
280
|
+
});
|
|
281
|
+
var TemplateConfigSchema = z.object({
|
|
282
|
+
path: z.string().optional(),
|
|
283
|
+
engine: z.enum(["handlebars", "liquid", "ejs"]).optional()
|
|
284
|
+
});
|
|
285
|
+
var OutputConfigSchema = z.object({
|
|
286
|
+
format: z.enum(["markdown", "github-release", "json"]),
|
|
287
|
+
file: z.string().optional(),
|
|
288
|
+
options: z.record(z.string(), z.unknown()).optional(),
|
|
289
|
+
templates: TemplateConfigSchema.optional()
|
|
290
|
+
});
|
|
291
|
+
var LLMOptionsSchema = z.object({
|
|
292
|
+
timeout: z.number().optional(),
|
|
293
|
+
maxTokens: z.number().optional(),
|
|
294
|
+
temperature: z.number().optional()
|
|
295
|
+
});
|
|
296
|
+
var LLMRetryConfigSchema = z.object({
|
|
297
|
+
maxAttempts: z.number().int().positive().optional(),
|
|
298
|
+
initialDelay: z.number().nonnegative().optional(),
|
|
299
|
+
maxDelay: z.number().positive().optional(),
|
|
300
|
+
backoffFactor: z.number().positive().optional()
|
|
301
|
+
});
|
|
302
|
+
var LLMTasksConfigSchema = z.object({
|
|
303
|
+
summarize: z.boolean().optional(),
|
|
304
|
+
enhance: z.boolean().optional(),
|
|
305
|
+
categorize: z.boolean().optional(),
|
|
306
|
+
releaseNotes: z.boolean().optional()
|
|
307
|
+
});
|
|
308
|
+
var LLMCategorySchema = z.object({
|
|
309
|
+
name: z.string(),
|
|
310
|
+
description: z.string(),
|
|
311
|
+
scopes: z.array(z.string()).optional()
|
|
312
|
+
});
|
|
313
|
+
var ScopeRulesSchema = z.object({
|
|
314
|
+
allowed: z.array(z.string()).optional(),
|
|
315
|
+
caseSensitive: z.boolean().default(false),
|
|
316
|
+
invalidScopeAction: z.enum(["remove", "keep", "fallback"]).default("remove"),
|
|
317
|
+
fallbackScope: z.string().optional()
|
|
318
|
+
});
|
|
319
|
+
var ScopeConfigSchema = z.object({
|
|
320
|
+
mode: z.enum(["restricted", "packages", "none", "unrestricted"]).default("unrestricted"),
|
|
321
|
+
rules: ScopeRulesSchema.optional()
|
|
322
|
+
});
|
|
323
|
+
var LLMPromptOverridesSchema = z.object({
|
|
324
|
+
enhance: z.string().optional(),
|
|
325
|
+
categorize: z.string().optional(),
|
|
326
|
+
enhanceAndCategorize: z.string().optional(),
|
|
327
|
+
summarize: z.string().optional(),
|
|
328
|
+
releaseNotes: z.string().optional()
|
|
329
|
+
});
|
|
330
|
+
var LLMPromptsConfigSchema = z.object({
|
|
331
|
+
instructions: LLMPromptOverridesSchema.optional(),
|
|
332
|
+
templates: LLMPromptOverridesSchema.optional()
|
|
333
|
+
});
|
|
334
|
+
var LLMConfigSchema = z.object({
|
|
335
|
+
provider: z.string(),
|
|
336
|
+
model: z.string(),
|
|
337
|
+
baseURL: z.string().optional(),
|
|
338
|
+
apiKey: z.string().optional(),
|
|
339
|
+
options: LLMOptionsSchema.optional(),
|
|
340
|
+
concurrency: z.number().int().positive().optional(),
|
|
341
|
+
retry: LLMRetryConfigSchema.optional(),
|
|
342
|
+
tasks: LLMTasksConfigSchema.optional(),
|
|
343
|
+
categories: z.array(LLMCategorySchema).optional(),
|
|
344
|
+
style: z.string().optional(),
|
|
345
|
+
scopes: ScopeConfigSchema.optional(),
|
|
346
|
+
prompts: LLMPromptsConfigSchema.optional()
|
|
347
|
+
});
|
|
348
|
+
var NotesInputConfigSchema = z.object({
|
|
349
|
+
source: z.string().optional(),
|
|
350
|
+
file: z.string().optional()
|
|
351
|
+
});
|
|
352
|
+
var NotesConfigSchema = z.object({
|
|
353
|
+
input: NotesInputConfigSchema.optional(),
|
|
354
|
+
output: z.array(OutputConfigSchema).default([{ format: "markdown", file: "CHANGELOG.md" }]),
|
|
355
|
+
monorepo: MonorepoConfigSchema.optional(),
|
|
356
|
+
templates: TemplateConfigSchema.optional(),
|
|
357
|
+
llm: LLMConfigSchema.optional(),
|
|
358
|
+
updateStrategy: z.enum(["prepend", "regenerate"]).default("prepend")
|
|
359
|
+
});
|
|
360
|
+
var ReleaseKitConfigSchema = z.object({
|
|
361
|
+
git: GitConfigSchema.optional(),
|
|
362
|
+
monorepo: MonorepoConfigSchema.optional(),
|
|
363
|
+
version: VersionConfigSchema.optional(),
|
|
364
|
+
publish: PublishConfigSchema.optional(),
|
|
365
|
+
notes: NotesConfigSchema.optional()
|
|
366
|
+
});
|
|
367
|
+
var MAX_INPUT_LENGTH = 1e4;
|
|
368
|
+
function substituteVariables(value) {
|
|
369
|
+
if (value.length > MAX_INPUT_LENGTH) {
|
|
370
|
+
throw new Error(`Input too long: ${value.length} characters (max ${MAX_INPUT_LENGTH})`);
|
|
371
|
+
}
|
|
372
|
+
const envPattern = /\{env:([^}]{1,1000})\}/g;
|
|
373
|
+
const filePattern = /\{file:([^}]{1,1000})\}/g;
|
|
374
|
+
let result = value;
|
|
375
|
+
result = result.replace(envPattern, (_, varName) => {
|
|
376
|
+
return process.env[varName] ?? "";
|
|
377
|
+
});
|
|
378
|
+
result = result.replace(filePattern, (_, filePath) => {
|
|
379
|
+
const expandedPath = filePath.startsWith("~") ? path2.join(os.homedir(), filePath.slice(1)) : filePath;
|
|
380
|
+
try {
|
|
381
|
+
return fs2.readFileSync(expandedPath, "utf-8").trim();
|
|
382
|
+
} catch {
|
|
383
|
+
return "";
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
return result;
|
|
387
|
+
}
|
|
388
|
+
var SOLE_REFERENCE_PATTERN = /^\{(?:env|file):[^}]+\}$/;
|
|
389
|
+
function substituteInObject(obj) {
|
|
390
|
+
if (typeof obj === "string") {
|
|
391
|
+
const result = substituteVariables(obj);
|
|
392
|
+
if (result === "" && SOLE_REFERENCE_PATTERN.test(obj)) {
|
|
393
|
+
return void 0;
|
|
394
|
+
}
|
|
395
|
+
return result;
|
|
396
|
+
}
|
|
397
|
+
if (Array.isArray(obj)) {
|
|
398
|
+
return obj.map((item) => substituteInObject(item));
|
|
399
|
+
}
|
|
400
|
+
if (obj && typeof obj === "object") {
|
|
401
|
+
const result = {};
|
|
402
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
403
|
+
result[key] = substituteInObject(value);
|
|
404
|
+
}
|
|
405
|
+
return result;
|
|
406
|
+
}
|
|
407
|
+
return obj;
|
|
408
|
+
}
|
|
409
|
+
var AUTH_DIR = path2.join(os.homedir(), ".config", "releasekit");
|
|
410
|
+
var AUTH_FILE = path2.join(AUTH_DIR, "auth.json");
|
|
411
|
+
var CONFIG_FILE = "releasekit.config.json";
|
|
412
|
+
function loadConfigFile(configPath) {
|
|
413
|
+
if (!fs3.existsSync(configPath)) {
|
|
414
|
+
return {};
|
|
415
|
+
}
|
|
416
|
+
try {
|
|
417
|
+
const content = fs3.readFileSync(configPath, "utf-8");
|
|
418
|
+
const parsed = parseJsonc(content);
|
|
419
|
+
const substituted = substituteInObject(parsed);
|
|
420
|
+
return ReleaseKitConfigSchema.parse(substituted);
|
|
421
|
+
} catch (error) {
|
|
422
|
+
if (error instanceof z2.ZodError) {
|
|
423
|
+
const issues = error.issues.map((i) => ` ${i.path.join(".")}: ${i.message}`).join("\n");
|
|
424
|
+
throw new ConfigError(`Config validation errors:
|
|
425
|
+
${issues}`);
|
|
426
|
+
}
|
|
427
|
+
if (error instanceof SyntaxError) {
|
|
428
|
+
throw new ConfigError(`Invalid JSON in config file: ${error.message}`);
|
|
429
|
+
}
|
|
430
|
+
throw error;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
function loadConfig(options) {
|
|
434
|
+
const cwd = options?.cwd ?? process.cwd();
|
|
435
|
+
const configPath = options?.configPath ?? path3.join(cwd, CONFIG_FILE);
|
|
436
|
+
return loadConfigFile(configPath);
|
|
437
|
+
}
|
|
438
|
+
function loadPublishConfig(options) {
|
|
439
|
+
const config = loadConfig(options);
|
|
440
|
+
if (!config.publish) return void 0;
|
|
441
|
+
const mergedGit = mergeGitConfig(config.git, config.publish.git);
|
|
442
|
+
return {
|
|
443
|
+
...config.publish,
|
|
444
|
+
git: mergedGit ? {
|
|
445
|
+
push: mergedGit.push ?? true,
|
|
446
|
+
pushMethod: mergedGit.pushMethod,
|
|
447
|
+
remote: mergedGit.remote,
|
|
448
|
+
branch: mergedGit.branch,
|
|
449
|
+
httpsTokenEnv: mergedGit.httpsTokenEnv,
|
|
450
|
+
skipHooks: mergedGit.skipHooks
|
|
451
|
+
} : void 0
|
|
452
|
+
};
|
|
453
|
+
}
|
|
3
454
|
|
|
4
455
|
// src/types.ts
|
|
5
456
|
function getDefaultConfig() {
|
|
@@ -23,14 +474,16 @@ function getDefaultConfig() {
|
|
|
23
474
|
push: true,
|
|
24
475
|
pushMethod: "auto",
|
|
25
476
|
remote: "origin",
|
|
26
|
-
branch: "main"
|
|
477
|
+
branch: "main",
|
|
478
|
+
httpsTokenEnv: void 0,
|
|
479
|
+
skipHooks: false
|
|
27
480
|
},
|
|
28
481
|
githubRelease: {
|
|
29
482
|
enabled: true,
|
|
30
483
|
draft: true,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
484
|
+
perPackage: true,
|
|
485
|
+
prerelease: "auto",
|
|
486
|
+
releaseNotes: "auto"
|
|
34
487
|
},
|
|
35
488
|
verify: {
|
|
36
489
|
npm: {
|
|
@@ -71,15 +524,16 @@ function toPublishConfig(config) {
|
|
|
71
524
|
push: config.git.push ?? defaults.git.push,
|
|
72
525
|
pushMethod: config.git.pushMethod ?? defaults.git.pushMethod,
|
|
73
526
|
remote: config.git.remote ?? defaults.git.remote,
|
|
74
|
-
branch: config.git.branch ?? defaults.git.branch
|
|
527
|
+
branch: config.git.branch ?? defaults.git.branch,
|
|
528
|
+
httpsTokenEnv: config.git.httpsTokenEnv ?? defaults.git.httpsTokenEnv,
|
|
529
|
+
skipHooks: config.git.skipHooks ?? defaults.git.skipHooks
|
|
75
530
|
} : defaults.git,
|
|
76
531
|
githubRelease: {
|
|
77
532
|
enabled: config.githubRelease?.enabled ?? defaults.githubRelease.enabled,
|
|
78
533
|
draft: config.githubRelease?.draft ?? defaults.githubRelease.draft,
|
|
79
|
-
generateNotes: config.githubRelease?.generateNotes ?? defaults.githubRelease.generateNotes,
|
|
80
534
|
perPackage: config.githubRelease?.perPackage ?? defaults.githubRelease.perPackage,
|
|
81
535
|
prerelease: config.githubRelease?.prerelease ?? defaults.githubRelease.prerelease,
|
|
82
|
-
|
|
536
|
+
releaseNotes: config.githubRelease?.releaseNotes ?? defaults.githubRelease.releaseNotes
|
|
83
537
|
},
|
|
84
538
|
verify: {
|
|
85
539
|
npm: {
|
|
@@ -99,7 +553,7 @@ function toPublishConfig(config) {
|
|
|
99
553
|
}
|
|
100
554
|
|
|
101
555
|
// src/config.ts
|
|
102
|
-
function
|
|
556
|
+
function loadConfig2(options) {
|
|
103
557
|
const baseConfig = loadPublishConfig(options);
|
|
104
558
|
return toPublishConfig(baseConfig);
|
|
105
559
|
}
|
|
@@ -108,7 +562,6 @@ function getDefaultConfig2() {
|
|
|
108
562
|
}
|
|
109
563
|
|
|
110
564
|
// src/errors/index.ts
|
|
111
|
-
import { ReleaseKitError } from "@releasekit/core";
|
|
112
565
|
var BasePublishError = class _BasePublishError extends ReleaseKitError {
|
|
113
566
|
code;
|
|
114
567
|
suggestions;
|
|
@@ -247,9 +700,20 @@ function createPublishError(code, details) {
|
|
|
247
700
|
|
|
248
701
|
// src/utils/exec.ts
|
|
249
702
|
import { execFile } from "child_process";
|
|
250
|
-
|
|
703
|
+
function redactArg(arg) {
|
|
704
|
+
try {
|
|
705
|
+
const url = new URL(arg);
|
|
706
|
+
if (url.username || url.password) {
|
|
707
|
+
url.username = url.username ? "***" : "";
|
|
708
|
+
url.password = url.password ? "***" : "";
|
|
709
|
+
return url.toString();
|
|
710
|
+
}
|
|
711
|
+
} catch {
|
|
712
|
+
}
|
|
713
|
+
return arg;
|
|
714
|
+
}
|
|
251
715
|
async function execCommand(file, args, options = {}) {
|
|
252
|
-
const displayCommand = options.label ?? [file, ...args].join(" ");
|
|
716
|
+
const displayCommand = options.label ?? [file, ...args.map(redactArg)].join(" ");
|
|
253
717
|
if (options.dryRun) {
|
|
254
718
|
info(`[DRY RUN] Would execute: ${displayCommand}`);
|
|
255
719
|
return { stdout: "", stderr: "", exitCode: 0 };
|
|
@@ -305,7 +769,7 @@ function detectNpmAuth() {
|
|
|
305
769
|
if (process.env.ACTIONS_ID_TOKEN_REQUEST_URL) {
|
|
306
770
|
return "oidc";
|
|
307
771
|
}
|
|
308
|
-
if (process.env.NPM_TOKEN) {
|
|
772
|
+
if (process.env.NPM_TOKEN || process.env.NODE_AUTH_TOKEN) {
|
|
309
773
|
return "token";
|
|
310
774
|
}
|
|
311
775
|
return null;
|
|
@@ -323,15 +787,14 @@ async function detectGitPushMethod(remote, cwd) {
|
|
|
323
787
|
}
|
|
324
788
|
|
|
325
789
|
// src/utils/cargo.ts
|
|
326
|
-
import * as
|
|
327
|
-
import
|
|
328
|
-
import * as TOML from "smol-toml";
|
|
790
|
+
import * as fs4 from "fs";
|
|
791
|
+
import * as TOML2 from "smol-toml";
|
|
329
792
|
function updateCargoVersion(cargoPath, newVersion) {
|
|
330
793
|
try {
|
|
331
794
|
const cargo = parseCargoToml(cargoPath);
|
|
332
795
|
if (cargo.package) {
|
|
333
796
|
cargo.package.version = newVersion;
|
|
334
|
-
|
|
797
|
+
fs4.writeFileSync(cargoPath, TOML2.stringify(cargo));
|
|
335
798
|
}
|
|
336
799
|
} catch (error) {
|
|
337
800
|
throw createPublishError(
|
|
@@ -368,11 +831,11 @@ function getDistTag(version, defaultTag = "latest") {
|
|
|
368
831
|
}
|
|
369
832
|
|
|
370
833
|
// src/utils/package-manager.ts
|
|
371
|
-
import * as
|
|
372
|
-
import * as
|
|
834
|
+
import * as fs5 from "fs";
|
|
835
|
+
import * as path4 from "path";
|
|
373
836
|
function detectPackageManager(cwd) {
|
|
374
|
-
if (
|
|
375
|
-
if (
|
|
837
|
+
if (fs5.existsSync(path4.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
838
|
+
if (fs5.existsSync(path4.join(cwd, "yarn.lock"))) return "yarn";
|
|
376
839
|
return "npm";
|
|
377
840
|
}
|
|
378
841
|
function buildPublishCommand(pm, packageName, _packageDir, options) {
|
|
@@ -397,25 +860,24 @@ function buildViewCommand(pm, packageName, version) {
|
|
|
397
860
|
}
|
|
398
861
|
|
|
399
862
|
// src/stages/cargo-publish.ts
|
|
400
|
-
import * as
|
|
401
|
-
import * as
|
|
402
|
-
import { debug as debug2, success, warn } from "@releasekit/core";
|
|
863
|
+
import * as fs6 from "fs";
|
|
864
|
+
import * as path5 from "path";
|
|
403
865
|
async function runCargoPublishStage(ctx) {
|
|
404
866
|
const { input, config, cliOptions, cwd } = ctx;
|
|
405
867
|
const dryRun = cliOptions.dryRun;
|
|
406
868
|
if (!config.cargo.enabled) {
|
|
407
|
-
|
|
869
|
+
debug("Cargo publishing disabled in config");
|
|
408
870
|
return;
|
|
409
871
|
}
|
|
410
872
|
if (!hasCargoAuth() && !dryRun) {
|
|
411
873
|
throw createPublishError("CARGO_AUTH_ERROR" /* CARGO_AUTH_ERROR */, "CARGO_REGISTRY_TOKEN not set");
|
|
412
874
|
}
|
|
413
875
|
const crates = findCrates(
|
|
414
|
-
input.updates.map((u) => ({ dir:
|
|
876
|
+
input.updates.map((u) => ({ dir: path5.dirname(path5.resolve(cwd, u.filePath)), ...u })),
|
|
415
877
|
cwd
|
|
416
878
|
);
|
|
417
879
|
if (crates.length === 0) {
|
|
418
|
-
|
|
880
|
+
debug("No Cargo crates found to publish");
|
|
419
881
|
return;
|
|
420
882
|
}
|
|
421
883
|
const ordered = orderCrates(crates, config.cargo.publishOrder);
|
|
@@ -464,8 +926,8 @@ async function runCargoPublishStage(ctx) {
|
|
|
464
926
|
function findCrates(updates, _cwd) {
|
|
465
927
|
const crates = [];
|
|
466
928
|
for (const update of updates) {
|
|
467
|
-
const cargoPath =
|
|
468
|
-
if (!
|
|
929
|
+
const cargoPath = path5.join(update.dir, "Cargo.toml");
|
|
930
|
+
if (!fs6.existsSync(cargoPath)) {
|
|
469
931
|
continue;
|
|
470
932
|
}
|
|
471
933
|
try {
|
|
@@ -513,9 +975,9 @@ function topologicalSort(crates) {
|
|
|
513
975
|
}
|
|
514
976
|
for (const crate of crates) {
|
|
515
977
|
for (const depPath of crate.pathDeps) {
|
|
516
|
-
const resolvedDir =
|
|
978
|
+
const resolvedDir = path5.resolve(crate.dir, depPath);
|
|
517
979
|
for (const other of crates) {
|
|
518
|
-
if (
|
|
980
|
+
if (path5.resolve(other.dir) === resolvedDir && nameSet.has(other.name)) {
|
|
519
981
|
graph.get(crate.name)?.push(other.name);
|
|
520
982
|
}
|
|
521
983
|
}
|
|
@@ -557,18 +1019,21 @@ function topologicalSort(crates) {
|
|
|
557
1019
|
}
|
|
558
1020
|
|
|
559
1021
|
// src/stages/git-commit.ts
|
|
560
|
-
import * as
|
|
561
|
-
import { info as info2, success as success2 } from "@releasekit/core";
|
|
1022
|
+
import * as path6 from "path";
|
|
562
1023
|
async function runGitCommitStage(ctx) {
|
|
563
|
-
const { input, cliOptions, cwd } = ctx;
|
|
1024
|
+
const { input, config, cliOptions, cwd } = ctx;
|
|
564
1025
|
const dryRun = cliOptions.dryRun;
|
|
1026
|
+
const skipHooks = config.git.skipHooks ?? false;
|
|
565
1027
|
if (!input.commitMessage) {
|
|
566
|
-
|
|
1028
|
+
info("No commit message provided, skipping git commit");
|
|
567
1029
|
return;
|
|
568
1030
|
}
|
|
569
|
-
const filePaths = input.updates.map((u) =>
|
|
1031
|
+
const filePaths = input.updates.map((u) => path6.resolve(cwd, u.filePath));
|
|
1032
|
+
if (ctx.additionalFiles) {
|
|
1033
|
+
filePaths.push(...ctx.additionalFiles.map((f) => path6.resolve(cwd, f)));
|
|
1034
|
+
}
|
|
570
1035
|
if (filePaths.length === 0) {
|
|
571
|
-
|
|
1036
|
+
info("No files to commit");
|
|
572
1037
|
return;
|
|
573
1038
|
}
|
|
574
1039
|
try {
|
|
@@ -583,15 +1048,20 @@ async function runGitCommitStage(ctx) {
|
|
|
583
1048
|
`git add failed: ${error instanceof Error ? error.message : String(error)}`
|
|
584
1049
|
);
|
|
585
1050
|
}
|
|
1051
|
+
const commitArgs = ["commit"];
|
|
1052
|
+
if (skipHooks) {
|
|
1053
|
+
commitArgs.push("--no-verify");
|
|
1054
|
+
}
|
|
1055
|
+
commitArgs.push("-m", input.commitMessage);
|
|
586
1056
|
try {
|
|
587
|
-
await execCommand("git",
|
|
1057
|
+
await execCommand("git", commitArgs, {
|
|
588
1058
|
cwd,
|
|
589
1059
|
dryRun,
|
|
590
1060
|
label: `git commit -m "${input.commitMessage}"`
|
|
591
1061
|
});
|
|
592
1062
|
ctx.output.git.committed = true;
|
|
593
1063
|
if (!dryRun) {
|
|
594
|
-
|
|
1064
|
+
success("Created git commit");
|
|
595
1065
|
}
|
|
596
1066
|
} catch (error) {
|
|
597
1067
|
throw createPublishError(
|
|
@@ -609,7 +1079,7 @@ async function runGitCommitStage(ctx) {
|
|
|
609
1079
|
});
|
|
610
1080
|
ctx.output.git.tags.push(tag);
|
|
611
1081
|
if (!dryRun) {
|
|
612
|
-
|
|
1082
|
+
success(`Created tag: ${tag}`);
|
|
613
1083
|
}
|
|
614
1084
|
} catch (error) {
|
|
615
1085
|
throw createPublishError(
|
|
@@ -621,16 +1091,27 @@ async function runGitCommitStage(ctx) {
|
|
|
621
1091
|
}
|
|
622
1092
|
|
|
623
1093
|
// src/stages/git-push.ts
|
|
624
|
-
|
|
1094
|
+
function toGithubAuthedUrl(remoteUrl, token) {
|
|
1095
|
+
try {
|
|
1096
|
+
const url = new URL(remoteUrl);
|
|
1097
|
+
if (url.protocol !== "https:") return void 0;
|
|
1098
|
+
if (url.host !== "github.com") return void 0;
|
|
1099
|
+
url.username = "x-access-token";
|
|
1100
|
+
url.password = token;
|
|
1101
|
+
return url.toString();
|
|
1102
|
+
} catch {
|
|
1103
|
+
return void 0;
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
625
1106
|
async function runGitPushStage(ctx) {
|
|
626
1107
|
const { config, cliOptions, cwd, output } = ctx;
|
|
627
1108
|
const dryRun = cliOptions.dryRun;
|
|
628
1109
|
if (!config.git.push) {
|
|
629
|
-
|
|
1110
|
+
info("Git push disabled in config, skipping");
|
|
630
1111
|
return;
|
|
631
1112
|
}
|
|
632
1113
|
if (!output.git.committed && output.git.tags.length === 0) {
|
|
633
|
-
|
|
1114
|
+
info("Nothing to push (no commits or tags created)");
|
|
634
1115
|
return;
|
|
635
1116
|
}
|
|
636
1117
|
const { remote, branch } = config.git;
|
|
@@ -642,16 +1123,26 @@ async function runGitPushStage(ctx) {
|
|
|
642
1123
|
pushMethod = "https";
|
|
643
1124
|
}
|
|
644
1125
|
}
|
|
1126
|
+
const httpsTokenEnv = config.git.httpsTokenEnv;
|
|
1127
|
+
const httpsToken = httpsTokenEnv ? process.env[httpsTokenEnv] : void 0;
|
|
645
1128
|
try {
|
|
1129
|
+
let pushRemote = remote;
|
|
1130
|
+
if (pushMethod === "https" && httpsToken) {
|
|
1131
|
+
const remoteUrlResult = await execCommand("git", ["remote", "get-url", remote], { cwd, dryRun: false });
|
|
1132
|
+
const authed = toGithubAuthedUrl(remoteUrlResult.stdout.trim(), httpsToken);
|
|
1133
|
+
if (authed) {
|
|
1134
|
+
pushRemote = authed;
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
646
1137
|
if (output.git.committed) {
|
|
647
|
-
await execCommand("git", ["push",
|
|
1138
|
+
await execCommand("git", ["push", pushRemote, branch], {
|
|
648
1139
|
cwd,
|
|
649
1140
|
dryRun,
|
|
650
1141
|
label: `git push ${remote} ${branch}`
|
|
651
1142
|
});
|
|
652
1143
|
}
|
|
653
1144
|
if (output.git.tags.length > 0) {
|
|
654
|
-
await execCommand("git", ["push",
|
|
1145
|
+
await execCommand("git", ["push", pushRemote, "--tags"], {
|
|
655
1146
|
cwd,
|
|
656
1147
|
dryRun,
|
|
657
1148
|
label: `git push ${remote} --tags`
|
|
@@ -659,7 +1150,7 @@ async function runGitPushStage(ctx) {
|
|
|
659
1150
|
}
|
|
660
1151
|
ctx.output.git.pushed = true;
|
|
661
1152
|
if (!dryRun) {
|
|
662
|
-
|
|
1153
|
+
success(`Pushed to ${remote}/${branch}`);
|
|
663
1154
|
}
|
|
664
1155
|
} catch (error) {
|
|
665
1156
|
throw createPublishError(
|
|
@@ -670,33 +1161,82 @@ async function runGitPushStage(ctx) {
|
|
|
670
1161
|
}
|
|
671
1162
|
|
|
672
1163
|
// src/stages/github-release.ts
|
|
673
|
-
import * as
|
|
674
|
-
|
|
1164
|
+
import * as fs7 from "fs";
|
|
1165
|
+
function resolveNotes(notesSetting, tag, changelogs, pipelineNotes) {
|
|
1166
|
+
if (notesSetting === "none") {
|
|
1167
|
+
return { useGithubNotes: false };
|
|
1168
|
+
}
|
|
1169
|
+
if (notesSetting === "github") {
|
|
1170
|
+
return { useGithubNotes: true };
|
|
1171
|
+
}
|
|
1172
|
+
if (notesSetting !== "auto") {
|
|
1173
|
+
const body = readFileIfExists(notesSetting);
|
|
1174
|
+
if (body) return { body, useGithubNotes: false };
|
|
1175
|
+
debug(`Notes file not found: ${notesSetting}, falling back to GitHub auto-notes`);
|
|
1176
|
+
return { useGithubNotes: true };
|
|
1177
|
+
}
|
|
1178
|
+
if (pipelineNotes) {
|
|
1179
|
+
const body = findNotesForTag(tag, pipelineNotes);
|
|
1180
|
+
if (body) return { body, useGithubNotes: false };
|
|
1181
|
+
}
|
|
1182
|
+
const packageBody = formatChangelogForTag(tag, changelogs);
|
|
1183
|
+
if (packageBody) {
|
|
1184
|
+
return { body: packageBody, useGithubNotes: false };
|
|
1185
|
+
}
|
|
1186
|
+
return { useGithubNotes: true };
|
|
1187
|
+
}
|
|
1188
|
+
function isVersionOnlyTag(tag) {
|
|
1189
|
+
return /^v?\d+\.\d+\.\d+/.test(tag);
|
|
1190
|
+
}
|
|
1191
|
+
function findNotesForTag(tag, notes) {
|
|
1192
|
+
for (const [packageName, body] of Object.entries(notes)) {
|
|
1193
|
+
if (tag.startsWith(`${packageName}@`) && body.trim()) {
|
|
1194
|
+
return body;
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
const entries = Object.values(notes).filter((b) => b.trim());
|
|
1198
|
+
if (entries.length === 1 && isVersionOnlyTag(tag)) return entries[0];
|
|
1199
|
+
return void 0;
|
|
1200
|
+
}
|
|
1201
|
+
function readFileIfExists(filePath) {
|
|
1202
|
+
try {
|
|
1203
|
+
const content = fs7.readFileSync(filePath, "utf-8").trim();
|
|
1204
|
+
return content || void 0;
|
|
1205
|
+
} catch {
|
|
1206
|
+
return void 0;
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
function formatChangelogForTag(tag, changelogs) {
|
|
1210
|
+
if (changelogs.length === 0) return void 0;
|
|
1211
|
+
const changelog = changelogs.find((c) => tag.startsWith(`${c.packageName}@`));
|
|
1212
|
+
const target = changelog ?? (changelogs.length === 1 && isVersionOnlyTag(tag) ? changelogs[0] : void 0);
|
|
1213
|
+
if (!target || target.entries.length === 0) return void 0;
|
|
1214
|
+
const lines = [];
|
|
1215
|
+
for (const entry of target.entries) {
|
|
1216
|
+
const scope = entry.scope ? `**${entry.scope}:** ` : "";
|
|
1217
|
+
lines.push(`- ${scope}${entry.description}`);
|
|
1218
|
+
}
|
|
1219
|
+
return lines.join("\n");
|
|
1220
|
+
}
|
|
675
1221
|
async function runGithubReleaseStage(ctx) {
|
|
676
1222
|
const { config, cliOptions, output } = ctx;
|
|
677
1223
|
const dryRun = cliOptions.dryRun;
|
|
678
1224
|
if (!config.githubRelease.enabled) {
|
|
679
|
-
|
|
1225
|
+
debug("GitHub releases disabled in config");
|
|
680
1226
|
return;
|
|
681
1227
|
}
|
|
682
1228
|
const tags = output.git.tags.length > 0 ? output.git.tags : ctx.input.tags;
|
|
683
1229
|
if (tags.length === 0) {
|
|
684
|
-
|
|
1230
|
+
info("No tags available for GitHub release");
|
|
685
1231
|
return;
|
|
686
1232
|
}
|
|
687
|
-
let notesBody;
|
|
688
|
-
if (config.githubRelease.notesFile) {
|
|
689
|
-
try {
|
|
690
|
-
notesBody = fs4.readFileSync(config.githubRelease.notesFile, "utf-8");
|
|
691
|
-
} catch {
|
|
692
|
-
debug3(`Could not read notes file: ${config.githubRelease.notesFile}`);
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
1233
|
const firstTag = tags[0];
|
|
696
1234
|
if (!firstTag) return;
|
|
697
1235
|
const tagsToRelease = config.githubRelease.perPackage ? tags : [firstTag];
|
|
698
1236
|
for (const tag of tagsToRelease) {
|
|
699
|
-
const
|
|
1237
|
+
const MAX_TAG_LENGTH = 1e3;
|
|
1238
|
+
const truncatedTag = tag.length > MAX_TAG_LENGTH ? tag.slice(0, MAX_TAG_LENGTH) : tag;
|
|
1239
|
+
const versionMatch = truncatedTag.match(/(\d{1,20}\.\d{1,20}\.\d{1,20}(?:[-+.]?[a-zA-Z0-9.-]{0,100})?)$/);
|
|
700
1240
|
const version = versionMatch?.[1] ?? "";
|
|
701
1241
|
const isPreRel = config.githubRelease.prerelease === "auto" ? version ? isPrerelease(version) : false : config.githubRelease.prerelease;
|
|
702
1242
|
const result = {
|
|
@@ -712,9 +1252,15 @@ async function runGithubReleaseStage(ctx) {
|
|
|
712
1252
|
if (isPreRel) {
|
|
713
1253
|
ghArgs.push("--prerelease");
|
|
714
1254
|
}
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
1255
|
+
const { body, useGithubNotes } = resolveNotes(
|
|
1256
|
+
config.githubRelease.releaseNotes,
|
|
1257
|
+
tag,
|
|
1258
|
+
ctx.input.changelogs,
|
|
1259
|
+
ctx.releaseNotes
|
|
1260
|
+
);
|
|
1261
|
+
if (body) {
|
|
1262
|
+
ghArgs.push("--notes", body);
|
|
1263
|
+
} else if (useGithubNotes) {
|
|
718
1264
|
ghArgs.push("--generate-notes");
|
|
719
1265
|
}
|
|
720
1266
|
try {
|
|
@@ -727,25 +1273,91 @@ async function runGithubReleaseStage(ctx) {
|
|
|
727
1273
|
result.url = execResult.stdout.trim();
|
|
728
1274
|
}
|
|
729
1275
|
if (!dryRun) {
|
|
730
|
-
|
|
1276
|
+
success(`Created GitHub release for ${tag}`);
|
|
731
1277
|
}
|
|
732
1278
|
} catch (error) {
|
|
733
1279
|
result.reason = error instanceof Error ? error.message : String(error);
|
|
734
|
-
|
|
1280
|
+
warn(`Failed to create GitHub release for ${tag}: ${result.reason}`);
|
|
735
1281
|
}
|
|
736
1282
|
ctx.output.githubReleases.push(result);
|
|
737
1283
|
}
|
|
738
1284
|
}
|
|
739
1285
|
|
|
740
1286
|
// src/stages/npm-publish.ts
|
|
741
|
-
import * as
|
|
742
|
-
import * as
|
|
743
|
-
|
|
1287
|
+
import * as fs9 from "fs";
|
|
1288
|
+
import * as path8 from "path";
|
|
1289
|
+
|
|
1290
|
+
// src/utils/npm-env.ts
|
|
1291
|
+
import * as fs8 from "fs";
|
|
1292
|
+
import * as os2 from "os";
|
|
1293
|
+
import * as path7 from "path";
|
|
1294
|
+
function writeTempNpmrc(contents) {
|
|
1295
|
+
const dir = fs8.mkdtempSync(path7.join(os2.tmpdir(), "releasekit-npmrc-"));
|
|
1296
|
+
const npmrcPath = path7.join(dir, ".npmrc");
|
|
1297
|
+
fs8.writeFileSync(npmrcPath, contents, "utf-8");
|
|
1298
|
+
return {
|
|
1299
|
+
npmrcPath,
|
|
1300
|
+
cleanup: () => {
|
|
1301
|
+
try {
|
|
1302
|
+
fs8.rmSync(dir, { recursive: true, force: true });
|
|
1303
|
+
} catch {
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
};
|
|
1307
|
+
}
|
|
1308
|
+
function createNpmSubprocessIsolation(options) {
|
|
1309
|
+
const { authMethod, registryUrl } = options;
|
|
1310
|
+
const baseEnv = {};
|
|
1311
|
+
if (!authMethod) return { env: baseEnv, cleanup: () => {
|
|
1312
|
+
} };
|
|
1313
|
+
const token = process.env.NPM_TOKEN ?? process.env.NODE_AUTH_TOKEN;
|
|
1314
|
+
const registryHost = (() => {
|
|
1315
|
+
try {
|
|
1316
|
+
return new URL(registryUrl).host;
|
|
1317
|
+
} catch {
|
|
1318
|
+
return "registry.npmjs.org";
|
|
1319
|
+
}
|
|
1320
|
+
})();
|
|
1321
|
+
const lines = [`registry=${registryUrl}`];
|
|
1322
|
+
if (authMethod === "oidc") {
|
|
1323
|
+
lines.push("always-auth=false");
|
|
1324
|
+
}
|
|
1325
|
+
if (authMethod === "token" && token) {
|
|
1326
|
+
lines.push(`//${registryHost}/:_authToken=${token}`);
|
|
1327
|
+
}
|
|
1328
|
+
lines.push("");
|
|
1329
|
+
const { npmrcPath, cleanup } = writeTempNpmrc(lines.join("\n"));
|
|
1330
|
+
debug(`Using isolated npm userconfig: ${npmrcPath}`);
|
|
1331
|
+
const isOidc = authMethod === "oidc";
|
|
1332
|
+
return {
|
|
1333
|
+
env: {
|
|
1334
|
+
...baseEnv,
|
|
1335
|
+
// Ensure npm and tools that read npm_config_* pick up our temp file
|
|
1336
|
+
NPM_CONFIG_USERCONFIG: npmrcPath,
|
|
1337
|
+
npm_config_userconfig: npmrcPath,
|
|
1338
|
+
// Auth-specific hardening
|
|
1339
|
+
...isOidc ? {
|
|
1340
|
+
// Prevent setup-node's always-auth from forcing token lookups
|
|
1341
|
+
NPM_CONFIG_ALWAYS_AUTH: "false",
|
|
1342
|
+
npm_config_always_auth: "false",
|
|
1343
|
+
// Explicitly prevent token-based publishing from being selected implicitly
|
|
1344
|
+
NODE_AUTH_TOKEN: void 0,
|
|
1345
|
+
NPM_TOKEN: void 0
|
|
1346
|
+
} : {
|
|
1347
|
+
// Ensure CLIs that expect NODE_AUTH_TOKEN can still work
|
|
1348
|
+
NODE_AUTH_TOKEN: token
|
|
1349
|
+
}
|
|
1350
|
+
},
|
|
1351
|
+
cleanup
|
|
1352
|
+
};
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
// src/stages/npm-publish.ts
|
|
744
1356
|
async function runNpmPublishStage(ctx) {
|
|
745
1357
|
const { input, config, cliOptions, cwd } = ctx;
|
|
746
1358
|
const dryRun = cliOptions.dryRun;
|
|
747
1359
|
if (!config.npm.enabled) {
|
|
748
|
-
|
|
1360
|
+
info("NPM publishing disabled in config");
|
|
749
1361
|
return;
|
|
750
1362
|
}
|
|
751
1363
|
const authMethod = config.npm.auth === "auto" ? detectNpmAuth() : config.npm.auth;
|
|
@@ -753,107 +1365,116 @@ async function runNpmPublishStage(ctx) {
|
|
|
753
1365
|
throw createPublishError("NPM_AUTH_ERROR" /* NPM_AUTH_ERROR */, "No NPM authentication method detected");
|
|
754
1366
|
}
|
|
755
1367
|
const useProvenance = config.npm.provenance && authMethod === "oidc";
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
1368
|
+
const npmIsolation = createNpmSubprocessIsolation({
|
|
1369
|
+
authMethod,
|
|
1370
|
+
registryUrl: config.npm.registry
|
|
1371
|
+
});
|
|
1372
|
+
try {
|
|
1373
|
+
for (const update of input.updates) {
|
|
1374
|
+
const result = {
|
|
1375
|
+
packageName: update.packageName,
|
|
1376
|
+
version: update.newVersion,
|
|
1377
|
+
registry: "npm",
|
|
1378
|
+
success: false,
|
|
1379
|
+
skipped: false
|
|
1380
|
+
};
|
|
1381
|
+
const pkgJsonPath = path8.resolve(cwd, update.filePath);
|
|
1382
|
+
try {
|
|
1383
|
+
const pkgContent = fs9.readFileSync(pkgJsonPath, "utf-8");
|
|
1384
|
+
const pkgJson = JSON.parse(pkgContent);
|
|
1385
|
+
if (pkgJson.private) {
|
|
1386
|
+
result.skipped = true;
|
|
1387
|
+
result.success = true;
|
|
1388
|
+
result.reason = "Package is private";
|
|
1389
|
+
ctx.output.npm.push(result);
|
|
1390
|
+
debug(`Skipping private package: ${update.packageName}`);
|
|
1391
|
+
continue;
|
|
1392
|
+
}
|
|
1393
|
+
} catch {
|
|
1394
|
+
if (update.filePath.endsWith("Cargo.toml")) {
|
|
1395
|
+
result.skipped = true;
|
|
1396
|
+
result.success = true;
|
|
1397
|
+
result.reason = "Not an npm package";
|
|
1398
|
+
ctx.output.npm.push(result);
|
|
1399
|
+
continue;
|
|
1400
|
+
}
|
|
775
1401
|
}
|
|
776
|
-
|
|
777
|
-
|
|
1402
|
+
const { file: viewFile, args: viewArgs } = buildViewCommand(
|
|
1403
|
+
ctx.packageManager,
|
|
1404
|
+
update.packageName,
|
|
1405
|
+
update.newVersion
|
|
1406
|
+
);
|
|
1407
|
+
const viewResult = await execCommandSafe(viewFile, viewArgs, {
|
|
1408
|
+
cwd,
|
|
1409
|
+
dryRun: false,
|
|
1410
|
+
// Always check, even in dry-run
|
|
1411
|
+
env: npmIsolation.env
|
|
1412
|
+
});
|
|
1413
|
+
if (viewResult.exitCode === 0 && viewResult.stdout.trim()) {
|
|
1414
|
+
result.alreadyPublished = true;
|
|
778
1415
|
result.skipped = true;
|
|
779
1416
|
result.success = true;
|
|
780
|
-
result.reason = "
|
|
1417
|
+
result.reason = "Already published";
|
|
781
1418
|
ctx.output.npm.push(result);
|
|
1419
|
+
warn(`${update.packageName}@${update.newVersion} is already published, skipping`);
|
|
782
1420
|
continue;
|
|
783
1421
|
}
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
ctx.packageManager,
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
cwd,
|
|
792
|
-
dryRun: false
|
|
793
|
-
// Always check, even in dry-run
|
|
794
|
-
});
|
|
795
|
-
if (viewResult.exitCode === 0 && viewResult.stdout.trim()) {
|
|
796
|
-
result.alreadyPublished = true;
|
|
797
|
-
result.skipped = true;
|
|
798
|
-
result.success = true;
|
|
799
|
-
result.reason = "Already published";
|
|
800
|
-
ctx.output.npm.push(result);
|
|
801
|
-
warn3(`${update.packageName}@${update.newVersion} is already published, skipping`);
|
|
802
|
-
continue;
|
|
803
|
-
}
|
|
804
|
-
const distTag = getDistTag(update.newVersion, config.npm.tag);
|
|
805
|
-
const pkgDir = path4.dirname(path4.resolve(cwd, update.filePath));
|
|
806
|
-
const { file: pubFile, args: pubArgs } = buildPublishCommand(ctx.packageManager, update.packageName, pkgDir, {
|
|
807
|
-
access: config.npm.access,
|
|
808
|
-
tag: distTag,
|
|
809
|
-
provenance: useProvenance,
|
|
810
|
-
noGitChecks: true
|
|
811
|
-
});
|
|
812
|
-
try {
|
|
813
|
-
await execCommand(pubFile, pubArgs, {
|
|
814
|
-
cwd,
|
|
815
|
-
dryRun,
|
|
816
|
-
label: `npm publish ${update.packageName}@${update.newVersion}`
|
|
1422
|
+
const distTag = getDistTag(update.newVersion, config.npm.tag);
|
|
1423
|
+
const pkgDir = path8.dirname(path8.resolve(cwd, update.filePath));
|
|
1424
|
+
const { file: pubFile, args: pubArgs } = buildPublishCommand(ctx.packageManager, update.packageName, pkgDir, {
|
|
1425
|
+
access: config.npm.access,
|
|
1426
|
+
tag: distTag,
|
|
1427
|
+
provenance: useProvenance,
|
|
1428
|
+
noGitChecks: true
|
|
817
1429
|
});
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
1430
|
+
try {
|
|
1431
|
+
await execCommand(pubFile, pubArgs, {
|
|
1432
|
+
cwd,
|
|
1433
|
+
dryRun,
|
|
1434
|
+
label: `npm publish ${update.packageName}@${update.newVersion}`,
|
|
1435
|
+
env: npmIsolation.env
|
|
1436
|
+
});
|
|
1437
|
+
result.success = true;
|
|
1438
|
+
if (!dryRun) {
|
|
1439
|
+
success(`Published ${update.packageName}@${update.newVersion} to npm`);
|
|
1440
|
+
}
|
|
1441
|
+
} catch (error) {
|
|
1442
|
+
result.reason = error instanceof Error ? error.message : String(error);
|
|
1443
|
+
warn(`Failed to publish ${update.packageName}: ${result.reason}`);
|
|
821
1444
|
}
|
|
822
|
-
|
|
823
|
-
result.reason = error instanceof Error ? error.message : String(error);
|
|
824
|
-
warn3(`Failed to publish ${update.packageName}: ${result.reason}`);
|
|
1445
|
+
ctx.output.npm.push(result);
|
|
825
1446
|
}
|
|
826
|
-
|
|
1447
|
+
} finally {
|
|
1448
|
+
npmIsolation.cleanup();
|
|
827
1449
|
}
|
|
828
1450
|
}
|
|
829
1451
|
|
|
830
1452
|
// src/stages/prepare.ts
|
|
831
|
-
import * as
|
|
832
|
-
import * as
|
|
833
|
-
import { debug as debug5, info as info6 } from "@releasekit/core";
|
|
1453
|
+
import * as fs10 from "fs";
|
|
1454
|
+
import * as path9 from "path";
|
|
834
1455
|
async function runPrepareStage(ctx) {
|
|
835
1456
|
const { input, config, cliOptions, cwd } = ctx;
|
|
836
1457
|
if (config.npm.enabled && config.npm.copyFiles.length > 0) {
|
|
837
1458
|
for (const update of input.updates) {
|
|
838
|
-
const pkgDir =
|
|
1459
|
+
const pkgDir = path9.dirname(path9.resolve(cwd, update.filePath));
|
|
839
1460
|
for (const file of config.npm.copyFiles) {
|
|
840
|
-
const src =
|
|
841
|
-
const dest =
|
|
842
|
-
if (!
|
|
843
|
-
|
|
1461
|
+
const src = path9.resolve(cwd, file);
|
|
1462
|
+
const dest = path9.join(pkgDir, file);
|
|
1463
|
+
if (!fs10.existsSync(src)) {
|
|
1464
|
+
debug(`Source file not found, skipping copy: ${src}`);
|
|
844
1465
|
continue;
|
|
845
1466
|
}
|
|
846
|
-
if (
|
|
847
|
-
|
|
1467
|
+
if (path9.resolve(path9.dirname(src)) === path9.resolve(pkgDir)) {
|
|
1468
|
+
debug(`Skipping copy of ${file} - same directory as source`);
|
|
848
1469
|
continue;
|
|
849
1470
|
}
|
|
850
1471
|
if (cliOptions.dryRun) {
|
|
851
|
-
|
|
1472
|
+
info(`[DRY RUN] Would copy ${src} \u2192 ${dest}`);
|
|
852
1473
|
continue;
|
|
853
1474
|
}
|
|
854
1475
|
try {
|
|
855
|
-
|
|
856
|
-
|
|
1476
|
+
fs10.copyFileSync(src, dest);
|
|
1477
|
+
debug(`Copied ${file} \u2192 ${pkgDir}`);
|
|
857
1478
|
} catch (error) {
|
|
858
1479
|
throw createPublishError(
|
|
859
1480
|
"FILE_COPY_ERROR" /* FILE_COPY_ERROR */,
|
|
@@ -865,26 +1486,22 @@ async function runPrepareStage(ctx) {
|
|
|
865
1486
|
}
|
|
866
1487
|
if (config.cargo.enabled) {
|
|
867
1488
|
for (const update of input.updates) {
|
|
868
|
-
const pkgDir =
|
|
869
|
-
const cargoPath =
|
|
870
|
-
if (!
|
|
1489
|
+
const pkgDir = path9.dirname(path9.resolve(cwd, update.filePath));
|
|
1490
|
+
const cargoPath = path9.join(pkgDir, "Cargo.toml");
|
|
1491
|
+
if (!fs10.existsSync(cargoPath)) {
|
|
871
1492
|
continue;
|
|
872
1493
|
}
|
|
873
1494
|
if (cliOptions.dryRun) {
|
|
874
|
-
|
|
1495
|
+
info(`[DRY RUN] Would update ${cargoPath} to version ${update.newVersion}`);
|
|
875
1496
|
continue;
|
|
876
1497
|
}
|
|
877
1498
|
updateCargoVersion(cargoPath, update.newVersion);
|
|
878
|
-
|
|
1499
|
+
debug(`Updated ${cargoPath} to version ${update.newVersion}`);
|
|
879
1500
|
}
|
|
880
1501
|
}
|
|
881
1502
|
}
|
|
882
1503
|
|
|
883
|
-
// src/stages/verify.ts
|
|
884
|
-
import { debug as debug7, info as info7, success as success6, warn as warn4 } from "@releasekit/core";
|
|
885
|
-
|
|
886
1504
|
// src/utils/retry.ts
|
|
887
|
-
import { debug as debug6 } from "@releasekit/core";
|
|
888
1505
|
async function withRetry(fn, options, shouldRetry) {
|
|
889
1506
|
let lastError;
|
|
890
1507
|
let delay = options.initialDelay;
|
|
@@ -897,7 +1514,7 @@ async function withRetry(fn, options, shouldRetry) {
|
|
|
897
1514
|
throw error;
|
|
898
1515
|
}
|
|
899
1516
|
if (attempt < options.maxAttempts) {
|
|
900
|
-
|
|
1517
|
+
debug(`Attempt ${attempt}/${options.maxAttempts} failed, retrying in ${delay}ms...`);
|
|
901
1518
|
await sleep(delay);
|
|
902
1519
|
delay = Math.floor(delay * options.backoffMultiplier);
|
|
903
1520
|
}
|
|
@@ -923,7 +1540,7 @@ async function runVerifyStage(ctx) {
|
|
|
923
1540
|
attempts: 0
|
|
924
1541
|
};
|
|
925
1542
|
if (cliOptions.dryRun) {
|
|
926
|
-
|
|
1543
|
+
info(`[DRY RUN] Would verify ${pkg.packageName}@${pkg.version} on npm`);
|
|
927
1544
|
result.verified = true;
|
|
928
1545
|
ctx.output.verification.push(result);
|
|
929
1546
|
continue;
|
|
@@ -939,12 +1556,12 @@ async function runVerifyStage(ctx) {
|
|
|
939
1556
|
if (viewResult.exitCode !== 0 || !viewResult.stdout.trim()) {
|
|
940
1557
|
throw new Error(`${pkg.packageName}@${pkg.version} not yet available on npm`);
|
|
941
1558
|
}
|
|
942
|
-
|
|
1559
|
+
debug(`Verified ${pkg.packageName}@${pkg.version} on npm`);
|
|
943
1560
|
}, config.verify.npm);
|
|
944
1561
|
result.verified = true;
|
|
945
|
-
|
|
1562
|
+
success(`Verified ${pkg.packageName}@${pkg.version} on npm`);
|
|
946
1563
|
} catch {
|
|
947
|
-
|
|
1564
|
+
warn(`Failed to verify ${pkg.packageName}@${pkg.version} on npm after ${result.attempts} attempts`);
|
|
948
1565
|
}
|
|
949
1566
|
ctx.output.verification.push(result);
|
|
950
1567
|
}
|
|
@@ -960,7 +1577,7 @@ async function runVerifyStage(ctx) {
|
|
|
960
1577
|
attempts: 0
|
|
961
1578
|
};
|
|
962
1579
|
if (cliOptions.dryRun) {
|
|
963
|
-
|
|
1580
|
+
info(`[DRY RUN] Would verify ${crate.packageName}@${crate.version} on crates.io`);
|
|
964
1581
|
result.verified = true;
|
|
965
1582
|
ctx.output.verification.push(result);
|
|
966
1583
|
continue;
|
|
@@ -972,12 +1589,12 @@ async function runVerifyStage(ctx) {
|
|
|
972
1589
|
if (!response.ok) {
|
|
973
1590
|
throw new Error(`${crate.packageName}@${crate.version} not yet available on crates.io`);
|
|
974
1591
|
}
|
|
975
|
-
|
|
1592
|
+
debug(`Verified ${crate.packageName}@${crate.version} on crates.io`);
|
|
976
1593
|
}, config.verify.cargo);
|
|
977
1594
|
result.verified = true;
|
|
978
|
-
|
|
1595
|
+
success(`Verified ${crate.packageName}@${crate.version} on crates.io`);
|
|
979
1596
|
} catch {
|
|
980
|
-
|
|
1597
|
+
warn(`Failed to verify ${crate.packageName}@${crate.version} on crates.io after ${result.attempts} attempts`);
|
|
981
1598
|
}
|
|
982
1599
|
ctx.output.verification.push(result);
|
|
983
1600
|
}
|
|
@@ -1012,6 +1629,8 @@ async function runPipeline(input, config, options) {
|
|
|
1012
1629
|
cliOptions: options,
|
|
1013
1630
|
packageManager: detectPackageManager(cwd),
|
|
1014
1631
|
cwd,
|
|
1632
|
+
releaseNotes: options.releaseNotes,
|
|
1633
|
+
additionalFiles: options.additionalFiles,
|
|
1015
1634
|
output: {
|
|
1016
1635
|
dryRun: options.dryRun,
|
|
1017
1636
|
git: { committed: false, tags: [], pushed: false },
|
|
@@ -1023,7 +1642,10 @@ async function runPipeline(input, config, options) {
|
|
|
1023
1642
|
};
|
|
1024
1643
|
try {
|
|
1025
1644
|
await runPrepareStage(ctx);
|
|
1026
|
-
if (!options.skipGit) {
|
|
1645
|
+
if (options.skipGitCommit && !options.skipGit) {
|
|
1646
|
+
ctx.output.git.committed = !!input.commitMessage;
|
|
1647
|
+
ctx.output.git.tags = [...input.tags];
|
|
1648
|
+
} else if (!options.skipGit) {
|
|
1027
1649
|
await runGitCommitStage(ctx);
|
|
1028
1650
|
}
|
|
1029
1651
|
if (!options.skipPublish) {
|
|
@@ -1052,41 +1674,40 @@ async function runPipeline(input, config, options) {
|
|
|
1052
1674
|
}
|
|
1053
1675
|
|
|
1054
1676
|
// src/stages/input.ts
|
|
1055
|
-
import * as
|
|
1056
|
-
import {
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
originalType: z.string().optional()
|
|
1677
|
+
import * as fs11 from "fs";
|
|
1678
|
+
import { z as z3 } from "zod";
|
|
1679
|
+
var VersionChangelogEntrySchema = z3.object({
|
|
1680
|
+
type: z3.string(),
|
|
1681
|
+
description: z3.string(),
|
|
1682
|
+
issueIds: z3.array(z3.string()).optional(),
|
|
1683
|
+
scope: z3.string().optional(),
|
|
1684
|
+
originalType: z3.string().optional()
|
|
1064
1685
|
});
|
|
1065
|
-
var VersionPackageChangelogSchema =
|
|
1066
|
-
packageName:
|
|
1067
|
-
version:
|
|
1068
|
-
previousVersion:
|
|
1069
|
-
revisionRange:
|
|
1070
|
-
repoUrl:
|
|
1071
|
-
entries:
|
|
1686
|
+
var VersionPackageChangelogSchema = z3.object({
|
|
1687
|
+
packageName: z3.string(),
|
|
1688
|
+
version: z3.string(),
|
|
1689
|
+
previousVersion: z3.string().nullable(),
|
|
1690
|
+
revisionRange: z3.string(),
|
|
1691
|
+
repoUrl: z3.string().nullable(),
|
|
1692
|
+
entries: z3.array(VersionChangelogEntrySchema)
|
|
1072
1693
|
});
|
|
1073
|
-
var VersionPackageUpdateSchema =
|
|
1074
|
-
packageName:
|
|
1075
|
-
newVersion:
|
|
1076
|
-
filePath:
|
|
1694
|
+
var VersionPackageUpdateSchema = z3.object({
|
|
1695
|
+
packageName: z3.string(),
|
|
1696
|
+
newVersion: z3.string(),
|
|
1697
|
+
filePath: z3.string()
|
|
1077
1698
|
});
|
|
1078
|
-
var VersionOutputSchema =
|
|
1079
|
-
dryRun:
|
|
1080
|
-
updates:
|
|
1081
|
-
changelogs:
|
|
1082
|
-
commitMessage:
|
|
1083
|
-
tags:
|
|
1699
|
+
var VersionOutputSchema = z3.object({
|
|
1700
|
+
dryRun: z3.boolean(),
|
|
1701
|
+
updates: z3.array(VersionPackageUpdateSchema),
|
|
1702
|
+
changelogs: z3.array(VersionPackageChangelogSchema),
|
|
1703
|
+
commitMessage: z3.string().optional(),
|
|
1704
|
+
tags: z3.array(z3.string())
|
|
1084
1705
|
});
|
|
1085
1706
|
async function parseInput(inputPath) {
|
|
1086
1707
|
let raw;
|
|
1087
1708
|
if (inputPath) {
|
|
1088
1709
|
try {
|
|
1089
|
-
raw =
|
|
1710
|
+
raw = fs11.readFileSync(inputPath, "utf-8");
|
|
1090
1711
|
} catch {
|
|
1091
1712
|
throw createPublishError("INPUT_PARSE_ERROR" /* INPUT_PARSE_ERROR */, `Could not read file: ${inputPath}`);
|
|
1092
1713
|
}
|
|
@@ -1106,7 +1727,7 @@ async function parseInput(inputPath) {
|
|
|
1106
1727
|
${issues}`);
|
|
1107
1728
|
}
|
|
1108
1729
|
if (result.data.updates.length === 0) {
|
|
1109
|
-
|
|
1730
|
+
info("No package updates in version output \u2014 pipeline will be a no-op");
|
|
1110
1731
|
}
|
|
1111
1732
|
return result.data;
|
|
1112
1733
|
}
|
|
@@ -1119,7 +1740,11 @@ async function readStdin() {
|
|
|
1119
1740
|
}
|
|
1120
1741
|
|
|
1121
1742
|
export {
|
|
1122
|
-
|
|
1743
|
+
setLogLevel,
|
|
1744
|
+
setJsonMode,
|
|
1745
|
+
EXIT_CODES,
|
|
1746
|
+
parseCargoToml,
|
|
1747
|
+
loadConfig2 as loadConfig,
|
|
1123
1748
|
getDefaultConfig2 as getDefaultConfig,
|
|
1124
1749
|
BasePublishError,
|
|
1125
1750
|
PublishError,
|
|
@@ -1128,7 +1753,6 @@ export {
|
|
|
1128
1753
|
createPublishError,
|
|
1129
1754
|
detectNpmAuth,
|
|
1130
1755
|
hasCargoAuth,
|
|
1131
|
-
parseCargoToml,
|
|
1132
1756
|
updateCargoVersion,
|
|
1133
1757
|
extractPathDeps,
|
|
1134
1758
|
isPrerelease,
|