@releasekit/publish 0.2.0 → 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/README.md +2 -0
- package/dist/{chunk-H7AKSLZP.js → chunk-PJUNQA6B.js} +634 -137
- package/dist/cli.d.ts +9 -0
- package/dist/cli.js +5 -3
- package/dist/index.d.ts +9 -165
- package/dist/index.js +1 -1
- package/package.json +7 -12
- package/dist/cli.cjs +0 -1311
- package/dist/cli.d.cts +0 -1
- package/dist/index.cjs +0 -1322
- package/dist/index.d.cts +0 -165
package/dist/cli.cjs
DELETED
|
@@ -1,1311 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
var __create = Object.create;
|
|
4
|
-
var __defProp = Object.defineProperty;
|
|
5
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
var __copyProps = (to, from, except, desc) => {
|
|
10
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
-
for (let key of __getOwnPropNames(from))
|
|
12
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
-
}
|
|
15
|
-
return to;
|
|
16
|
-
};
|
|
17
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
18
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
19
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
20
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
21
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
22
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
23
|
-
mod
|
|
24
|
-
));
|
|
25
|
-
|
|
26
|
-
// src/cli.ts
|
|
27
|
-
var import_core13 = require("@releasekit/core");
|
|
28
|
-
var import_commander = require("commander");
|
|
29
|
-
|
|
30
|
-
// src/config.ts
|
|
31
|
-
var import_config = require("@releasekit/config");
|
|
32
|
-
|
|
33
|
-
// src/types.ts
|
|
34
|
-
function getDefaultConfig() {
|
|
35
|
-
return {
|
|
36
|
-
npm: {
|
|
37
|
-
enabled: true,
|
|
38
|
-
auth: "auto",
|
|
39
|
-
provenance: true,
|
|
40
|
-
access: "public",
|
|
41
|
-
registry: "https://registry.npmjs.org",
|
|
42
|
-
copyFiles: ["LICENSE"],
|
|
43
|
-
tag: "latest"
|
|
44
|
-
},
|
|
45
|
-
cargo: {
|
|
46
|
-
enabled: false,
|
|
47
|
-
noVerify: false,
|
|
48
|
-
publishOrder: [],
|
|
49
|
-
clean: false
|
|
50
|
-
},
|
|
51
|
-
git: {
|
|
52
|
-
push: true,
|
|
53
|
-
pushMethod: "auto",
|
|
54
|
-
remote: "origin",
|
|
55
|
-
branch: "main",
|
|
56
|
-
httpsTokenEnv: void 0,
|
|
57
|
-
skipHooks: false
|
|
58
|
-
},
|
|
59
|
-
githubRelease: {
|
|
60
|
-
enabled: true,
|
|
61
|
-
draft: true,
|
|
62
|
-
generateNotes: true,
|
|
63
|
-
perPackage: false,
|
|
64
|
-
prerelease: "auto"
|
|
65
|
-
},
|
|
66
|
-
verify: {
|
|
67
|
-
npm: {
|
|
68
|
-
enabled: true,
|
|
69
|
-
maxAttempts: 5,
|
|
70
|
-
initialDelay: 15e3,
|
|
71
|
-
backoffMultiplier: 2
|
|
72
|
-
},
|
|
73
|
-
cargo: {
|
|
74
|
-
enabled: true,
|
|
75
|
-
maxAttempts: 10,
|
|
76
|
-
initialDelay: 3e4,
|
|
77
|
-
backoffMultiplier: 2
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
function toPublishConfig(config) {
|
|
83
|
-
const defaults = getDefaultConfig();
|
|
84
|
-
if (!config) return defaults;
|
|
85
|
-
return {
|
|
86
|
-
npm: {
|
|
87
|
-
enabled: config.npm?.enabled ?? defaults.npm.enabled,
|
|
88
|
-
auth: config.npm?.auth ?? defaults.npm.auth,
|
|
89
|
-
provenance: config.npm?.provenance ?? defaults.npm.provenance,
|
|
90
|
-
access: config.npm?.access ?? defaults.npm.access,
|
|
91
|
-
registry: config.npm?.registry ?? defaults.npm.registry,
|
|
92
|
-
copyFiles: config.npm?.copyFiles ?? defaults.npm.copyFiles,
|
|
93
|
-
tag: config.npm?.tag ?? defaults.npm.tag
|
|
94
|
-
},
|
|
95
|
-
cargo: {
|
|
96
|
-
enabled: config.cargo?.enabled ?? defaults.cargo.enabled,
|
|
97
|
-
noVerify: config.cargo?.noVerify ?? defaults.cargo.noVerify,
|
|
98
|
-
publishOrder: config.cargo?.publishOrder ?? defaults.cargo.publishOrder,
|
|
99
|
-
clean: config.cargo?.clean ?? defaults.cargo.clean
|
|
100
|
-
},
|
|
101
|
-
git: config.git ? {
|
|
102
|
-
push: config.git.push ?? defaults.git.push,
|
|
103
|
-
pushMethod: config.git.pushMethod ?? defaults.git.pushMethod,
|
|
104
|
-
remote: config.git.remote ?? defaults.git.remote,
|
|
105
|
-
branch: config.git.branch ?? defaults.git.branch,
|
|
106
|
-
httpsTokenEnv: config.git.httpsTokenEnv ?? defaults.git.httpsTokenEnv,
|
|
107
|
-
skipHooks: config.git.skipHooks ?? defaults.git.skipHooks
|
|
108
|
-
} : defaults.git,
|
|
109
|
-
githubRelease: {
|
|
110
|
-
enabled: config.githubRelease?.enabled ?? defaults.githubRelease.enabled,
|
|
111
|
-
draft: config.githubRelease?.draft ?? defaults.githubRelease.draft,
|
|
112
|
-
generateNotes: config.githubRelease?.generateNotes ?? defaults.githubRelease.generateNotes,
|
|
113
|
-
perPackage: config.githubRelease?.perPackage ?? defaults.githubRelease.perPackage,
|
|
114
|
-
prerelease: config.githubRelease?.prerelease ?? defaults.githubRelease.prerelease,
|
|
115
|
-
notesFile: config.githubRelease?.notesFile
|
|
116
|
-
},
|
|
117
|
-
verify: {
|
|
118
|
-
npm: {
|
|
119
|
-
enabled: config.verify?.npm?.enabled ?? defaults.verify.npm.enabled,
|
|
120
|
-
maxAttempts: config.verify?.npm?.maxAttempts ?? defaults.verify.npm.maxAttempts,
|
|
121
|
-
initialDelay: config.verify?.npm?.initialDelay ?? defaults.verify.npm.initialDelay,
|
|
122
|
-
backoffMultiplier: config.verify?.npm?.backoffMultiplier ?? defaults.verify.npm.backoffMultiplier
|
|
123
|
-
},
|
|
124
|
-
cargo: {
|
|
125
|
-
enabled: config.verify?.cargo?.enabled ?? defaults.verify.cargo.enabled,
|
|
126
|
-
maxAttempts: config.verify?.cargo?.maxAttempts ?? defaults.verify.cargo.maxAttempts,
|
|
127
|
-
initialDelay: config.verify?.cargo?.initialDelay ?? defaults.verify.cargo.initialDelay,
|
|
128
|
-
backoffMultiplier: config.verify?.cargo?.backoffMultiplier ?? defaults.verify.cargo.backoffMultiplier
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// src/config.ts
|
|
135
|
-
function loadConfig(options) {
|
|
136
|
-
const baseConfig = (0, import_config.loadPublishConfig)(options);
|
|
137
|
-
return toPublishConfig(baseConfig);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// src/errors/index.ts
|
|
141
|
-
var import_core = require("@releasekit/core");
|
|
142
|
-
var BasePublishError = class _BasePublishError extends import_core.ReleaseKitError {
|
|
143
|
-
code;
|
|
144
|
-
suggestions;
|
|
145
|
-
constructor(message, code, suggestions) {
|
|
146
|
-
super(message);
|
|
147
|
-
this.code = code;
|
|
148
|
-
this.suggestions = suggestions ?? [];
|
|
149
|
-
}
|
|
150
|
-
static isPublishError(error) {
|
|
151
|
-
return error instanceof _BasePublishError;
|
|
152
|
-
}
|
|
153
|
-
};
|
|
154
|
-
var PublishError = class extends BasePublishError {
|
|
155
|
-
};
|
|
156
|
-
var PipelineError = class extends BasePublishError {
|
|
157
|
-
partialOutput;
|
|
158
|
-
failedStage;
|
|
159
|
-
cause;
|
|
160
|
-
constructor(message, failedStage, partialOutput, cause) {
|
|
161
|
-
super(message, "PIPELINE_STAGE_ERROR" /* PIPELINE_STAGE_ERROR */, [
|
|
162
|
-
"Check the partial output for results from stages that completed before the failure",
|
|
163
|
-
"Use --json to get structured error output with partial results"
|
|
164
|
-
]);
|
|
165
|
-
this.failedStage = failedStage;
|
|
166
|
-
this.partialOutput = partialOutput;
|
|
167
|
-
this.cause = cause;
|
|
168
|
-
}
|
|
169
|
-
};
|
|
170
|
-
function createPublishError(code, details) {
|
|
171
|
-
const messages = {
|
|
172
|
-
["INPUT_PARSE_ERROR" /* INPUT_PARSE_ERROR */]: "Failed to parse version output",
|
|
173
|
-
["INPUT_VALIDATION_ERROR" /* INPUT_VALIDATION_ERROR */]: "Version output validation failed",
|
|
174
|
-
["CONFIG_ERROR" /* CONFIG_ERROR */]: "Invalid publish configuration",
|
|
175
|
-
["GIT_COMMIT_ERROR" /* GIT_COMMIT_ERROR */]: "Failed to create git commit",
|
|
176
|
-
["GIT_TAG_ERROR" /* GIT_TAG_ERROR */]: "Failed to create git tag",
|
|
177
|
-
["GIT_PUSH_ERROR" /* GIT_PUSH_ERROR */]: "Failed to push to remote",
|
|
178
|
-
["NPM_PUBLISH_ERROR" /* NPM_PUBLISH_ERROR */]: "Failed to publish to npm",
|
|
179
|
-
["NPM_AUTH_ERROR" /* NPM_AUTH_ERROR */]: "NPM authentication failed",
|
|
180
|
-
["CARGO_PUBLISH_ERROR" /* CARGO_PUBLISH_ERROR */]: "Failed to publish to crates.io",
|
|
181
|
-
["CARGO_AUTH_ERROR" /* CARGO_AUTH_ERROR */]: "Cargo authentication failed",
|
|
182
|
-
["VERIFICATION_FAILED" /* VERIFICATION_FAILED */]: "Package verification failed",
|
|
183
|
-
["GITHUB_RELEASE_ERROR" /* GITHUB_RELEASE_ERROR */]: "Failed to create GitHub release",
|
|
184
|
-
["FILE_COPY_ERROR" /* FILE_COPY_ERROR */]: "Failed to copy files",
|
|
185
|
-
["CARGO_TOML_ERROR" /* CARGO_TOML_ERROR */]: "Failed to update Cargo.toml",
|
|
186
|
-
["PIPELINE_STAGE_ERROR" /* PIPELINE_STAGE_ERROR */]: "Pipeline stage failed"
|
|
187
|
-
};
|
|
188
|
-
const suggestions = {
|
|
189
|
-
["INPUT_PARSE_ERROR" /* INPUT_PARSE_ERROR */]: [
|
|
190
|
-
"Ensure the input is valid JSON from @releasekit/version --json",
|
|
191
|
-
"Check that stdin is piped correctly or --input path is valid"
|
|
192
|
-
],
|
|
193
|
-
["INPUT_VALIDATION_ERROR" /* INPUT_VALIDATION_ERROR */]: [
|
|
194
|
-
"Ensure the input matches the expected VersionOutput schema",
|
|
195
|
-
"Run @releasekit/version with --json to generate valid output"
|
|
196
|
-
],
|
|
197
|
-
["CONFIG_ERROR" /* CONFIG_ERROR */]: [
|
|
198
|
-
"Validate publish.config.json syntax",
|
|
199
|
-
"Check configuration against the schema",
|
|
200
|
-
"Review documentation for valid configuration options"
|
|
201
|
-
],
|
|
202
|
-
["GIT_COMMIT_ERROR" /* GIT_COMMIT_ERROR */]: [
|
|
203
|
-
"Ensure there are staged changes to commit",
|
|
204
|
-
"Check git user.name and user.email are configured",
|
|
205
|
-
"Verify you have write access to the repository"
|
|
206
|
-
],
|
|
207
|
-
["GIT_TAG_ERROR" /* GIT_TAG_ERROR */]: [
|
|
208
|
-
"Check if the tag already exists: git tag -l <tag>",
|
|
209
|
-
"Delete existing tag if needed: git tag -d <tag>"
|
|
210
|
-
],
|
|
211
|
-
["GIT_PUSH_ERROR" /* GIT_PUSH_ERROR */]: [
|
|
212
|
-
"Verify remote repository access",
|
|
213
|
-
"Check SSH key or deploy key configuration",
|
|
214
|
-
"Ensure the branch is not protected or you have push access"
|
|
215
|
-
],
|
|
216
|
-
["NPM_PUBLISH_ERROR" /* NPM_PUBLISH_ERROR */]: [
|
|
217
|
-
"Check npm registry availability",
|
|
218
|
-
"Verify package name is not already taken by another owner",
|
|
219
|
-
"Ensure package version has not already been published"
|
|
220
|
-
],
|
|
221
|
-
["NPM_AUTH_ERROR" /* NPM_AUTH_ERROR */]: [
|
|
222
|
-
"Set NPM_TOKEN environment variable for token-based auth",
|
|
223
|
-
"Enable OIDC trusted publishing in GitHub Actions for provenance",
|
|
224
|
-
"Run npm login for local publishing"
|
|
225
|
-
],
|
|
226
|
-
["CARGO_PUBLISH_ERROR" /* CARGO_PUBLISH_ERROR */]: [
|
|
227
|
-
"Check crates.io registry availability",
|
|
228
|
-
"Verify crate name ownership on crates.io",
|
|
229
|
-
"Ensure Cargo.toml metadata is complete (description, license, etc.)"
|
|
230
|
-
],
|
|
231
|
-
["CARGO_AUTH_ERROR" /* CARGO_AUTH_ERROR */]: [
|
|
232
|
-
"Set CARGO_REGISTRY_TOKEN environment variable",
|
|
233
|
-
"Generate a token at https://crates.io/settings/tokens"
|
|
234
|
-
],
|
|
235
|
-
["VERIFICATION_FAILED" /* VERIFICATION_FAILED */]: [
|
|
236
|
-
"Registry propagation may take longer than expected",
|
|
237
|
-
"Try increasing verify.maxAttempts or verify.initialDelay in config",
|
|
238
|
-
"Check registry status pages for outages"
|
|
239
|
-
],
|
|
240
|
-
["GITHUB_RELEASE_ERROR" /* GITHUB_RELEASE_ERROR */]: [
|
|
241
|
-
"Ensure gh CLI is installed and authenticated",
|
|
242
|
-
"Verify GITHUB_TOKEN has contents:write permission",
|
|
243
|
-
"Check that the tag exists in the remote repository"
|
|
244
|
-
],
|
|
245
|
-
["FILE_COPY_ERROR" /* FILE_COPY_ERROR */]: ["Verify the source file exists in the project root", "Check file permissions"],
|
|
246
|
-
["CARGO_TOML_ERROR" /* CARGO_TOML_ERROR */]: [
|
|
247
|
-
"Ensure Cargo.toml exists and is valid TOML",
|
|
248
|
-
"Check that the [package] section has a version field"
|
|
249
|
-
],
|
|
250
|
-
["PIPELINE_STAGE_ERROR" /* PIPELINE_STAGE_ERROR */]: [
|
|
251
|
-
"Check the partial output for results from stages that completed before the failure",
|
|
252
|
-
"Use --json to get structured error output with partial results"
|
|
253
|
-
]
|
|
254
|
-
};
|
|
255
|
-
const baseMessage = messages[code];
|
|
256
|
-
const fullMessage = details ? `${baseMessage}: ${details}` : baseMessage;
|
|
257
|
-
return new PublishError(fullMessage, code, suggestions[code]);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
// src/stages/cargo-publish.ts
|
|
261
|
-
var fs2 = __toESM(require("fs"), 1);
|
|
262
|
-
var path = __toESM(require("path"), 1);
|
|
263
|
-
var import_core3 = require("@releasekit/core");
|
|
264
|
-
|
|
265
|
-
// src/utils/exec.ts
|
|
266
|
-
var import_node_child_process = require("child_process");
|
|
267
|
-
var import_core2 = require("@releasekit/core");
|
|
268
|
-
function redactArg(arg) {
|
|
269
|
-
try {
|
|
270
|
-
const url = new URL(arg);
|
|
271
|
-
if (url.username || url.password) {
|
|
272
|
-
url.username = url.username ? "***" : "";
|
|
273
|
-
url.password = url.password ? "***" : "";
|
|
274
|
-
return url.toString();
|
|
275
|
-
}
|
|
276
|
-
} catch {
|
|
277
|
-
}
|
|
278
|
-
return arg;
|
|
279
|
-
}
|
|
280
|
-
async function execCommand(file, args, options = {}) {
|
|
281
|
-
const displayCommand = options.label ?? [file, ...args.map(redactArg)].join(" ");
|
|
282
|
-
if (options.dryRun) {
|
|
283
|
-
(0, import_core2.info)(`[DRY RUN] Would execute: ${displayCommand}`);
|
|
284
|
-
return { stdout: "", stderr: "", exitCode: 0 };
|
|
285
|
-
}
|
|
286
|
-
(0, import_core2.debug)(`Executing: ${displayCommand}`);
|
|
287
|
-
return new Promise((resolve5, reject) => {
|
|
288
|
-
(0, import_node_child_process.execFile)(
|
|
289
|
-
file,
|
|
290
|
-
args,
|
|
291
|
-
{
|
|
292
|
-
maxBuffer: 1024 * 1024 * 10,
|
|
293
|
-
cwd: options.cwd,
|
|
294
|
-
env: options.env ? { ...process.env, ...options.env } : void 0
|
|
295
|
-
},
|
|
296
|
-
(error, stdout, stderr) => {
|
|
297
|
-
if (error) {
|
|
298
|
-
reject(
|
|
299
|
-
Object.assign(new Error(error.message), {
|
|
300
|
-
stdout: stdout.toString(),
|
|
301
|
-
stderr: stderr.toString(),
|
|
302
|
-
exitCode: error.code ?? 1
|
|
303
|
-
})
|
|
304
|
-
);
|
|
305
|
-
} else {
|
|
306
|
-
resolve5({
|
|
307
|
-
stdout: stdout.toString(),
|
|
308
|
-
stderr: stderr.toString(),
|
|
309
|
-
exitCode: 0
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
);
|
|
314
|
-
});
|
|
315
|
-
}
|
|
316
|
-
async function execCommandSafe(file, args, options = {}) {
|
|
317
|
-
try {
|
|
318
|
-
return await execCommand(file, args, options);
|
|
319
|
-
} catch (error) {
|
|
320
|
-
if (error && typeof error === "object" && "stdout" in error) {
|
|
321
|
-
const execError = error;
|
|
322
|
-
return {
|
|
323
|
-
stdout: execError.stdout ?? "",
|
|
324
|
-
stderr: execError.stderr ?? "",
|
|
325
|
-
exitCode: execError.exitCode ?? 1
|
|
326
|
-
};
|
|
327
|
-
}
|
|
328
|
-
return { stdout: "", stderr: error instanceof Error ? error.message : String(error), exitCode: 1 };
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
// src/utils/auth.ts
|
|
333
|
-
function detectNpmAuth() {
|
|
334
|
-
if (process.env.ACTIONS_ID_TOKEN_REQUEST_URL) {
|
|
335
|
-
return "oidc";
|
|
336
|
-
}
|
|
337
|
-
if (process.env.NPM_TOKEN || process.env.NODE_AUTH_TOKEN) {
|
|
338
|
-
return "token";
|
|
339
|
-
}
|
|
340
|
-
return null;
|
|
341
|
-
}
|
|
342
|
-
function hasCargoAuth() {
|
|
343
|
-
return !!process.env.CARGO_REGISTRY_TOKEN;
|
|
344
|
-
}
|
|
345
|
-
async function detectGitPushMethod(remote, cwd) {
|
|
346
|
-
const result = await execCommand("git", ["remote", "get-url", remote], { cwd });
|
|
347
|
-
const url = result.stdout.trim();
|
|
348
|
-
if (url.startsWith("git@") || url.startsWith("ssh://")) {
|
|
349
|
-
return "ssh";
|
|
350
|
-
}
|
|
351
|
-
return "https";
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
// src/utils/cargo.ts
|
|
355
|
-
var fs = __toESM(require("fs"), 1);
|
|
356
|
-
var import_config2 = require("@releasekit/config");
|
|
357
|
-
var TOML = __toESM(require("smol-toml"), 1);
|
|
358
|
-
function updateCargoVersion(cargoPath, newVersion) {
|
|
359
|
-
try {
|
|
360
|
-
const cargo = (0, import_config2.parseCargoToml)(cargoPath);
|
|
361
|
-
if (cargo.package) {
|
|
362
|
-
cargo.package.version = newVersion;
|
|
363
|
-
fs.writeFileSync(cargoPath, TOML.stringify(cargo));
|
|
364
|
-
}
|
|
365
|
-
} catch (error) {
|
|
366
|
-
throw createPublishError(
|
|
367
|
-
"CARGO_TOML_ERROR" /* CARGO_TOML_ERROR */,
|
|
368
|
-
`${cargoPath}: ${error instanceof Error ? error.message : String(error)}`
|
|
369
|
-
);
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
function extractPathDeps(manifest) {
|
|
373
|
-
const pathDeps = [];
|
|
374
|
-
const deps = manifest.dependencies;
|
|
375
|
-
if (deps) {
|
|
376
|
-
for (const dep of Object.values(deps)) {
|
|
377
|
-
if (dep && typeof dep === "object" && "path" in dep) {
|
|
378
|
-
pathDeps.push(dep.path);
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
return pathDeps;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
// src/stages/cargo-publish.ts
|
|
386
|
-
async function runCargoPublishStage(ctx) {
|
|
387
|
-
const { input, config, cliOptions, cwd } = ctx;
|
|
388
|
-
const dryRun = cliOptions.dryRun;
|
|
389
|
-
if (!config.cargo.enabled) {
|
|
390
|
-
(0, import_core3.debug)("Cargo publishing disabled in config");
|
|
391
|
-
return;
|
|
392
|
-
}
|
|
393
|
-
if (!hasCargoAuth() && !dryRun) {
|
|
394
|
-
throw createPublishError("CARGO_AUTH_ERROR" /* CARGO_AUTH_ERROR */, "CARGO_REGISTRY_TOKEN not set");
|
|
395
|
-
}
|
|
396
|
-
const crates = findCrates(
|
|
397
|
-
input.updates.map((u) => ({ dir: path.dirname(path.resolve(cwd, u.filePath)), ...u })),
|
|
398
|
-
cwd
|
|
399
|
-
);
|
|
400
|
-
if (crates.length === 0) {
|
|
401
|
-
(0, import_core3.debug)("No Cargo crates found to publish");
|
|
402
|
-
return;
|
|
403
|
-
}
|
|
404
|
-
const ordered = orderCrates(crates, config.cargo.publishOrder);
|
|
405
|
-
for (const crate of ordered) {
|
|
406
|
-
const result = {
|
|
407
|
-
packageName: crate.name,
|
|
408
|
-
version: crate.version,
|
|
409
|
-
registry: "cargo",
|
|
410
|
-
success: false,
|
|
411
|
-
skipped: false
|
|
412
|
-
};
|
|
413
|
-
const searchResult = await execCommandSafe("cargo", ["search", crate.name, "--limit", "1"], { cwd, dryRun: false });
|
|
414
|
-
if (searchResult.exitCode === 0 && searchResult.stdout.includes(`"${crate.version}"`)) {
|
|
415
|
-
result.alreadyPublished = true;
|
|
416
|
-
result.skipped = true;
|
|
417
|
-
result.success = true;
|
|
418
|
-
result.reason = "Already published on crates.io";
|
|
419
|
-
ctx.output.cargo.push(result);
|
|
420
|
-
(0, import_core3.warn)(`${crate.name}@${crate.version} is already published on crates.io, skipping`);
|
|
421
|
-
continue;
|
|
422
|
-
}
|
|
423
|
-
if (config.cargo.clean) {
|
|
424
|
-
await execCommand("cargo", ["clean"], { cwd: crate.dir, dryRun, label: `cargo clean (${crate.name})` });
|
|
425
|
-
}
|
|
426
|
-
const publishArgs = ["publish", "--manifest-path", crate.manifestPath];
|
|
427
|
-
if (config.cargo.noVerify) {
|
|
428
|
-
publishArgs.push("--no-verify");
|
|
429
|
-
}
|
|
430
|
-
try {
|
|
431
|
-
await execCommand("cargo", publishArgs, {
|
|
432
|
-
cwd,
|
|
433
|
-
dryRun,
|
|
434
|
-
label: `cargo publish ${crate.name}@${crate.version}`
|
|
435
|
-
});
|
|
436
|
-
result.success = true;
|
|
437
|
-
if (!dryRun) {
|
|
438
|
-
(0, import_core3.success)(`Published ${crate.name}@${crate.version} to crates.io`);
|
|
439
|
-
}
|
|
440
|
-
} catch (error) {
|
|
441
|
-
result.reason = error instanceof Error ? error.message : String(error);
|
|
442
|
-
(0, import_core3.warn)(`Failed to publish ${crate.name}: ${result.reason}`);
|
|
443
|
-
}
|
|
444
|
-
ctx.output.cargo.push(result);
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
function findCrates(updates, _cwd) {
|
|
448
|
-
const crates = [];
|
|
449
|
-
for (const update of updates) {
|
|
450
|
-
const cargoPath = path.join(update.dir, "Cargo.toml");
|
|
451
|
-
if (!fs2.existsSync(cargoPath)) {
|
|
452
|
-
continue;
|
|
453
|
-
}
|
|
454
|
-
try {
|
|
455
|
-
const cargo = (0, import_config2.parseCargoToml)(cargoPath);
|
|
456
|
-
if (!cargo.package?.name) {
|
|
457
|
-
continue;
|
|
458
|
-
}
|
|
459
|
-
const pathDeps = extractPathDeps(cargo);
|
|
460
|
-
crates.push({
|
|
461
|
-
name: cargo.package.name,
|
|
462
|
-
version: update.newVersion,
|
|
463
|
-
dir: update.dir,
|
|
464
|
-
manifestPath: cargoPath,
|
|
465
|
-
pathDeps
|
|
466
|
-
});
|
|
467
|
-
} catch {
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
return crates;
|
|
471
|
-
}
|
|
472
|
-
function orderCrates(crates, explicitOrder) {
|
|
473
|
-
if (explicitOrder.length > 0) {
|
|
474
|
-
const ordered = [];
|
|
475
|
-
const byName = new Map(crates.map((c) => [c.name, c]));
|
|
476
|
-
for (const name of explicitOrder) {
|
|
477
|
-
const crate = byName.get(name);
|
|
478
|
-
if (crate) {
|
|
479
|
-
ordered.push(crate);
|
|
480
|
-
byName.delete(name);
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
for (const crate of byName.values()) {
|
|
484
|
-
ordered.push(crate);
|
|
485
|
-
}
|
|
486
|
-
return ordered;
|
|
487
|
-
}
|
|
488
|
-
return topologicalSort(crates);
|
|
489
|
-
}
|
|
490
|
-
function topologicalSort(crates) {
|
|
491
|
-
const nameSet = new Set(crates.map((c) => c.name));
|
|
492
|
-
const graph = /* @__PURE__ */ new Map();
|
|
493
|
-
const crateMap = new Map(crates.map((c) => [c.name, c]));
|
|
494
|
-
for (const crate of crates) {
|
|
495
|
-
graph.set(crate.name, []);
|
|
496
|
-
}
|
|
497
|
-
for (const crate of crates) {
|
|
498
|
-
for (const depPath of crate.pathDeps) {
|
|
499
|
-
const resolvedDir = path.resolve(crate.dir, depPath);
|
|
500
|
-
for (const other of crates) {
|
|
501
|
-
if (path.resolve(other.dir) === resolvedDir && nameSet.has(other.name)) {
|
|
502
|
-
graph.get(crate.name)?.push(other.name);
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
const inDegree = /* @__PURE__ */ new Map();
|
|
508
|
-
for (const name of nameSet) {
|
|
509
|
-
inDegree.set(name, 0);
|
|
510
|
-
}
|
|
511
|
-
for (const deps of graph.values()) {
|
|
512
|
-
for (const dep of deps) {
|
|
513
|
-
inDegree.set(dep, (inDegree.get(dep) ?? 0) + 1);
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
const queue = [];
|
|
517
|
-
for (const [name, degree] of inDegree) {
|
|
518
|
-
if (degree === 0) {
|
|
519
|
-
queue.push(name);
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
const result = [];
|
|
523
|
-
while (queue.length > 0) {
|
|
524
|
-
const name = queue.shift();
|
|
525
|
-
if (!name) break;
|
|
526
|
-
const crate = crateMap.get(name);
|
|
527
|
-
if (crate) {
|
|
528
|
-
result.push(crate);
|
|
529
|
-
}
|
|
530
|
-
for (const dep of graph.get(name) ?? []) {
|
|
531
|
-
const newDegree = (inDegree.get(dep) ?? 1) - 1;
|
|
532
|
-
inDegree.set(dep, newDegree);
|
|
533
|
-
if (newDegree === 0) {
|
|
534
|
-
queue.push(dep);
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
result.reverse();
|
|
539
|
-
return result;
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
// src/stages/git-commit.ts
|
|
543
|
-
var path2 = __toESM(require("path"), 1);
|
|
544
|
-
var import_core4 = require("@releasekit/core");
|
|
545
|
-
async function runGitCommitStage(ctx) {
|
|
546
|
-
const { input, config, cliOptions, cwd } = ctx;
|
|
547
|
-
const dryRun = cliOptions.dryRun;
|
|
548
|
-
const skipHooks = config.git.skipHooks ?? false;
|
|
549
|
-
if (!input.commitMessage) {
|
|
550
|
-
(0, import_core4.info)("No commit message provided, skipping git commit");
|
|
551
|
-
return;
|
|
552
|
-
}
|
|
553
|
-
const filePaths = input.updates.map((u) => path2.resolve(cwd, u.filePath));
|
|
554
|
-
if (filePaths.length === 0) {
|
|
555
|
-
(0, import_core4.info)("No files to commit");
|
|
556
|
-
return;
|
|
557
|
-
}
|
|
558
|
-
try {
|
|
559
|
-
await execCommand("git", ["add", ...filePaths], {
|
|
560
|
-
cwd,
|
|
561
|
-
dryRun,
|
|
562
|
-
label: `git add ${filePaths.length} file(s)`
|
|
563
|
-
});
|
|
564
|
-
} catch (error) {
|
|
565
|
-
throw createPublishError(
|
|
566
|
-
"GIT_COMMIT_ERROR" /* GIT_COMMIT_ERROR */,
|
|
567
|
-
`git add failed: ${error instanceof Error ? error.message : String(error)}`
|
|
568
|
-
);
|
|
569
|
-
}
|
|
570
|
-
const commitArgs = ["commit"];
|
|
571
|
-
if (skipHooks) {
|
|
572
|
-
commitArgs.push("--no-verify");
|
|
573
|
-
}
|
|
574
|
-
commitArgs.push("-m", input.commitMessage);
|
|
575
|
-
try {
|
|
576
|
-
await execCommand("git", commitArgs, {
|
|
577
|
-
cwd,
|
|
578
|
-
dryRun,
|
|
579
|
-
label: `git commit -m "${input.commitMessage}"`
|
|
580
|
-
});
|
|
581
|
-
ctx.output.git.committed = true;
|
|
582
|
-
if (!dryRun) {
|
|
583
|
-
(0, import_core4.success)("Created git commit");
|
|
584
|
-
}
|
|
585
|
-
} catch (error) {
|
|
586
|
-
throw createPublishError(
|
|
587
|
-
"GIT_COMMIT_ERROR" /* GIT_COMMIT_ERROR */,
|
|
588
|
-
`git commit failed: ${error instanceof Error ? error.message : String(error)}`
|
|
589
|
-
);
|
|
590
|
-
}
|
|
591
|
-
for (const tag of input.tags) {
|
|
592
|
-
try {
|
|
593
|
-
const tagMessage = `Release ${tag}`;
|
|
594
|
-
await execCommand("git", ["tag", "-a", tag, "-m", tagMessage], {
|
|
595
|
-
cwd,
|
|
596
|
-
dryRun,
|
|
597
|
-
label: `git tag ${tag}`
|
|
598
|
-
});
|
|
599
|
-
ctx.output.git.tags.push(tag);
|
|
600
|
-
if (!dryRun) {
|
|
601
|
-
(0, import_core4.success)(`Created tag: ${tag}`);
|
|
602
|
-
}
|
|
603
|
-
} catch (error) {
|
|
604
|
-
throw createPublishError(
|
|
605
|
-
"GIT_TAG_ERROR" /* GIT_TAG_ERROR */,
|
|
606
|
-
`Failed to create tag ${tag}: ${error instanceof Error ? error.message : String(error)}`
|
|
607
|
-
);
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
// src/stages/git-push.ts
|
|
613
|
-
var import_core5 = require("@releasekit/core");
|
|
614
|
-
function toGithubAuthedUrl(remoteUrl, token) {
|
|
615
|
-
try {
|
|
616
|
-
const url = new URL(remoteUrl);
|
|
617
|
-
if (url.protocol !== "https:") return void 0;
|
|
618
|
-
if (url.host !== "github.com") return void 0;
|
|
619
|
-
url.username = "x-access-token";
|
|
620
|
-
url.password = token;
|
|
621
|
-
return url.toString();
|
|
622
|
-
} catch {
|
|
623
|
-
return void 0;
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
async function runGitPushStage(ctx) {
|
|
627
|
-
const { config, cliOptions, cwd, output } = ctx;
|
|
628
|
-
const dryRun = cliOptions.dryRun;
|
|
629
|
-
if (!config.git.push) {
|
|
630
|
-
(0, import_core5.info)("Git push disabled in config, skipping");
|
|
631
|
-
return;
|
|
632
|
-
}
|
|
633
|
-
if (!output.git.committed && output.git.tags.length === 0) {
|
|
634
|
-
(0, import_core5.info)("Nothing to push (no commits or tags created)");
|
|
635
|
-
return;
|
|
636
|
-
}
|
|
637
|
-
const { remote, branch } = config.git;
|
|
638
|
-
let pushMethod = config.git.pushMethod;
|
|
639
|
-
if (pushMethod === "auto") {
|
|
640
|
-
try {
|
|
641
|
-
pushMethod = await detectGitPushMethod(remote, cwd);
|
|
642
|
-
} catch {
|
|
643
|
-
pushMethod = "https";
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
const httpsTokenEnv = config.git.httpsTokenEnv;
|
|
647
|
-
const httpsToken = httpsTokenEnv ? process.env[httpsTokenEnv] : void 0;
|
|
648
|
-
try {
|
|
649
|
-
let pushRemote = remote;
|
|
650
|
-
if (pushMethod === "https" && httpsToken) {
|
|
651
|
-
const remoteUrlResult = await execCommand("git", ["remote", "get-url", remote], { cwd, dryRun: false });
|
|
652
|
-
const authed = toGithubAuthedUrl(remoteUrlResult.stdout.trim(), httpsToken);
|
|
653
|
-
if (authed) {
|
|
654
|
-
pushRemote = authed;
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
if (output.git.committed) {
|
|
658
|
-
await execCommand("git", ["push", pushRemote, branch], {
|
|
659
|
-
cwd,
|
|
660
|
-
dryRun,
|
|
661
|
-
label: `git push ${remote} ${branch}`
|
|
662
|
-
});
|
|
663
|
-
}
|
|
664
|
-
if (output.git.tags.length > 0) {
|
|
665
|
-
await execCommand("git", ["push", pushRemote, "--tags"], {
|
|
666
|
-
cwd,
|
|
667
|
-
dryRun,
|
|
668
|
-
label: `git push ${remote} --tags`
|
|
669
|
-
});
|
|
670
|
-
}
|
|
671
|
-
ctx.output.git.pushed = true;
|
|
672
|
-
if (!dryRun) {
|
|
673
|
-
(0, import_core5.success)(`Pushed to ${remote}/${branch}`);
|
|
674
|
-
}
|
|
675
|
-
} catch (error) {
|
|
676
|
-
throw createPublishError(
|
|
677
|
-
"GIT_PUSH_ERROR" /* GIT_PUSH_ERROR */,
|
|
678
|
-
`${error instanceof Error ? error.message : String(error)}`
|
|
679
|
-
);
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
// src/stages/github-release.ts
|
|
684
|
-
var fs3 = __toESM(require("fs"), 1);
|
|
685
|
-
var import_core6 = require("@releasekit/core");
|
|
686
|
-
|
|
687
|
-
// src/utils/semver.ts
|
|
688
|
-
var import_semver = __toESM(require("semver"), 1);
|
|
689
|
-
function isPrerelease(version) {
|
|
690
|
-
return import_semver.default.prerelease(version) !== null;
|
|
691
|
-
}
|
|
692
|
-
function getDistTag(version, defaultTag = "latest") {
|
|
693
|
-
const pre = import_semver.default.prerelease(version);
|
|
694
|
-
if (pre && pre.length > 0) {
|
|
695
|
-
const identifier = pre[0];
|
|
696
|
-
return typeof identifier === "string" ? identifier : "next";
|
|
697
|
-
}
|
|
698
|
-
return defaultTag;
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
// src/stages/github-release.ts
|
|
702
|
-
async function runGithubReleaseStage(ctx) {
|
|
703
|
-
const { config, cliOptions, output } = ctx;
|
|
704
|
-
const dryRun = cliOptions.dryRun;
|
|
705
|
-
if (!config.githubRelease.enabled) {
|
|
706
|
-
(0, import_core6.debug)("GitHub releases disabled in config");
|
|
707
|
-
return;
|
|
708
|
-
}
|
|
709
|
-
const tags = output.git.tags.length > 0 ? output.git.tags : ctx.input.tags;
|
|
710
|
-
if (tags.length === 0) {
|
|
711
|
-
(0, import_core6.info)("No tags available for GitHub release");
|
|
712
|
-
return;
|
|
713
|
-
}
|
|
714
|
-
let notesBody;
|
|
715
|
-
if (config.githubRelease.notesFile) {
|
|
716
|
-
try {
|
|
717
|
-
notesBody = fs3.readFileSync(config.githubRelease.notesFile, "utf-8");
|
|
718
|
-
} catch {
|
|
719
|
-
(0, import_core6.debug)(`Could not read notes file: ${config.githubRelease.notesFile}`);
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
|
-
const firstTag = tags[0];
|
|
723
|
-
if (!firstTag) return;
|
|
724
|
-
const tagsToRelease = config.githubRelease.perPackage ? tags : [firstTag];
|
|
725
|
-
for (const tag of tagsToRelease) {
|
|
726
|
-
const MAX_TAG_LENGTH = 1e3;
|
|
727
|
-
const truncatedTag = tag.length > MAX_TAG_LENGTH ? tag.slice(0, MAX_TAG_LENGTH) : tag;
|
|
728
|
-
const versionMatch = truncatedTag.match(/(\d{1,20}\.\d{1,20}\.\d{1,20}(?:[-+.]?[a-zA-Z0-9.-]{0,100})?)$/);
|
|
729
|
-
const version = versionMatch?.[1] ?? "";
|
|
730
|
-
const isPreRel = config.githubRelease.prerelease === "auto" ? version ? isPrerelease(version) : false : config.githubRelease.prerelease;
|
|
731
|
-
const result = {
|
|
732
|
-
tag,
|
|
733
|
-
draft: config.githubRelease.draft,
|
|
734
|
-
prerelease: isPreRel,
|
|
735
|
-
success: false
|
|
736
|
-
};
|
|
737
|
-
const ghArgs = ["release", "create", tag];
|
|
738
|
-
if (config.githubRelease.draft) {
|
|
739
|
-
ghArgs.push("--draft");
|
|
740
|
-
}
|
|
741
|
-
if (isPreRel) {
|
|
742
|
-
ghArgs.push("--prerelease");
|
|
743
|
-
}
|
|
744
|
-
if (notesBody) {
|
|
745
|
-
ghArgs.push("--notes", notesBody);
|
|
746
|
-
} else if (config.githubRelease.generateNotes) {
|
|
747
|
-
ghArgs.push("--generate-notes");
|
|
748
|
-
}
|
|
749
|
-
try {
|
|
750
|
-
const execResult = await execCommand("gh", ghArgs, {
|
|
751
|
-
dryRun,
|
|
752
|
-
label: `gh release create ${tag}`
|
|
753
|
-
});
|
|
754
|
-
result.success = true;
|
|
755
|
-
if (!dryRun && execResult.stdout.trim()) {
|
|
756
|
-
result.url = execResult.stdout.trim();
|
|
757
|
-
}
|
|
758
|
-
if (!dryRun) {
|
|
759
|
-
(0, import_core6.success)(`Created GitHub release for ${tag}`);
|
|
760
|
-
}
|
|
761
|
-
} catch (error) {
|
|
762
|
-
result.reason = error instanceof Error ? error.message : String(error);
|
|
763
|
-
(0, import_core6.warn)(`Failed to create GitHub release for ${tag}: ${result.reason}`);
|
|
764
|
-
}
|
|
765
|
-
ctx.output.githubReleases.push(result);
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
// src/stages/npm-publish.ts
|
|
770
|
-
var fs6 = __toESM(require("fs"), 1);
|
|
771
|
-
var path5 = __toESM(require("path"), 1);
|
|
772
|
-
var import_core8 = require("@releasekit/core");
|
|
773
|
-
|
|
774
|
-
// src/utils/npm-env.ts
|
|
775
|
-
var fs4 = __toESM(require("fs"), 1);
|
|
776
|
-
var os = __toESM(require("os"), 1);
|
|
777
|
-
var path3 = __toESM(require("path"), 1);
|
|
778
|
-
var import_core7 = require("@releasekit/core");
|
|
779
|
-
function writeTempNpmrc(contents) {
|
|
780
|
-
const dir = fs4.mkdtempSync(path3.join(os.tmpdir(), "releasekit-npmrc-"));
|
|
781
|
-
const npmrcPath = path3.join(dir, ".npmrc");
|
|
782
|
-
fs4.writeFileSync(npmrcPath, contents, "utf-8");
|
|
783
|
-
return {
|
|
784
|
-
npmrcPath,
|
|
785
|
-
cleanup: () => {
|
|
786
|
-
try {
|
|
787
|
-
fs4.rmSync(dir, { recursive: true, force: true });
|
|
788
|
-
} catch {
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
};
|
|
792
|
-
}
|
|
793
|
-
function createNpmSubprocessIsolation(options) {
|
|
794
|
-
const { authMethod, registryUrl } = options;
|
|
795
|
-
const baseEnv = {};
|
|
796
|
-
if (!authMethod) return { env: baseEnv, cleanup: () => {
|
|
797
|
-
} };
|
|
798
|
-
const token = process.env.NPM_TOKEN ?? process.env.NODE_AUTH_TOKEN;
|
|
799
|
-
const registryHost = (() => {
|
|
800
|
-
try {
|
|
801
|
-
return new URL(registryUrl).host;
|
|
802
|
-
} catch {
|
|
803
|
-
return "registry.npmjs.org";
|
|
804
|
-
}
|
|
805
|
-
})();
|
|
806
|
-
const lines = [`registry=${registryUrl}`];
|
|
807
|
-
if (authMethod === "oidc") {
|
|
808
|
-
lines.push("always-auth=false");
|
|
809
|
-
}
|
|
810
|
-
if (authMethod === "token" && token) {
|
|
811
|
-
lines.push(`//${registryHost}/:_authToken=${token}`);
|
|
812
|
-
}
|
|
813
|
-
lines.push("");
|
|
814
|
-
const { npmrcPath, cleanup } = writeTempNpmrc(lines.join("\n"));
|
|
815
|
-
(0, import_core7.debug)(`Using isolated npm userconfig: ${npmrcPath}`);
|
|
816
|
-
const isOidc = authMethod === "oidc";
|
|
817
|
-
return {
|
|
818
|
-
env: {
|
|
819
|
-
...baseEnv,
|
|
820
|
-
// Ensure npm and tools that read npm_config_* pick up our temp file
|
|
821
|
-
NPM_CONFIG_USERCONFIG: npmrcPath,
|
|
822
|
-
npm_config_userconfig: npmrcPath,
|
|
823
|
-
// Auth-specific hardening
|
|
824
|
-
...isOidc ? {
|
|
825
|
-
// Prevent setup-node's always-auth from forcing token lookups
|
|
826
|
-
NPM_CONFIG_ALWAYS_AUTH: "false",
|
|
827
|
-
npm_config_always_auth: "false",
|
|
828
|
-
// Explicitly prevent token-based publishing from being selected implicitly
|
|
829
|
-
NODE_AUTH_TOKEN: void 0,
|
|
830
|
-
NPM_TOKEN: void 0
|
|
831
|
-
} : {
|
|
832
|
-
// Ensure CLIs that expect NODE_AUTH_TOKEN can still work
|
|
833
|
-
NODE_AUTH_TOKEN: token
|
|
834
|
-
}
|
|
835
|
-
},
|
|
836
|
-
cleanup
|
|
837
|
-
};
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
// src/utils/package-manager.ts
|
|
841
|
-
var fs5 = __toESM(require("fs"), 1);
|
|
842
|
-
var path4 = __toESM(require("path"), 1);
|
|
843
|
-
function detectPackageManager(cwd) {
|
|
844
|
-
if (fs5.existsSync(path4.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
845
|
-
if (fs5.existsSync(path4.join(cwd, "yarn.lock"))) return "yarn";
|
|
846
|
-
return "npm";
|
|
847
|
-
}
|
|
848
|
-
function buildPublishCommand(pm, packageName, _packageDir, options) {
|
|
849
|
-
const args = ["publish"];
|
|
850
|
-
let file;
|
|
851
|
-
if (pm === "pnpm") {
|
|
852
|
-
file = "pnpm";
|
|
853
|
-
args.push("--filter", packageName, "--access", options.access, "--tag", options.tag);
|
|
854
|
-
if (options.noGitChecks) args.push("--no-git-checks");
|
|
855
|
-
} else {
|
|
856
|
-
file = "npm";
|
|
857
|
-
args.push("--access", options.access, "--tag", options.tag);
|
|
858
|
-
}
|
|
859
|
-
if (options.provenance) {
|
|
860
|
-
args.push("--provenance");
|
|
861
|
-
}
|
|
862
|
-
return { file, args };
|
|
863
|
-
}
|
|
864
|
-
function buildViewCommand(pm, packageName, version) {
|
|
865
|
-
const file = pm === "pnpm" ? "pnpm" : "npm";
|
|
866
|
-
return { file, args: ["view", `${packageName}@${version}`, "version", "--json"] };
|
|
867
|
-
}
|
|
868
|
-
|
|
869
|
-
// src/stages/npm-publish.ts
|
|
870
|
-
async function runNpmPublishStage(ctx) {
|
|
871
|
-
const { input, config, cliOptions, cwd } = ctx;
|
|
872
|
-
const dryRun = cliOptions.dryRun;
|
|
873
|
-
if (!config.npm.enabled) {
|
|
874
|
-
(0, import_core8.info)("NPM publishing disabled in config");
|
|
875
|
-
return;
|
|
876
|
-
}
|
|
877
|
-
const authMethod = config.npm.auth === "auto" ? detectNpmAuth() : config.npm.auth;
|
|
878
|
-
if (!authMethod && !dryRun) {
|
|
879
|
-
throw createPublishError("NPM_AUTH_ERROR" /* NPM_AUTH_ERROR */, "No NPM authentication method detected");
|
|
880
|
-
}
|
|
881
|
-
const useProvenance = config.npm.provenance && authMethod === "oidc";
|
|
882
|
-
const npmIsolation = createNpmSubprocessIsolation({
|
|
883
|
-
authMethod,
|
|
884
|
-
registryUrl: config.npm.registry
|
|
885
|
-
});
|
|
886
|
-
try {
|
|
887
|
-
for (const update of input.updates) {
|
|
888
|
-
const result = {
|
|
889
|
-
packageName: update.packageName,
|
|
890
|
-
version: update.newVersion,
|
|
891
|
-
registry: "npm",
|
|
892
|
-
success: false,
|
|
893
|
-
skipped: false
|
|
894
|
-
};
|
|
895
|
-
const pkgJsonPath = path5.resolve(cwd, update.filePath);
|
|
896
|
-
try {
|
|
897
|
-
const pkgContent = fs6.readFileSync(pkgJsonPath, "utf-8");
|
|
898
|
-
const pkgJson = JSON.parse(pkgContent);
|
|
899
|
-
if (pkgJson.private) {
|
|
900
|
-
result.skipped = true;
|
|
901
|
-
result.success = true;
|
|
902
|
-
result.reason = "Package is private";
|
|
903
|
-
ctx.output.npm.push(result);
|
|
904
|
-
(0, import_core8.debug)(`Skipping private package: ${update.packageName}`);
|
|
905
|
-
continue;
|
|
906
|
-
}
|
|
907
|
-
} catch {
|
|
908
|
-
if (update.filePath.endsWith("Cargo.toml")) {
|
|
909
|
-
result.skipped = true;
|
|
910
|
-
result.success = true;
|
|
911
|
-
result.reason = "Not an npm package";
|
|
912
|
-
ctx.output.npm.push(result);
|
|
913
|
-
continue;
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
const { file: viewFile, args: viewArgs } = buildViewCommand(
|
|
917
|
-
ctx.packageManager,
|
|
918
|
-
update.packageName,
|
|
919
|
-
update.newVersion
|
|
920
|
-
);
|
|
921
|
-
const viewResult = await execCommandSafe(viewFile, viewArgs, {
|
|
922
|
-
cwd,
|
|
923
|
-
dryRun: false,
|
|
924
|
-
// Always check, even in dry-run
|
|
925
|
-
env: npmIsolation.env
|
|
926
|
-
});
|
|
927
|
-
if (viewResult.exitCode === 0 && viewResult.stdout.trim()) {
|
|
928
|
-
result.alreadyPublished = true;
|
|
929
|
-
result.skipped = true;
|
|
930
|
-
result.success = true;
|
|
931
|
-
result.reason = "Already published";
|
|
932
|
-
ctx.output.npm.push(result);
|
|
933
|
-
(0, import_core8.warn)(`${update.packageName}@${update.newVersion} is already published, skipping`);
|
|
934
|
-
continue;
|
|
935
|
-
}
|
|
936
|
-
const distTag = getDistTag(update.newVersion, config.npm.tag);
|
|
937
|
-
const pkgDir = path5.dirname(path5.resolve(cwd, update.filePath));
|
|
938
|
-
const { file: pubFile, args: pubArgs } = buildPublishCommand(ctx.packageManager, update.packageName, pkgDir, {
|
|
939
|
-
access: config.npm.access,
|
|
940
|
-
tag: distTag,
|
|
941
|
-
provenance: useProvenance,
|
|
942
|
-
noGitChecks: true
|
|
943
|
-
});
|
|
944
|
-
try {
|
|
945
|
-
await execCommand(pubFile, pubArgs, {
|
|
946
|
-
cwd,
|
|
947
|
-
dryRun,
|
|
948
|
-
label: `npm publish ${update.packageName}@${update.newVersion}`,
|
|
949
|
-
env: npmIsolation.env
|
|
950
|
-
});
|
|
951
|
-
result.success = true;
|
|
952
|
-
if (!dryRun) {
|
|
953
|
-
(0, import_core8.success)(`Published ${update.packageName}@${update.newVersion} to npm`);
|
|
954
|
-
}
|
|
955
|
-
} catch (error) {
|
|
956
|
-
result.reason = error instanceof Error ? error.message : String(error);
|
|
957
|
-
(0, import_core8.warn)(`Failed to publish ${update.packageName}: ${result.reason}`);
|
|
958
|
-
}
|
|
959
|
-
ctx.output.npm.push(result);
|
|
960
|
-
}
|
|
961
|
-
} finally {
|
|
962
|
-
npmIsolation.cleanup();
|
|
963
|
-
}
|
|
964
|
-
}
|
|
965
|
-
|
|
966
|
-
// src/stages/prepare.ts
|
|
967
|
-
var fs7 = __toESM(require("fs"), 1);
|
|
968
|
-
var path6 = __toESM(require("path"), 1);
|
|
969
|
-
var import_core9 = require("@releasekit/core");
|
|
970
|
-
async function runPrepareStage(ctx) {
|
|
971
|
-
const { input, config, cliOptions, cwd } = ctx;
|
|
972
|
-
if (config.npm.enabled && config.npm.copyFiles.length > 0) {
|
|
973
|
-
for (const update of input.updates) {
|
|
974
|
-
const pkgDir = path6.dirname(path6.resolve(cwd, update.filePath));
|
|
975
|
-
for (const file of config.npm.copyFiles) {
|
|
976
|
-
const src = path6.resolve(cwd, file);
|
|
977
|
-
const dest = path6.join(pkgDir, file);
|
|
978
|
-
if (!fs7.existsSync(src)) {
|
|
979
|
-
(0, import_core9.debug)(`Source file not found, skipping copy: ${src}`);
|
|
980
|
-
continue;
|
|
981
|
-
}
|
|
982
|
-
if (path6.resolve(path6.dirname(src)) === path6.resolve(pkgDir)) {
|
|
983
|
-
(0, import_core9.debug)(`Skipping copy of ${file} - same directory as source`);
|
|
984
|
-
continue;
|
|
985
|
-
}
|
|
986
|
-
if (cliOptions.dryRun) {
|
|
987
|
-
(0, import_core9.info)(`[DRY RUN] Would copy ${src} \u2192 ${dest}`);
|
|
988
|
-
continue;
|
|
989
|
-
}
|
|
990
|
-
try {
|
|
991
|
-
fs7.copyFileSync(src, dest);
|
|
992
|
-
(0, import_core9.debug)(`Copied ${file} \u2192 ${pkgDir}`);
|
|
993
|
-
} catch (error) {
|
|
994
|
-
throw createPublishError(
|
|
995
|
-
"FILE_COPY_ERROR" /* FILE_COPY_ERROR */,
|
|
996
|
-
`Failed to copy ${src} to ${dest}: ${error instanceof Error ? error.message : String(error)}`
|
|
997
|
-
);
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
}
|
|
1001
|
-
}
|
|
1002
|
-
if (config.cargo.enabled) {
|
|
1003
|
-
for (const update of input.updates) {
|
|
1004
|
-
const pkgDir = path6.dirname(path6.resolve(cwd, update.filePath));
|
|
1005
|
-
const cargoPath = path6.join(pkgDir, "Cargo.toml");
|
|
1006
|
-
if (!fs7.existsSync(cargoPath)) {
|
|
1007
|
-
continue;
|
|
1008
|
-
}
|
|
1009
|
-
if (cliOptions.dryRun) {
|
|
1010
|
-
(0, import_core9.info)(`[DRY RUN] Would update ${cargoPath} to version ${update.newVersion}`);
|
|
1011
|
-
continue;
|
|
1012
|
-
}
|
|
1013
|
-
updateCargoVersion(cargoPath, update.newVersion);
|
|
1014
|
-
(0, import_core9.debug)(`Updated ${cargoPath} to version ${update.newVersion}`);
|
|
1015
|
-
}
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
// src/stages/verify.ts
|
|
1020
|
-
var import_core11 = require("@releasekit/core");
|
|
1021
|
-
|
|
1022
|
-
// src/utils/retry.ts
|
|
1023
|
-
var import_core10 = require("@releasekit/core");
|
|
1024
|
-
async function withRetry(fn, options, shouldRetry) {
|
|
1025
|
-
let lastError;
|
|
1026
|
-
let delay = options.initialDelay;
|
|
1027
|
-
for (let attempt = 1; attempt <= options.maxAttempts; attempt++) {
|
|
1028
|
-
try {
|
|
1029
|
-
return await fn();
|
|
1030
|
-
} catch (error) {
|
|
1031
|
-
lastError = error;
|
|
1032
|
-
if (shouldRetry && !shouldRetry(error)) {
|
|
1033
|
-
throw error;
|
|
1034
|
-
}
|
|
1035
|
-
if (attempt < options.maxAttempts) {
|
|
1036
|
-
(0, import_core10.debug)(`Attempt ${attempt}/${options.maxAttempts} failed, retrying in ${delay}ms...`);
|
|
1037
|
-
await sleep(delay);
|
|
1038
|
-
delay = Math.floor(delay * options.backoffMultiplier);
|
|
1039
|
-
}
|
|
1040
|
-
}
|
|
1041
|
-
}
|
|
1042
|
-
throw lastError;
|
|
1043
|
-
}
|
|
1044
|
-
function sleep(ms) {
|
|
1045
|
-
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
1046
|
-
}
|
|
1047
|
-
|
|
1048
|
-
// src/stages/verify.ts
|
|
1049
|
-
async function runVerifyStage(ctx) {
|
|
1050
|
-
const { config, cliOptions, output, cwd } = ctx;
|
|
1051
|
-
if (config.verify.npm.enabled) {
|
|
1052
|
-
const published = output.npm.filter((r) => r.success && !r.skipped && !r.alreadyPublished);
|
|
1053
|
-
for (const pkg of published) {
|
|
1054
|
-
const result = {
|
|
1055
|
-
packageName: pkg.packageName,
|
|
1056
|
-
version: pkg.version,
|
|
1057
|
-
registry: "npm",
|
|
1058
|
-
verified: false,
|
|
1059
|
-
attempts: 0
|
|
1060
|
-
};
|
|
1061
|
-
if (cliOptions.dryRun) {
|
|
1062
|
-
(0, import_core11.info)(`[DRY RUN] Would verify ${pkg.packageName}@${pkg.version} on npm`);
|
|
1063
|
-
result.verified = true;
|
|
1064
|
-
ctx.output.verification.push(result);
|
|
1065
|
-
continue;
|
|
1066
|
-
}
|
|
1067
|
-
try {
|
|
1068
|
-
await withRetry(async () => {
|
|
1069
|
-
result.attempts++;
|
|
1070
|
-
const { file: viewFile, args: viewArgs } = buildViewCommand(ctx.packageManager, pkg.packageName, pkg.version);
|
|
1071
|
-
const viewResult = await execCommandSafe(viewFile, viewArgs, {
|
|
1072
|
-
cwd,
|
|
1073
|
-
dryRun: false
|
|
1074
|
-
});
|
|
1075
|
-
if (viewResult.exitCode !== 0 || !viewResult.stdout.trim()) {
|
|
1076
|
-
throw new Error(`${pkg.packageName}@${pkg.version} not yet available on npm`);
|
|
1077
|
-
}
|
|
1078
|
-
(0, import_core11.debug)(`Verified ${pkg.packageName}@${pkg.version} on npm`);
|
|
1079
|
-
}, config.verify.npm);
|
|
1080
|
-
result.verified = true;
|
|
1081
|
-
(0, import_core11.success)(`Verified ${pkg.packageName}@${pkg.version} on npm`);
|
|
1082
|
-
} catch {
|
|
1083
|
-
(0, import_core11.warn)(`Failed to verify ${pkg.packageName}@${pkg.version} on npm after ${result.attempts} attempts`);
|
|
1084
|
-
}
|
|
1085
|
-
ctx.output.verification.push(result);
|
|
1086
|
-
}
|
|
1087
|
-
}
|
|
1088
|
-
if (config.verify.cargo.enabled) {
|
|
1089
|
-
const published = output.cargo.filter((r) => r.success && !r.skipped && !r.alreadyPublished);
|
|
1090
|
-
for (const crate of published) {
|
|
1091
|
-
const result = {
|
|
1092
|
-
packageName: crate.packageName,
|
|
1093
|
-
version: crate.version,
|
|
1094
|
-
registry: "cargo",
|
|
1095
|
-
verified: false,
|
|
1096
|
-
attempts: 0
|
|
1097
|
-
};
|
|
1098
|
-
if (cliOptions.dryRun) {
|
|
1099
|
-
(0, import_core11.info)(`[DRY RUN] Would verify ${crate.packageName}@${crate.version} on crates.io`);
|
|
1100
|
-
result.verified = true;
|
|
1101
|
-
ctx.output.verification.push(result);
|
|
1102
|
-
continue;
|
|
1103
|
-
}
|
|
1104
|
-
try {
|
|
1105
|
-
await withRetry(async () => {
|
|
1106
|
-
result.attempts++;
|
|
1107
|
-
const response = await fetch(`https://crates.io/api/v1/crates/${crate.packageName}/${crate.version}`);
|
|
1108
|
-
if (!response.ok) {
|
|
1109
|
-
throw new Error(`${crate.packageName}@${crate.version} not yet available on crates.io`);
|
|
1110
|
-
}
|
|
1111
|
-
(0, import_core11.debug)(`Verified ${crate.packageName}@${crate.version} on crates.io`);
|
|
1112
|
-
}, config.verify.cargo);
|
|
1113
|
-
result.verified = true;
|
|
1114
|
-
(0, import_core11.success)(`Verified ${crate.packageName}@${crate.version} on crates.io`);
|
|
1115
|
-
} catch {
|
|
1116
|
-
(0, import_core11.warn)(`Failed to verify ${crate.packageName}@${crate.version} on crates.io after ${result.attempts} attempts`);
|
|
1117
|
-
}
|
|
1118
|
-
ctx.output.verification.push(result);
|
|
1119
|
-
}
|
|
1120
|
-
}
|
|
1121
|
-
}
|
|
1122
|
-
|
|
1123
|
-
// src/pipeline/index.ts
|
|
1124
|
-
function inferStageName(error) {
|
|
1125
|
-
if (error instanceof BasePublishError) {
|
|
1126
|
-
const codeToStage = {
|
|
1127
|
-
FILE_COPY_ERROR: "prepare",
|
|
1128
|
-
CARGO_TOML_ERROR: "prepare",
|
|
1129
|
-
GIT_COMMIT_ERROR: "git-commit",
|
|
1130
|
-
GIT_TAG_ERROR: "git-commit",
|
|
1131
|
-
NPM_PUBLISH_ERROR: "npm-publish",
|
|
1132
|
-
NPM_AUTH_ERROR: "npm-publish",
|
|
1133
|
-
CARGO_PUBLISH_ERROR: "cargo-publish",
|
|
1134
|
-
CARGO_AUTH_ERROR: "cargo-publish",
|
|
1135
|
-
VERIFICATION_FAILED: "verify",
|
|
1136
|
-
GIT_PUSH_ERROR: "git-push",
|
|
1137
|
-
GITHUB_RELEASE_ERROR: "github-release"
|
|
1138
|
-
};
|
|
1139
|
-
return codeToStage[error.code] ?? "unknown";
|
|
1140
|
-
}
|
|
1141
|
-
return "unknown";
|
|
1142
|
-
}
|
|
1143
|
-
async function runPipeline(input, config, options) {
|
|
1144
|
-
const cwd = process.cwd();
|
|
1145
|
-
const ctx = {
|
|
1146
|
-
input,
|
|
1147
|
-
config,
|
|
1148
|
-
cliOptions: options,
|
|
1149
|
-
packageManager: detectPackageManager(cwd),
|
|
1150
|
-
cwd,
|
|
1151
|
-
output: {
|
|
1152
|
-
dryRun: options.dryRun,
|
|
1153
|
-
git: { committed: false, tags: [], pushed: false },
|
|
1154
|
-
npm: [],
|
|
1155
|
-
cargo: [],
|
|
1156
|
-
verification: [],
|
|
1157
|
-
githubReleases: []
|
|
1158
|
-
}
|
|
1159
|
-
};
|
|
1160
|
-
try {
|
|
1161
|
-
await runPrepareStage(ctx);
|
|
1162
|
-
if (options.skipGitCommit && !options.skipGit) {
|
|
1163
|
-
ctx.output.git.committed = !!input.commitMessage;
|
|
1164
|
-
ctx.output.git.tags = [...input.tags];
|
|
1165
|
-
} else if (!options.skipGit) {
|
|
1166
|
-
await runGitCommitStage(ctx);
|
|
1167
|
-
}
|
|
1168
|
-
if (!options.skipPublish) {
|
|
1169
|
-
if (options.registry === "all" || options.registry === "npm") {
|
|
1170
|
-
await runNpmPublishStage(ctx);
|
|
1171
|
-
}
|
|
1172
|
-
if (options.registry === "all" || options.registry === "cargo") {
|
|
1173
|
-
await runCargoPublishStage(ctx);
|
|
1174
|
-
}
|
|
1175
|
-
}
|
|
1176
|
-
if (!options.skipVerification && !options.skipPublish) {
|
|
1177
|
-
await runVerifyStage(ctx);
|
|
1178
|
-
}
|
|
1179
|
-
if (!options.skipGit) {
|
|
1180
|
-
await runGitPushStage(ctx);
|
|
1181
|
-
}
|
|
1182
|
-
if (!options.skipGithubRelease) {
|
|
1183
|
-
await runGithubReleaseStage(ctx);
|
|
1184
|
-
}
|
|
1185
|
-
} catch (error) {
|
|
1186
|
-
const stageName = inferStageName(error);
|
|
1187
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
1188
|
-
throw new PipelineError(message, stageName, ctx.output, error instanceof Error ? error : void 0);
|
|
1189
|
-
}
|
|
1190
|
-
return ctx.output;
|
|
1191
|
-
}
|
|
1192
|
-
|
|
1193
|
-
// src/stages/input.ts
|
|
1194
|
-
var fs8 = __toESM(require("fs"), 1);
|
|
1195
|
-
var import_core12 = require("@releasekit/core");
|
|
1196
|
-
var import_zod = require("zod");
|
|
1197
|
-
var VersionChangelogEntrySchema = import_zod.z.object({
|
|
1198
|
-
type: import_zod.z.string(),
|
|
1199
|
-
description: import_zod.z.string(),
|
|
1200
|
-
issueIds: import_zod.z.array(import_zod.z.string()).optional(),
|
|
1201
|
-
scope: import_zod.z.string().optional(),
|
|
1202
|
-
originalType: import_zod.z.string().optional()
|
|
1203
|
-
});
|
|
1204
|
-
var VersionPackageChangelogSchema = import_zod.z.object({
|
|
1205
|
-
packageName: import_zod.z.string(),
|
|
1206
|
-
version: import_zod.z.string(),
|
|
1207
|
-
previousVersion: import_zod.z.string().nullable(),
|
|
1208
|
-
revisionRange: import_zod.z.string(),
|
|
1209
|
-
repoUrl: import_zod.z.string().nullable(),
|
|
1210
|
-
entries: import_zod.z.array(VersionChangelogEntrySchema)
|
|
1211
|
-
});
|
|
1212
|
-
var VersionPackageUpdateSchema = import_zod.z.object({
|
|
1213
|
-
packageName: import_zod.z.string(),
|
|
1214
|
-
newVersion: import_zod.z.string(),
|
|
1215
|
-
filePath: import_zod.z.string()
|
|
1216
|
-
});
|
|
1217
|
-
var VersionOutputSchema = import_zod.z.object({
|
|
1218
|
-
dryRun: import_zod.z.boolean(),
|
|
1219
|
-
updates: import_zod.z.array(VersionPackageUpdateSchema),
|
|
1220
|
-
changelogs: import_zod.z.array(VersionPackageChangelogSchema),
|
|
1221
|
-
commitMessage: import_zod.z.string().optional(),
|
|
1222
|
-
tags: import_zod.z.array(import_zod.z.string())
|
|
1223
|
-
});
|
|
1224
|
-
async function parseInput(inputPath) {
|
|
1225
|
-
let raw;
|
|
1226
|
-
if (inputPath) {
|
|
1227
|
-
try {
|
|
1228
|
-
raw = fs8.readFileSync(inputPath, "utf-8");
|
|
1229
|
-
} catch {
|
|
1230
|
-
throw createPublishError("INPUT_PARSE_ERROR" /* INPUT_PARSE_ERROR */, `Could not read file: ${inputPath}`);
|
|
1231
|
-
}
|
|
1232
|
-
} else {
|
|
1233
|
-
raw = await readStdin();
|
|
1234
|
-
}
|
|
1235
|
-
let parsed;
|
|
1236
|
-
try {
|
|
1237
|
-
parsed = JSON.parse(raw);
|
|
1238
|
-
} catch {
|
|
1239
|
-
throw createPublishError("INPUT_PARSE_ERROR" /* INPUT_PARSE_ERROR */, "Input is not valid JSON");
|
|
1240
|
-
}
|
|
1241
|
-
const result = VersionOutputSchema.safeParse(parsed);
|
|
1242
|
-
if (!result.success) {
|
|
1243
|
-
const issues = result.error.issues.map((i) => ` ${i.path.join(".")}: ${i.message}`).join("\n");
|
|
1244
|
-
throw createPublishError("INPUT_VALIDATION_ERROR" /* INPUT_VALIDATION_ERROR */, `Schema validation failed:
|
|
1245
|
-
${issues}`);
|
|
1246
|
-
}
|
|
1247
|
-
if (result.data.updates.length === 0) {
|
|
1248
|
-
(0, import_core12.info)("No package updates in version output \u2014 pipeline will be a no-op");
|
|
1249
|
-
}
|
|
1250
|
-
return result.data;
|
|
1251
|
-
}
|
|
1252
|
-
async function readStdin() {
|
|
1253
|
-
const chunks = [];
|
|
1254
|
-
for await (const chunk of process.stdin) {
|
|
1255
|
-
chunks.push(chunk);
|
|
1256
|
-
}
|
|
1257
|
-
return chunks.join("");
|
|
1258
|
-
}
|
|
1259
|
-
|
|
1260
|
-
// src/cli.ts
|
|
1261
|
-
var program = new import_commander.Command();
|
|
1262
|
-
program.name("releasekit-publish").description("Publish packages to registries with git tagging and GitHub releases").version("0.1.0").option("--input <path>", "Path to version output JSON (default: stdin)").option("--config <path>", "Path to releasekit config").option("--registry <type>", "Registry to publish to (npm, cargo, all)", "all").option("--npm-auth <method>", "NPM auth method (oidc, token, auto)", "auto").option("--dry-run", "Simulate all operations", false).option("--skip-git", "Skip git commit/tag/push", false).option("--skip-publish", "Skip registry publishing", false).option("--skip-github-release", "Skip GitHub Release creation", false).option("--skip-verification", "Skip post-publish verification", false).option("--json", "Output results as JSON", false).option("--verbose", "Verbose logging", false).action(async (options) => {
|
|
1263
|
-
if (options.verbose) (0, import_core13.setLogLevel)("debug");
|
|
1264
|
-
if (options.json) (0, import_core13.setJsonMode)(true);
|
|
1265
|
-
try {
|
|
1266
|
-
const config = loadConfig({ configPath: options.config });
|
|
1267
|
-
const input = await parseInput(options.input);
|
|
1268
|
-
if (options.npmAuth !== "auto") {
|
|
1269
|
-
config.npm.auth = options.npmAuth;
|
|
1270
|
-
}
|
|
1271
|
-
const cliOptions = {
|
|
1272
|
-
input: options.input,
|
|
1273
|
-
config: options.config,
|
|
1274
|
-
registry: options.registry,
|
|
1275
|
-
npmAuth: options.npmAuth,
|
|
1276
|
-
dryRun: options.dryRun,
|
|
1277
|
-
skipGit: options.skipGit,
|
|
1278
|
-
skipPublish: options.skipPublish,
|
|
1279
|
-
skipGithubRelease: options.skipGithubRelease,
|
|
1280
|
-
skipVerification: options.skipVerification,
|
|
1281
|
-
json: options.json,
|
|
1282
|
-
verbose: options.verbose
|
|
1283
|
-
};
|
|
1284
|
-
const output = await runPipeline(input, config, cliOptions);
|
|
1285
|
-
if (options.json) {
|
|
1286
|
-
console.log(JSON.stringify(output, null, 2));
|
|
1287
|
-
}
|
|
1288
|
-
} catch (err) {
|
|
1289
|
-
if (err instanceof PipelineError && options.json) {
|
|
1290
|
-
console.log(
|
|
1291
|
-
JSON.stringify(
|
|
1292
|
-
{
|
|
1293
|
-
error: err.message,
|
|
1294
|
-
failedStage: err.failedStage,
|
|
1295
|
-
partialOutput: err.partialOutput
|
|
1296
|
-
},
|
|
1297
|
-
null,
|
|
1298
|
-
2
|
|
1299
|
-
)
|
|
1300
|
-
);
|
|
1301
|
-
process.exit(import_core13.EXIT_CODES.PUBLISH_ERROR);
|
|
1302
|
-
}
|
|
1303
|
-
if (BasePublishError.isPublishError(err)) {
|
|
1304
|
-
err.logError();
|
|
1305
|
-
process.exit(import_core13.EXIT_CODES.PUBLISH_ERROR);
|
|
1306
|
-
}
|
|
1307
|
-
console.error(err instanceof Error ? err.message : String(err));
|
|
1308
|
-
process.exit(import_core13.EXIT_CODES.GENERAL_ERROR);
|
|
1309
|
-
}
|
|
1310
|
-
});
|
|
1311
|
-
program.parse();
|