pubm 0.1.7 → 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 +5 -0
- package/bin/cli.js +260 -68
- package/dist/index.cjs +252 -60
- package/dist/index.js +260 -68
- package/package.json +1 -1
package/README.md
CHANGED
package/bin/cli.js
CHANGED
|
@@ -5249,50 +5249,6 @@ function link2(text, url) {
|
|
|
5249
5249
|
return `\x1B]8;;${url}\x07${text}\x1B]8;;\x07`;
|
|
5250
5250
|
}
|
|
5251
5251
|
|
|
5252
|
-
// src/utils/rollback.ts
|
|
5253
|
-
var rollbacks = [];
|
|
5254
|
-
function addRollback(rollback2, context) {
|
|
5255
|
-
rollbacks.push({ fn: rollback2, ctx: context });
|
|
5256
|
-
}
|
|
5257
|
-
var called = false;
|
|
5258
|
-
async function rollback() {
|
|
5259
|
-
if (called) return void 0;
|
|
5260
|
-
called = true;
|
|
5261
|
-
if (rollbacks.length <= 0) return void 0;
|
|
5262
|
-
console.log("Rollback...");
|
|
5263
|
-
const results = await Promise.allSettled(
|
|
5264
|
-
rollbacks.map(({ fn, ctx }) => fn(ctx))
|
|
5265
|
-
);
|
|
5266
|
-
const failures = results.filter(
|
|
5267
|
-
(r) => r.status === "rejected"
|
|
5268
|
-
);
|
|
5269
|
-
if (failures.length > 0) {
|
|
5270
|
-
for (const failure of failures) {
|
|
5271
|
-
console.error(
|
|
5272
|
-
`Rollback operation failed: ${failure.reason instanceof Error ? failure.reason.message : failure.reason}`
|
|
5273
|
-
);
|
|
5274
|
-
}
|
|
5275
|
-
console.log(
|
|
5276
|
-
"Rollback completed with errors. Some operations may require manual recovery."
|
|
5277
|
-
);
|
|
5278
|
-
} else {
|
|
5279
|
-
console.log("Rollback completed");
|
|
5280
|
-
}
|
|
5281
|
-
}
|
|
5282
|
-
|
|
5283
|
-
// src/utils/listr.ts
|
|
5284
|
-
function createListr(...args) {
|
|
5285
|
-
const listr = new Listr(...args);
|
|
5286
|
-
listr.isRoot = () => false;
|
|
5287
|
-
listr.externalSignalHandler = rollback;
|
|
5288
|
-
return listr;
|
|
5289
|
-
}
|
|
5290
|
-
|
|
5291
|
-
// src/utils/package.ts
|
|
5292
|
-
import { readFile as readFile2, stat as stat3, writeFile as writeFile2 } from "node:fs/promises";
|
|
5293
|
-
import path8 from "node:path";
|
|
5294
|
-
import process11 from "node:process";
|
|
5295
|
-
|
|
5296
5252
|
// src/ecosystem/rust.ts
|
|
5297
5253
|
import { readFile, stat as stat2, writeFile } from "node:fs/promises";
|
|
5298
5254
|
import path7 from "node:path";
|
|
@@ -5339,6 +5295,17 @@ var RustEcosystem = class extends Ecosystem {
|
|
|
5339
5295
|
pkg.version = newVersion;
|
|
5340
5296
|
await writeFile(filePath, stringify(cargo));
|
|
5341
5297
|
}
|
|
5298
|
+
async dependencies() {
|
|
5299
|
+
const cargo = await this.readCargoToml();
|
|
5300
|
+
const deps = [];
|
|
5301
|
+
for (const section of ["dependencies", "build-dependencies"]) {
|
|
5302
|
+
const sectionData = cargo[section];
|
|
5303
|
+
if (sectionData) {
|
|
5304
|
+
deps.push(...Object.keys(sectionData));
|
|
5305
|
+
}
|
|
5306
|
+
}
|
|
5307
|
+
return deps;
|
|
5308
|
+
}
|
|
5342
5309
|
manifestFiles() {
|
|
5343
5310
|
return ["Cargo.toml"];
|
|
5344
5311
|
}
|
|
@@ -5353,7 +5320,96 @@ var RustEcosystem = class extends Ecosystem {
|
|
|
5353
5320
|
}
|
|
5354
5321
|
};
|
|
5355
5322
|
|
|
5323
|
+
// src/utils/crate-graph.ts
|
|
5324
|
+
async function sortCratesByDependencyOrder(cratePaths) {
|
|
5325
|
+
if (cratePaths.length <= 1) return cratePaths;
|
|
5326
|
+
const crateInfos = await Promise.all(
|
|
5327
|
+
cratePaths.map(async (cratePath) => {
|
|
5328
|
+
const eco = new RustEcosystem(cratePath);
|
|
5329
|
+
const name = await eco.packageName();
|
|
5330
|
+
const deps = await eco.dependencies();
|
|
5331
|
+
return { cratePath, name, deps };
|
|
5332
|
+
})
|
|
5333
|
+
);
|
|
5334
|
+
const nameSet = new Set(crateInfos.map((c) => c.name));
|
|
5335
|
+
const nameToPath = new Map(crateInfos.map((c) => [c.name, c.cratePath]));
|
|
5336
|
+
const internalDeps = /* @__PURE__ */ new Map();
|
|
5337
|
+
const inDegree = /* @__PURE__ */ new Map();
|
|
5338
|
+
for (const name of nameSet) {
|
|
5339
|
+
inDegree.set(name, 0);
|
|
5340
|
+
}
|
|
5341
|
+
for (const crate of crateInfos) {
|
|
5342
|
+
const filtered = crate.deps.filter((d2) => nameSet.has(d2));
|
|
5343
|
+
internalDeps.set(crate.name, filtered);
|
|
5344
|
+
for (const _dep of filtered) {
|
|
5345
|
+
inDegree.set(crate.name, (inDegree.get(crate.name) ?? 0) + 1);
|
|
5346
|
+
}
|
|
5347
|
+
}
|
|
5348
|
+
const queue = [];
|
|
5349
|
+
for (const [name, degree] of inDegree) {
|
|
5350
|
+
if (degree === 0) queue.push(name);
|
|
5351
|
+
}
|
|
5352
|
+
const sorted = [];
|
|
5353
|
+
while (queue.length > 0) {
|
|
5354
|
+
const current = queue.shift();
|
|
5355
|
+
sorted.push(current);
|
|
5356
|
+
for (const [name, deps] of internalDeps) {
|
|
5357
|
+
if (deps.includes(current)) {
|
|
5358
|
+
const newDegree = (inDegree.get(name) ?? 0) - 1;
|
|
5359
|
+
inDegree.set(name, newDegree);
|
|
5360
|
+
if (newDegree === 0) queue.push(name);
|
|
5361
|
+
}
|
|
5362
|
+
}
|
|
5363
|
+
}
|
|
5364
|
+
if (sorted.length !== nameSet.size) {
|
|
5365
|
+
throw new Error("Circular dependency detected among configured crates");
|
|
5366
|
+
}
|
|
5367
|
+
return sorted.map((name) => nameToPath.get(name));
|
|
5368
|
+
}
|
|
5369
|
+
|
|
5370
|
+
// src/utils/rollback.ts
|
|
5371
|
+
var rollbacks = [];
|
|
5372
|
+
function addRollback(rollback2, context) {
|
|
5373
|
+
rollbacks.push({ fn: rollback2, ctx: context });
|
|
5374
|
+
}
|
|
5375
|
+
var called = false;
|
|
5376
|
+
async function rollback() {
|
|
5377
|
+
if (called) return void 0;
|
|
5378
|
+
called = true;
|
|
5379
|
+
if (rollbacks.length <= 0) return void 0;
|
|
5380
|
+
console.log("Rollback...");
|
|
5381
|
+
const results = await Promise.allSettled(
|
|
5382
|
+
rollbacks.map(({ fn, ctx }) => fn(ctx))
|
|
5383
|
+
);
|
|
5384
|
+
const failures = results.filter(
|
|
5385
|
+
(r) => r.status === "rejected"
|
|
5386
|
+
);
|
|
5387
|
+
if (failures.length > 0) {
|
|
5388
|
+
for (const failure of failures) {
|
|
5389
|
+
console.error(
|
|
5390
|
+
`Rollback operation failed: ${failure.reason instanceof Error ? failure.reason.message : failure.reason}`
|
|
5391
|
+
);
|
|
5392
|
+
}
|
|
5393
|
+
console.log(
|
|
5394
|
+
"Rollback completed with errors. Some operations may require manual recovery."
|
|
5395
|
+
);
|
|
5396
|
+
} else {
|
|
5397
|
+
console.log("Rollback completed");
|
|
5398
|
+
}
|
|
5399
|
+
}
|
|
5400
|
+
|
|
5401
|
+
// src/utils/listr.ts
|
|
5402
|
+
function createListr(...args) {
|
|
5403
|
+
const listr = new Listr(...args);
|
|
5404
|
+
listr.isRoot = () => false;
|
|
5405
|
+
listr.externalSignalHandler = rollback;
|
|
5406
|
+
return listr;
|
|
5407
|
+
}
|
|
5408
|
+
|
|
5356
5409
|
// src/utils/package.ts
|
|
5410
|
+
import { readFile as readFile2, stat as stat3, writeFile as writeFile2 } from "node:fs/promises";
|
|
5411
|
+
import path8 from "node:path";
|
|
5412
|
+
import process11 from "node:process";
|
|
5357
5413
|
var cachedPackageJson = {};
|
|
5358
5414
|
var cachedJsrJson = {};
|
|
5359
5415
|
function patchCachedJsrJson(contents, { cwd = process11.cwd() } = {}) {
|
|
@@ -5588,7 +5644,7 @@ function collectRegistries(ctx) {
|
|
|
5588
5644
|
|
|
5589
5645
|
// src/registry/crates.ts
|
|
5590
5646
|
import path9 from "node:path";
|
|
5591
|
-
import { exec as exec3 } from "tinyexec";
|
|
5647
|
+
import { exec as exec3, NonZeroExitError } from "tinyexec";
|
|
5592
5648
|
|
|
5593
5649
|
// src/registry/registry.ts
|
|
5594
5650
|
var Registry = class {
|
|
@@ -5596,6 +5652,8 @@ var Registry = class {
|
|
|
5596
5652
|
this.packageName = packageName;
|
|
5597
5653
|
this.registry = registry;
|
|
5598
5654
|
}
|
|
5655
|
+
async dryRunPublish(_manifestDir) {
|
|
5656
|
+
}
|
|
5599
5657
|
};
|
|
5600
5658
|
|
|
5601
5659
|
// src/registry/crates.ts
|
|
@@ -5670,9 +5728,24 @@ var CratesRegistry = class extends Registry {
|
|
|
5670
5728
|
await exec3("cargo", args, { throwOnError: true });
|
|
5671
5729
|
return true;
|
|
5672
5730
|
} catch (error) {
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5731
|
+
const stderr = error instanceof NonZeroExitError ? error.output?.stderr : void 0;
|
|
5732
|
+
const message = stderr ? `Failed to run \`cargo publish\`:
|
|
5733
|
+
${stderr}` : "Failed to run `cargo publish`";
|
|
5734
|
+
throw new CratesError(message, { cause: error });
|
|
5735
|
+
}
|
|
5736
|
+
}
|
|
5737
|
+
async dryRunPublish(manifestDir) {
|
|
5738
|
+
try {
|
|
5739
|
+
const args = ["publish", "--dry-run"];
|
|
5740
|
+
if (manifestDir) {
|
|
5741
|
+
args.push("--manifest-path", path9.join(manifestDir, "Cargo.toml"));
|
|
5742
|
+
}
|
|
5743
|
+
await exec3("cargo", args, { throwOnError: true });
|
|
5744
|
+
} catch (error) {
|
|
5745
|
+
const stderr = error instanceof NonZeroExitError ? error.output?.stderr : void 0;
|
|
5746
|
+
const message = stderr ? `Dry-run failed for \`cargo publish\`:
|
|
5747
|
+
${stderr}` : "Dry-run failed for `cargo publish`";
|
|
5748
|
+
throw new CratesError(message, { cause: error });
|
|
5676
5749
|
}
|
|
5677
5750
|
}
|
|
5678
5751
|
async isPublished() {
|
|
@@ -5761,13 +5834,8 @@ function createCratesPublishTask(packagePath) {
|
|
|
5761
5834
|
var cratesAvailableCheckTasks = createCratesAvailableCheckTask();
|
|
5762
5835
|
var cratesPublishTasks = createCratesPublishTask();
|
|
5763
5836
|
|
|
5764
|
-
// src/tasks/jsr.ts
|
|
5765
|
-
import process12 from "node:process";
|
|
5766
|
-
import { ListrEnquirerPromptAdapter } from "@listr2/prompt-adapter-enquirer";
|
|
5767
|
-
import npmCli from "@npmcli/promise-spawn";
|
|
5768
|
-
|
|
5769
5837
|
// src/registry/jsr.ts
|
|
5770
|
-
import { exec as exec4, NonZeroExitError } from "tinyexec";
|
|
5838
|
+
import { exec as exec4, NonZeroExitError as NonZeroExitError2 } from "tinyexec";
|
|
5771
5839
|
|
|
5772
5840
|
// src/utils/db.ts
|
|
5773
5841
|
import { createCipheriv, createDecipheriv, createHash } from "node:crypto";
|
|
@@ -5946,7 +6014,7 @@ var JsrRegisry = class extends Registry {
|
|
|
5946
6014
|
this.packageCreationUrls = void 0;
|
|
5947
6015
|
return true;
|
|
5948
6016
|
} catch (error) {
|
|
5949
|
-
const stderr = error instanceof
|
|
6017
|
+
const stderr = error instanceof NonZeroExitError2 ? error.output?.stderr : void 0;
|
|
5950
6018
|
if (stderr?.includes("don't exist")) {
|
|
5951
6019
|
const urls = [...stderr.matchAll(/https:\/\/jsr\.io\/new\S+/g)].map(
|
|
5952
6020
|
(m) => m[0]
|
|
@@ -5965,6 +6033,28 @@ ${stderr}` : ""}`,
|
|
|
5965
6033
|
);
|
|
5966
6034
|
}
|
|
5967
6035
|
}
|
|
6036
|
+
async dryRunPublish() {
|
|
6037
|
+
try {
|
|
6038
|
+
await exec4(
|
|
6039
|
+
"jsr",
|
|
6040
|
+
[
|
|
6041
|
+
"publish",
|
|
6042
|
+
"--dry-run",
|
|
6043
|
+
"--allow-dirty",
|
|
6044
|
+
"--token",
|
|
6045
|
+
`${JsrClient.token}`
|
|
6046
|
+
],
|
|
6047
|
+
{ throwOnError: true }
|
|
6048
|
+
);
|
|
6049
|
+
} catch (error) {
|
|
6050
|
+
const stderr = error instanceof NonZeroExitError2 ? error.output?.stderr : void 0;
|
|
6051
|
+
throw new JsrError(
|
|
6052
|
+
`Dry-run failed for \`jsr publish\`${stderr ? `
|
|
6053
|
+
${stderr}` : ""}`,
|
|
6054
|
+
{ cause: error }
|
|
6055
|
+
);
|
|
6056
|
+
}
|
|
6057
|
+
}
|
|
5968
6058
|
async version() {
|
|
5969
6059
|
return await this.jsr(["--version"]);
|
|
5970
6060
|
}
|
|
@@ -6206,7 +6296,7 @@ async function jsrRegistry() {
|
|
|
6206
6296
|
}
|
|
6207
6297
|
|
|
6208
6298
|
// src/registry/npm.ts
|
|
6209
|
-
import { exec as exec5, NonZeroExitError as
|
|
6299
|
+
import { exec as exec5, NonZeroExitError as NonZeroExitError3 } from "tinyexec";
|
|
6210
6300
|
var NpmError = class extends AbstractError {
|
|
6211
6301
|
constructor() {
|
|
6212
6302
|
super(...arguments);
|
|
@@ -6263,7 +6353,7 @@ var NpmRegistry = class extends Registry {
|
|
|
6263
6353
|
await this.npm(["whoami"]);
|
|
6264
6354
|
return true;
|
|
6265
6355
|
} catch (error) {
|
|
6266
|
-
if (error instanceof
|
|
6356
|
+
if (error instanceof NonZeroExitError3) {
|
|
6267
6357
|
return false;
|
|
6268
6358
|
}
|
|
6269
6359
|
throw new NpmError("Failed to run `npm whoami`", { cause: error });
|
|
@@ -6341,7 +6431,7 @@ var NpmRegistry = class extends Registry {
|
|
|
6341
6431
|
await this.npm(["publish", "--provenance", "--access", "public"]);
|
|
6342
6432
|
return true;
|
|
6343
6433
|
} catch (error) {
|
|
6344
|
-
if (error instanceof
|
|
6434
|
+
if (error instanceof NonZeroExitError3 && error.output?.stderr.includes("EOTP")) {
|
|
6345
6435
|
return false;
|
|
6346
6436
|
}
|
|
6347
6437
|
throw this.classifyPublishError(error);
|
|
@@ -6353,12 +6443,28 @@ var NpmRegistry = class extends Registry {
|
|
|
6353
6443
|
await this.npm(args);
|
|
6354
6444
|
return true;
|
|
6355
6445
|
} catch (error) {
|
|
6356
|
-
if (error instanceof
|
|
6446
|
+
if (error instanceof NonZeroExitError3 && error.output?.stderr.includes("EOTP")) {
|
|
6357
6447
|
return false;
|
|
6358
6448
|
}
|
|
6359
6449
|
throw this.classifyPublishError(error);
|
|
6360
6450
|
}
|
|
6361
6451
|
}
|
|
6452
|
+
async dryRunPublish() {
|
|
6453
|
+
try {
|
|
6454
|
+
await this.npm(["publish", "--dry-run"]);
|
|
6455
|
+
} catch (error) {
|
|
6456
|
+
throw this.classifyPublishError(error);
|
|
6457
|
+
}
|
|
6458
|
+
}
|
|
6459
|
+
async twoFactorAuthMode() {
|
|
6460
|
+
try {
|
|
6461
|
+
const output = await this.npm(["profile", "get", "--json"]);
|
|
6462
|
+
const profile = JSON.parse(output);
|
|
6463
|
+
return profile?.tfa?.mode ?? null;
|
|
6464
|
+
} catch {
|
|
6465
|
+
return null;
|
|
6466
|
+
}
|
|
6467
|
+
}
|
|
6362
6468
|
async isPackageNameAvaliable() {
|
|
6363
6469
|
return isValidPackageName(this.packageName);
|
|
6364
6470
|
}
|
|
@@ -6369,7 +6475,7 @@ var NpmRegistry = class extends Registry {
|
|
|
6369
6475
|
};
|
|
6370
6476
|
}
|
|
6371
6477
|
classifyPublishError(error) {
|
|
6372
|
-
if (error instanceof
|
|
6478
|
+
if (error instanceof NonZeroExitError3) {
|
|
6373
6479
|
const stderr = error.output?.stderr ?? "";
|
|
6374
6480
|
if (stderr.includes("EOTP")) {
|
|
6375
6481
|
return new NpmError("OTP required for publishing", { cause: error });
|
|
@@ -6395,7 +6501,71 @@ async function npmRegistry() {
|
|
|
6395
6501
|
return new NpmRegistry(packageJson.name);
|
|
6396
6502
|
}
|
|
6397
6503
|
|
|
6504
|
+
// src/tasks/dry-run-publish.ts
|
|
6505
|
+
var npmDryRunPublishTask = {
|
|
6506
|
+
title: "Dry-run npm publish",
|
|
6507
|
+
task: async (_, task) => {
|
|
6508
|
+
const npm = await npmRegistry();
|
|
6509
|
+
task.output = "Running npm publish --dry-run...";
|
|
6510
|
+
await npm.dryRunPublish();
|
|
6511
|
+
}
|
|
6512
|
+
};
|
|
6513
|
+
var jsrDryRunPublishTask = {
|
|
6514
|
+
title: "Dry-run jsr publish",
|
|
6515
|
+
skip: () => !JsrClient.token,
|
|
6516
|
+
task: async (_, task) => {
|
|
6517
|
+
const jsr = await jsrRegistry();
|
|
6518
|
+
task.output = "Running jsr publish --dry-run...";
|
|
6519
|
+
await jsr.dryRunPublish();
|
|
6520
|
+
}
|
|
6521
|
+
};
|
|
6522
|
+
function createCratesDryRunPublishTask(packagePath) {
|
|
6523
|
+
const label = packagePath ? ` (${packagePath})` : "";
|
|
6524
|
+
return {
|
|
6525
|
+
title: `Dry-run cargo publish${label}`,
|
|
6526
|
+
task: async (_, task) => {
|
|
6527
|
+
const eco = new RustEcosystem(packagePath ?? process.cwd());
|
|
6528
|
+
const packageName = await eco.packageName();
|
|
6529
|
+
const registry = new CratesRegistry(packageName);
|
|
6530
|
+
task.output = "Running cargo publish --dry-run...";
|
|
6531
|
+
await registry.dryRunPublish(packagePath);
|
|
6532
|
+
}
|
|
6533
|
+
};
|
|
6534
|
+
}
|
|
6535
|
+
var cratesDryRunPublishTask = createCratesDryRunPublishTask();
|
|
6536
|
+
function registryDryRunTask(registryKey) {
|
|
6537
|
+
switch (registryKey) {
|
|
6538
|
+
case "npm":
|
|
6539
|
+
return npmDryRunPublishTask;
|
|
6540
|
+
case "jsr":
|
|
6541
|
+
return jsrDryRunPublishTask;
|
|
6542
|
+
case "crates":
|
|
6543
|
+
return cratesDryRunPublishTask;
|
|
6544
|
+
default:
|
|
6545
|
+
return npmDryRunPublishTask;
|
|
6546
|
+
}
|
|
6547
|
+
}
|
|
6548
|
+
var dryRunPublishTask = {
|
|
6549
|
+
title: "Validating publish (dry-run)",
|
|
6550
|
+
task: (ctx, parentTask) => {
|
|
6551
|
+
if (ctx.packages?.length) {
|
|
6552
|
+
const tasks = ctx.packages.flatMap(
|
|
6553
|
+
(pkg) => pkg.registries.map(
|
|
6554
|
+
(registryKey) => registryKey === "crates" ? createCratesDryRunPublishTask(pkg.path) : registryDryRunTask(registryKey)
|
|
6555
|
+
)
|
|
6556
|
+
);
|
|
6557
|
+
return parentTask.newListr(tasks, { concurrent: true });
|
|
6558
|
+
}
|
|
6559
|
+
return parentTask.newListr(collectRegistries(ctx).map(registryDryRunTask), {
|
|
6560
|
+
concurrent: true
|
|
6561
|
+
});
|
|
6562
|
+
}
|
|
6563
|
+
};
|
|
6564
|
+
|
|
6398
6565
|
// src/tasks/jsr.ts
|
|
6566
|
+
import process12 from "node:process";
|
|
6567
|
+
import { ListrEnquirerPromptAdapter } from "@listr2/prompt-adapter-enquirer";
|
|
6568
|
+
import npmCli from "@npmcli/promise-spawn";
|
|
6399
6569
|
var { open } = npmCli;
|
|
6400
6570
|
var JsrAvailableError = class extends AbstractError {
|
|
6401
6571
|
constructor(message, { cause } = {}) {
|
|
@@ -6628,7 +6798,6 @@ var NpmAvailableError = class extends AbstractError {
|
|
|
6628
6798
|
};
|
|
6629
6799
|
var npmAvailableCheckTasks = {
|
|
6630
6800
|
title: "Checking npm avaliable for publising",
|
|
6631
|
-
skip: (ctx) => !!ctx.preview,
|
|
6632
6801
|
task: async (ctx, task) => {
|
|
6633
6802
|
const npm = await npmRegistry();
|
|
6634
6803
|
if (!await npm.isLoggedIn()) {
|
|
@@ -6691,6 +6860,14 @@ var npmAvailableCheckTasks = {
|
|
|
6691
6860
|
More information: ${link2("npm naming rules", "https://github.com/npm/validate-npm-package-name?tab=readme-ov-file#naming-rules")}`
|
|
6692
6861
|
);
|
|
6693
6862
|
}
|
|
6863
|
+
if (!ctx.promptEnabled) {
|
|
6864
|
+
const tfaMode = await npm.twoFactorAuthMode();
|
|
6865
|
+
if (tfaMode === "auth-and-writes") {
|
|
6866
|
+
throw new NpmAvailableError(
|
|
6867
|
+
`npm account has 2FA enabled for writes (auth-and-writes). CI publish will fail with EOTP. Use an automation token or configure granular access token at https://www.npmjs.com/package/${npm.packageName}/access`
|
|
6868
|
+
);
|
|
6869
|
+
}
|
|
6870
|
+
}
|
|
6694
6871
|
}
|
|
6695
6872
|
};
|
|
6696
6873
|
var npmPublishTasks = {
|
|
@@ -7108,13 +7285,24 @@ function registryTask(registry) {
|
|
|
7108
7285
|
return npmPublishTasks;
|
|
7109
7286
|
}
|
|
7110
7287
|
}
|
|
7111
|
-
function collectPublishTasks(ctx) {
|
|
7288
|
+
async function collectPublishTasks(ctx) {
|
|
7112
7289
|
if (ctx.packages?.length) {
|
|
7113
|
-
|
|
7114
|
-
(pkg) => pkg.registries.map(
|
|
7115
|
-
(reg) => reg === "crates" ? createCratesPublishTask(pkg.path) : registryTask(reg)
|
|
7116
|
-
)
|
|
7290
|
+
const nonCratesTasks = ctx.packages.flatMap(
|
|
7291
|
+
(pkg) => pkg.registries.filter((reg) => reg !== "crates").map((reg) => registryTask(reg))
|
|
7117
7292
|
);
|
|
7293
|
+
const cratesPaths = ctx.packages.filter((pkg) => pkg.registries.includes("crates")).map((pkg) => pkg.path);
|
|
7294
|
+
if (cratesPaths.length === 0) {
|
|
7295
|
+
return nonCratesTasks;
|
|
7296
|
+
}
|
|
7297
|
+
const sortedPaths = await sortCratesByDependencyOrder(cratesPaths);
|
|
7298
|
+
const sequentialCratesTask = {
|
|
7299
|
+
title: "Publishing to crates.io (sequential)",
|
|
7300
|
+
task: (_ctx, task) => task.newListr(
|
|
7301
|
+
sortedPaths.map((p) => createCratesPublishTask(p)),
|
|
7302
|
+
{ concurrent: false }
|
|
7303
|
+
)
|
|
7304
|
+
};
|
|
7305
|
+
return [...nonCratesTasks, sequentialCratesTask];
|
|
7118
7306
|
}
|
|
7119
7307
|
return collectRegistries(ctx).map(registryTask);
|
|
7120
7308
|
}
|
|
@@ -7136,7 +7324,7 @@ async function run(options) {
|
|
|
7136
7324
|
await createListr(
|
|
7137
7325
|
options.publishOnly ? {
|
|
7138
7326
|
title: "Publishing",
|
|
7139
|
-
task: (ctx2, parentTask) => parentTask.newListr(collectPublishTasks(ctx2), {
|
|
7327
|
+
task: async (ctx2, parentTask) => parentTask.newListr(await collectPublishTasks(ctx2), {
|
|
7140
7328
|
concurrent: true
|
|
7141
7329
|
})
|
|
7142
7330
|
} : [
|
|
@@ -7174,6 +7362,10 @@ async function run(options) {
|
|
|
7174
7362
|
}
|
|
7175
7363
|
}
|
|
7176
7364
|
},
|
|
7365
|
+
{
|
|
7366
|
+
...dryRunPublishTask,
|
|
7367
|
+
skip: (ctx2) => options.skipPublish || !!ctx2.preview
|
|
7368
|
+
},
|
|
7177
7369
|
{
|
|
7178
7370
|
title: "Bumping version",
|
|
7179
7371
|
skip: (ctx2) => !!ctx2.preview,
|
|
@@ -7225,7 +7417,7 @@ async function run(options) {
|
|
|
7225
7417
|
{
|
|
7226
7418
|
skip: (ctx2) => options.skipPublish || !!ctx2.preview,
|
|
7227
7419
|
title: "Publishing",
|
|
7228
|
-
task: (ctx2, parentTask) => parentTask.newListr(collectPublishTasks(ctx2), {
|
|
7420
|
+
task: async (ctx2, parentTask) => parentTask.newListr(await collectPublishTasks(ctx2), {
|
|
7229
7421
|
concurrent: true
|
|
7230
7422
|
})
|
|
7231
7423
|
},
|
package/dist/index.cjs
CHANGED
|
@@ -4814,50 +4814,6 @@ function link2(text, url) {
|
|
|
4814
4814
|
return `\x1B]8;;${url}\x07${text}\x1B]8;;\x07`;
|
|
4815
4815
|
}
|
|
4816
4816
|
|
|
4817
|
-
// src/utils/rollback.ts
|
|
4818
|
-
var rollbacks = [];
|
|
4819
|
-
function addRollback(rollback2, context) {
|
|
4820
|
-
rollbacks.push({ fn: rollback2, ctx: context });
|
|
4821
|
-
}
|
|
4822
|
-
var called = false;
|
|
4823
|
-
async function rollback() {
|
|
4824
|
-
if (called) return void 0;
|
|
4825
|
-
called = true;
|
|
4826
|
-
if (rollbacks.length <= 0) return void 0;
|
|
4827
|
-
console.log("Rollback...");
|
|
4828
|
-
const results = await Promise.allSettled(
|
|
4829
|
-
rollbacks.map(({ fn, ctx }) => fn(ctx))
|
|
4830
|
-
);
|
|
4831
|
-
const failures = results.filter(
|
|
4832
|
-
(r) => r.status === "rejected"
|
|
4833
|
-
);
|
|
4834
|
-
if (failures.length > 0) {
|
|
4835
|
-
for (const failure of failures) {
|
|
4836
|
-
console.error(
|
|
4837
|
-
`Rollback operation failed: ${failure.reason instanceof Error ? failure.reason.message : failure.reason}`
|
|
4838
|
-
);
|
|
4839
|
-
}
|
|
4840
|
-
console.log(
|
|
4841
|
-
"Rollback completed with errors. Some operations may require manual recovery."
|
|
4842
|
-
);
|
|
4843
|
-
} else {
|
|
4844
|
-
console.log("Rollback completed");
|
|
4845
|
-
}
|
|
4846
|
-
}
|
|
4847
|
-
|
|
4848
|
-
// src/utils/listr.ts
|
|
4849
|
-
function createListr(...args) {
|
|
4850
|
-
const listr = new Listr(...args);
|
|
4851
|
-
listr.isRoot = () => false;
|
|
4852
|
-
listr.externalSignalHandler = rollback;
|
|
4853
|
-
return listr;
|
|
4854
|
-
}
|
|
4855
|
-
|
|
4856
|
-
// src/utils/package.ts
|
|
4857
|
-
var import_promises3 = require("fs/promises");
|
|
4858
|
-
var import_node_path3 = __toESM(require("path"), 1);
|
|
4859
|
-
var import_node_process5 = __toESM(require("process"), 1);
|
|
4860
|
-
|
|
4861
4817
|
// src/ecosystem/rust.ts
|
|
4862
4818
|
var import_promises2 = require("fs/promises");
|
|
4863
4819
|
var import_node_path2 = __toESM(require("path"), 1);
|
|
@@ -4904,6 +4860,17 @@ var RustEcosystem = class extends Ecosystem {
|
|
|
4904
4860
|
pkg.version = newVersion;
|
|
4905
4861
|
await (0, import_promises2.writeFile)(filePath, (0, import_smol_toml.stringify)(cargo));
|
|
4906
4862
|
}
|
|
4863
|
+
async dependencies() {
|
|
4864
|
+
const cargo = await this.readCargoToml();
|
|
4865
|
+
const deps = [];
|
|
4866
|
+
for (const section of ["dependencies", "build-dependencies"]) {
|
|
4867
|
+
const sectionData = cargo[section];
|
|
4868
|
+
if (sectionData) {
|
|
4869
|
+
deps.push(...Object.keys(sectionData));
|
|
4870
|
+
}
|
|
4871
|
+
}
|
|
4872
|
+
return deps;
|
|
4873
|
+
}
|
|
4907
4874
|
manifestFiles() {
|
|
4908
4875
|
return ["Cargo.toml"];
|
|
4909
4876
|
}
|
|
@@ -4918,7 +4885,96 @@ var RustEcosystem = class extends Ecosystem {
|
|
|
4918
4885
|
}
|
|
4919
4886
|
};
|
|
4920
4887
|
|
|
4888
|
+
// src/utils/crate-graph.ts
|
|
4889
|
+
async function sortCratesByDependencyOrder(cratePaths) {
|
|
4890
|
+
if (cratePaths.length <= 1) return cratePaths;
|
|
4891
|
+
const crateInfos = await Promise.all(
|
|
4892
|
+
cratePaths.map(async (cratePath) => {
|
|
4893
|
+
const eco = new RustEcosystem(cratePath);
|
|
4894
|
+
const name = await eco.packageName();
|
|
4895
|
+
const deps = await eco.dependencies();
|
|
4896
|
+
return { cratePath, name, deps };
|
|
4897
|
+
})
|
|
4898
|
+
);
|
|
4899
|
+
const nameSet = new Set(crateInfos.map((c) => c.name));
|
|
4900
|
+
const nameToPath = new Map(crateInfos.map((c) => [c.name, c.cratePath]));
|
|
4901
|
+
const internalDeps = /* @__PURE__ */ new Map();
|
|
4902
|
+
const inDegree = /* @__PURE__ */ new Map();
|
|
4903
|
+
for (const name of nameSet) {
|
|
4904
|
+
inDegree.set(name, 0);
|
|
4905
|
+
}
|
|
4906
|
+
for (const crate of crateInfos) {
|
|
4907
|
+
const filtered = crate.deps.filter((d2) => nameSet.has(d2));
|
|
4908
|
+
internalDeps.set(crate.name, filtered);
|
|
4909
|
+
for (const _dep of filtered) {
|
|
4910
|
+
inDegree.set(crate.name, (inDegree.get(crate.name) ?? 0) + 1);
|
|
4911
|
+
}
|
|
4912
|
+
}
|
|
4913
|
+
const queue = [];
|
|
4914
|
+
for (const [name, degree] of inDegree) {
|
|
4915
|
+
if (degree === 0) queue.push(name);
|
|
4916
|
+
}
|
|
4917
|
+
const sorted = [];
|
|
4918
|
+
while (queue.length > 0) {
|
|
4919
|
+
const current = queue.shift();
|
|
4920
|
+
sorted.push(current);
|
|
4921
|
+
for (const [name, deps] of internalDeps) {
|
|
4922
|
+
if (deps.includes(current)) {
|
|
4923
|
+
const newDegree = (inDegree.get(name) ?? 0) - 1;
|
|
4924
|
+
inDegree.set(name, newDegree);
|
|
4925
|
+
if (newDegree === 0) queue.push(name);
|
|
4926
|
+
}
|
|
4927
|
+
}
|
|
4928
|
+
}
|
|
4929
|
+
if (sorted.length !== nameSet.size) {
|
|
4930
|
+
throw new Error("Circular dependency detected among configured crates");
|
|
4931
|
+
}
|
|
4932
|
+
return sorted.map((name) => nameToPath.get(name));
|
|
4933
|
+
}
|
|
4934
|
+
|
|
4935
|
+
// src/utils/rollback.ts
|
|
4936
|
+
var rollbacks = [];
|
|
4937
|
+
function addRollback(rollback2, context) {
|
|
4938
|
+
rollbacks.push({ fn: rollback2, ctx: context });
|
|
4939
|
+
}
|
|
4940
|
+
var called = false;
|
|
4941
|
+
async function rollback() {
|
|
4942
|
+
if (called) return void 0;
|
|
4943
|
+
called = true;
|
|
4944
|
+
if (rollbacks.length <= 0) return void 0;
|
|
4945
|
+
console.log("Rollback...");
|
|
4946
|
+
const results = await Promise.allSettled(
|
|
4947
|
+
rollbacks.map(({ fn, ctx }) => fn(ctx))
|
|
4948
|
+
);
|
|
4949
|
+
const failures = results.filter(
|
|
4950
|
+
(r) => r.status === "rejected"
|
|
4951
|
+
);
|
|
4952
|
+
if (failures.length > 0) {
|
|
4953
|
+
for (const failure of failures) {
|
|
4954
|
+
console.error(
|
|
4955
|
+
`Rollback operation failed: ${failure.reason instanceof Error ? failure.reason.message : failure.reason}`
|
|
4956
|
+
);
|
|
4957
|
+
}
|
|
4958
|
+
console.log(
|
|
4959
|
+
"Rollback completed with errors. Some operations may require manual recovery."
|
|
4960
|
+
);
|
|
4961
|
+
} else {
|
|
4962
|
+
console.log("Rollback completed");
|
|
4963
|
+
}
|
|
4964
|
+
}
|
|
4965
|
+
|
|
4966
|
+
// src/utils/listr.ts
|
|
4967
|
+
function createListr(...args) {
|
|
4968
|
+
const listr = new Listr(...args);
|
|
4969
|
+
listr.isRoot = () => false;
|
|
4970
|
+
listr.externalSignalHandler = rollback;
|
|
4971
|
+
return listr;
|
|
4972
|
+
}
|
|
4973
|
+
|
|
4921
4974
|
// src/utils/package.ts
|
|
4975
|
+
var import_promises3 = require("fs/promises");
|
|
4976
|
+
var import_node_path3 = __toESM(require("path"), 1);
|
|
4977
|
+
var import_node_process5 = __toESM(require("process"), 1);
|
|
4922
4978
|
var cachedPackageJson = {};
|
|
4923
4979
|
var cachedJsrJson = {};
|
|
4924
4980
|
function patchCachedJsrJson(contents, { cwd = import_node_process5.default.cwd() } = {}) {
|
|
@@ -5161,6 +5217,8 @@ var Registry = class {
|
|
|
5161
5217
|
this.packageName = packageName;
|
|
5162
5218
|
this.registry = registry;
|
|
5163
5219
|
}
|
|
5220
|
+
async dryRunPublish(_manifestDir) {
|
|
5221
|
+
}
|
|
5164
5222
|
};
|
|
5165
5223
|
|
|
5166
5224
|
// src/registry/crates.ts
|
|
@@ -5235,9 +5293,24 @@ var CratesRegistry = class extends Registry {
|
|
|
5235
5293
|
await (0, import_tinyexec2.exec)("cargo", args, { throwOnError: true });
|
|
5236
5294
|
return true;
|
|
5237
5295
|
} catch (error) {
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5296
|
+
const stderr = error instanceof import_tinyexec2.NonZeroExitError ? error.output?.stderr : void 0;
|
|
5297
|
+
const message = stderr ? `Failed to run \`cargo publish\`:
|
|
5298
|
+
${stderr}` : "Failed to run `cargo publish`";
|
|
5299
|
+
throw new CratesError(message, { cause: error });
|
|
5300
|
+
}
|
|
5301
|
+
}
|
|
5302
|
+
async dryRunPublish(manifestDir) {
|
|
5303
|
+
try {
|
|
5304
|
+
const args = ["publish", "--dry-run"];
|
|
5305
|
+
if (manifestDir) {
|
|
5306
|
+
args.push("--manifest-path", import_node_path4.default.join(manifestDir, "Cargo.toml"));
|
|
5307
|
+
}
|
|
5308
|
+
await (0, import_tinyexec2.exec)("cargo", args, { throwOnError: true });
|
|
5309
|
+
} catch (error) {
|
|
5310
|
+
const stderr = error instanceof import_tinyexec2.NonZeroExitError ? error.output?.stderr : void 0;
|
|
5311
|
+
const message = stderr ? `Dry-run failed for \`cargo publish\`:
|
|
5312
|
+
${stderr}` : "Dry-run failed for `cargo publish`";
|
|
5313
|
+
throw new CratesError(message, { cause: error });
|
|
5241
5314
|
}
|
|
5242
5315
|
}
|
|
5243
5316
|
async isPublished() {
|
|
@@ -5326,11 +5399,6 @@ function createCratesPublishTask(packagePath) {
|
|
|
5326
5399
|
var cratesAvailableCheckTasks = createCratesAvailableCheckTask();
|
|
5327
5400
|
var cratesPublishTasks = createCratesPublishTask();
|
|
5328
5401
|
|
|
5329
|
-
// src/tasks/jsr.ts
|
|
5330
|
-
var import_node_process6 = __toESM(require("process"), 1);
|
|
5331
|
-
var import_prompt_adapter_enquirer = require("@listr2/prompt-adapter-enquirer");
|
|
5332
|
-
var import_promise_spawn = __toESM(require("@npmcli/promise-spawn"), 1);
|
|
5333
|
-
|
|
5334
5402
|
// src/registry/jsr.ts
|
|
5335
5403
|
var import_tinyexec3 = require("tinyexec");
|
|
5336
5404
|
|
|
@@ -5532,6 +5600,28 @@ ${stderr}` : ""}`,
|
|
|
5532
5600
|
);
|
|
5533
5601
|
}
|
|
5534
5602
|
}
|
|
5603
|
+
async dryRunPublish() {
|
|
5604
|
+
try {
|
|
5605
|
+
await (0, import_tinyexec3.exec)(
|
|
5606
|
+
"jsr",
|
|
5607
|
+
[
|
|
5608
|
+
"publish",
|
|
5609
|
+
"--dry-run",
|
|
5610
|
+
"--allow-dirty",
|
|
5611
|
+
"--token",
|
|
5612
|
+
`${JsrClient.token}`
|
|
5613
|
+
],
|
|
5614
|
+
{ throwOnError: true }
|
|
5615
|
+
);
|
|
5616
|
+
} catch (error) {
|
|
5617
|
+
const stderr = error instanceof import_tinyexec3.NonZeroExitError ? error.output?.stderr : void 0;
|
|
5618
|
+
throw new JsrError(
|
|
5619
|
+
`Dry-run failed for \`jsr publish\`${stderr ? `
|
|
5620
|
+
${stderr}` : ""}`,
|
|
5621
|
+
{ cause: error }
|
|
5622
|
+
);
|
|
5623
|
+
}
|
|
5624
|
+
}
|
|
5535
5625
|
async version() {
|
|
5536
5626
|
return await this.jsr(["--version"]);
|
|
5537
5627
|
}
|
|
@@ -5926,6 +6016,22 @@ var NpmRegistry = class extends Registry {
|
|
|
5926
6016
|
throw this.classifyPublishError(error);
|
|
5927
6017
|
}
|
|
5928
6018
|
}
|
|
6019
|
+
async dryRunPublish() {
|
|
6020
|
+
try {
|
|
6021
|
+
await this.npm(["publish", "--dry-run"]);
|
|
6022
|
+
} catch (error) {
|
|
6023
|
+
throw this.classifyPublishError(error);
|
|
6024
|
+
}
|
|
6025
|
+
}
|
|
6026
|
+
async twoFactorAuthMode() {
|
|
6027
|
+
try {
|
|
6028
|
+
const output = await this.npm(["profile", "get", "--json"]);
|
|
6029
|
+
const profile = JSON.parse(output);
|
|
6030
|
+
return profile?.tfa?.mode ?? null;
|
|
6031
|
+
} catch {
|
|
6032
|
+
return null;
|
|
6033
|
+
}
|
|
6034
|
+
}
|
|
5929
6035
|
async isPackageNameAvaliable() {
|
|
5930
6036
|
return isValidPackageName(this.packageName);
|
|
5931
6037
|
}
|
|
@@ -5962,7 +6068,71 @@ async function npmRegistry() {
|
|
|
5962
6068
|
return new NpmRegistry(packageJson.name);
|
|
5963
6069
|
}
|
|
5964
6070
|
|
|
6071
|
+
// src/tasks/dry-run-publish.ts
|
|
6072
|
+
var npmDryRunPublishTask = {
|
|
6073
|
+
title: "Dry-run npm publish",
|
|
6074
|
+
task: async (_, task) => {
|
|
6075
|
+
const npm = await npmRegistry();
|
|
6076
|
+
task.output = "Running npm publish --dry-run...";
|
|
6077
|
+
await npm.dryRunPublish();
|
|
6078
|
+
}
|
|
6079
|
+
};
|
|
6080
|
+
var jsrDryRunPublishTask = {
|
|
6081
|
+
title: "Dry-run jsr publish",
|
|
6082
|
+
skip: () => !JsrClient.token,
|
|
6083
|
+
task: async (_, task) => {
|
|
6084
|
+
const jsr = await jsrRegistry();
|
|
6085
|
+
task.output = "Running jsr publish --dry-run...";
|
|
6086
|
+
await jsr.dryRunPublish();
|
|
6087
|
+
}
|
|
6088
|
+
};
|
|
6089
|
+
function createCratesDryRunPublishTask(packagePath) {
|
|
6090
|
+
const label = packagePath ? ` (${packagePath})` : "";
|
|
6091
|
+
return {
|
|
6092
|
+
title: `Dry-run cargo publish${label}`,
|
|
6093
|
+
task: async (_, task) => {
|
|
6094
|
+
const eco = new RustEcosystem(packagePath ?? process.cwd());
|
|
6095
|
+
const packageName = await eco.packageName();
|
|
6096
|
+
const registry = new CratesRegistry(packageName);
|
|
6097
|
+
task.output = "Running cargo publish --dry-run...";
|
|
6098
|
+
await registry.dryRunPublish(packagePath);
|
|
6099
|
+
}
|
|
6100
|
+
};
|
|
6101
|
+
}
|
|
6102
|
+
var cratesDryRunPublishTask = createCratesDryRunPublishTask();
|
|
6103
|
+
function registryDryRunTask(registryKey) {
|
|
6104
|
+
switch (registryKey) {
|
|
6105
|
+
case "npm":
|
|
6106
|
+
return npmDryRunPublishTask;
|
|
6107
|
+
case "jsr":
|
|
6108
|
+
return jsrDryRunPublishTask;
|
|
6109
|
+
case "crates":
|
|
6110
|
+
return cratesDryRunPublishTask;
|
|
6111
|
+
default:
|
|
6112
|
+
return npmDryRunPublishTask;
|
|
6113
|
+
}
|
|
6114
|
+
}
|
|
6115
|
+
var dryRunPublishTask = {
|
|
6116
|
+
title: "Validating publish (dry-run)",
|
|
6117
|
+
task: (ctx, parentTask) => {
|
|
6118
|
+
if (ctx.packages?.length) {
|
|
6119
|
+
const tasks = ctx.packages.flatMap(
|
|
6120
|
+
(pkg) => pkg.registries.map(
|
|
6121
|
+
(registryKey) => registryKey === "crates" ? createCratesDryRunPublishTask(pkg.path) : registryDryRunTask(registryKey)
|
|
6122
|
+
)
|
|
6123
|
+
);
|
|
6124
|
+
return parentTask.newListr(tasks, { concurrent: true });
|
|
6125
|
+
}
|
|
6126
|
+
return parentTask.newListr(collectRegistries(ctx).map(registryDryRunTask), {
|
|
6127
|
+
concurrent: true
|
|
6128
|
+
});
|
|
6129
|
+
}
|
|
6130
|
+
};
|
|
6131
|
+
|
|
5965
6132
|
// src/tasks/jsr.ts
|
|
6133
|
+
var import_node_process6 = __toESM(require("process"), 1);
|
|
6134
|
+
var import_prompt_adapter_enquirer = require("@listr2/prompt-adapter-enquirer");
|
|
6135
|
+
var import_promise_spawn = __toESM(require("@npmcli/promise-spawn"), 1);
|
|
5966
6136
|
var { open } = import_promise_spawn.default;
|
|
5967
6137
|
var JsrAvailableError = class extends AbstractError {
|
|
5968
6138
|
constructor(message, { cause } = {}) {
|
|
@@ -6195,7 +6365,6 @@ var NpmAvailableError = class extends AbstractError {
|
|
|
6195
6365
|
};
|
|
6196
6366
|
var npmAvailableCheckTasks = {
|
|
6197
6367
|
title: "Checking npm avaliable for publising",
|
|
6198
|
-
skip: (ctx) => !!ctx.preview,
|
|
6199
6368
|
task: async (ctx, task) => {
|
|
6200
6369
|
const npm = await npmRegistry();
|
|
6201
6370
|
if (!await npm.isLoggedIn()) {
|
|
@@ -6258,6 +6427,14 @@ var npmAvailableCheckTasks = {
|
|
|
6258
6427
|
More information: ${link2("npm naming rules", "https://github.com/npm/validate-npm-package-name?tab=readme-ov-file#naming-rules")}`
|
|
6259
6428
|
);
|
|
6260
6429
|
}
|
|
6430
|
+
if (!ctx.promptEnabled) {
|
|
6431
|
+
const tfaMode = await npm.twoFactorAuthMode();
|
|
6432
|
+
if (tfaMode === "auth-and-writes") {
|
|
6433
|
+
throw new NpmAvailableError(
|
|
6434
|
+
`npm account has 2FA enabled for writes (auth-and-writes). CI publish will fail with EOTP. Use an automation token or configure granular access token at https://www.npmjs.com/package/${npm.packageName}/access`
|
|
6435
|
+
);
|
|
6436
|
+
}
|
|
6437
|
+
}
|
|
6261
6438
|
}
|
|
6262
6439
|
};
|
|
6263
6440
|
var npmPublishTasks = {
|
|
@@ -6676,13 +6853,24 @@ function registryTask(registry) {
|
|
|
6676
6853
|
return npmPublishTasks;
|
|
6677
6854
|
}
|
|
6678
6855
|
}
|
|
6679
|
-
function collectPublishTasks(ctx) {
|
|
6856
|
+
async function collectPublishTasks(ctx) {
|
|
6680
6857
|
if (ctx.packages?.length) {
|
|
6681
|
-
|
|
6682
|
-
(pkg) => pkg.registries.map(
|
|
6683
|
-
(reg) => reg === "crates" ? createCratesPublishTask(pkg.path) : registryTask(reg)
|
|
6684
|
-
)
|
|
6858
|
+
const nonCratesTasks = ctx.packages.flatMap(
|
|
6859
|
+
(pkg) => pkg.registries.filter((reg) => reg !== "crates").map((reg) => registryTask(reg))
|
|
6685
6860
|
);
|
|
6861
|
+
const cratesPaths = ctx.packages.filter((pkg) => pkg.registries.includes("crates")).map((pkg) => pkg.path);
|
|
6862
|
+
if (cratesPaths.length === 0) {
|
|
6863
|
+
return nonCratesTasks;
|
|
6864
|
+
}
|
|
6865
|
+
const sortedPaths = await sortCratesByDependencyOrder(cratesPaths);
|
|
6866
|
+
const sequentialCratesTask = {
|
|
6867
|
+
title: "Publishing to crates.io (sequential)",
|
|
6868
|
+
task: (_ctx, task) => task.newListr(
|
|
6869
|
+
sortedPaths.map((p) => createCratesPublishTask(p)),
|
|
6870
|
+
{ concurrent: false }
|
|
6871
|
+
)
|
|
6872
|
+
};
|
|
6873
|
+
return [...nonCratesTasks, sequentialCratesTask];
|
|
6686
6874
|
}
|
|
6687
6875
|
return collectRegistries(ctx).map(registryTask);
|
|
6688
6876
|
}
|
|
@@ -6704,7 +6892,7 @@ async function run(options) {
|
|
|
6704
6892
|
await createListr(
|
|
6705
6893
|
options.publishOnly ? {
|
|
6706
6894
|
title: "Publishing",
|
|
6707
|
-
task: (ctx2, parentTask) => parentTask.newListr(collectPublishTasks(ctx2), {
|
|
6895
|
+
task: async (ctx2, parentTask) => parentTask.newListr(await collectPublishTasks(ctx2), {
|
|
6708
6896
|
concurrent: true
|
|
6709
6897
|
})
|
|
6710
6898
|
} : [
|
|
@@ -6742,6 +6930,10 @@ async function run(options) {
|
|
|
6742
6930
|
}
|
|
6743
6931
|
}
|
|
6744
6932
|
},
|
|
6933
|
+
{
|
|
6934
|
+
...dryRunPublishTask,
|
|
6935
|
+
skip: (ctx2) => options.skipPublish || !!ctx2.preview
|
|
6936
|
+
},
|
|
6745
6937
|
{
|
|
6746
6938
|
title: "Bumping version",
|
|
6747
6939
|
skip: (ctx2) => !!ctx2.preview,
|
|
@@ -6793,7 +6985,7 @@ async function run(options) {
|
|
|
6793
6985
|
{
|
|
6794
6986
|
skip: (ctx2) => options.skipPublish || !!ctx2.preview,
|
|
6795
6987
|
title: "Publishing",
|
|
6796
|
-
task: (ctx2, parentTask) => parentTask.newListr(collectPublishTasks(ctx2), {
|
|
6988
|
+
task: async (ctx2, parentTask) => parentTask.newListr(await collectPublishTasks(ctx2), {
|
|
6797
6989
|
concurrent: true
|
|
6798
6990
|
})
|
|
6799
6991
|
},
|
package/dist/index.js
CHANGED
|
@@ -4781,50 +4781,6 @@ function link2(text, url) {
|
|
|
4781
4781
|
return `\x1B]8;;${url}\x07${text}\x1B]8;;\x07`;
|
|
4782
4782
|
}
|
|
4783
4783
|
|
|
4784
|
-
// src/utils/rollback.ts
|
|
4785
|
-
var rollbacks = [];
|
|
4786
|
-
function addRollback(rollback2, context) {
|
|
4787
|
-
rollbacks.push({ fn: rollback2, ctx: context });
|
|
4788
|
-
}
|
|
4789
|
-
var called = false;
|
|
4790
|
-
async function rollback() {
|
|
4791
|
-
if (called) return void 0;
|
|
4792
|
-
called = true;
|
|
4793
|
-
if (rollbacks.length <= 0) return void 0;
|
|
4794
|
-
console.log("Rollback...");
|
|
4795
|
-
const results = await Promise.allSettled(
|
|
4796
|
-
rollbacks.map(({ fn, ctx }) => fn(ctx))
|
|
4797
|
-
);
|
|
4798
|
-
const failures = results.filter(
|
|
4799
|
-
(r) => r.status === "rejected"
|
|
4800
|
-
);
|
|
4801
|
-
if (failures.length > 0) {
|
|
4802
|
-
for (const failure of failures) {
|
|
4803
|
-
console.error(
|
|
4804
|
-
`Rollback operation failed: ${failure.reason instanceof Error ? failure.reason.message : failure.reason}`
|
|
4805
|
-
);
|
|
4806
|
-
}
|
|
4807
|
-
console.log(
|
|
4808
|
-
"Rollback completed with errors. Some operations may require manual recovery."
|
|
4809
|
-
);
|
|
4810
|
-
} else {
|
|
4811
|
-
console.log("Rollback completed");
|
|
4812
|
-
}
|
|
4813
|
-
}
|
|
4814
|
-
|
|
4815
|
-
// src/utils/listr.ts
|
|
4816
|
-
function createListr(...args) {
|
|
4817
|
-
const listr = new Listr(...args);
|
|
4818
|
-
listr.isRoot = () => false;
|
|
4819
|
-
listr.externalSignalHandler = rollback;
|
|
4820
|
-
return listr;
|
|
4821
|
-
}
|
|
4822
|
-
|
|
4823
|
-
// src/utils/package.ts
|
|
4824
|
-
import { readFile as readFile2, stat as stat3, writeFile as writeFile2 } from "node:fs/promises";
|
|
4825
|
-
import path3 from "node:path";
|
|
4826
|
-
import process7 from "node:process";
|
|
4827
|
-
|
|
4828
4784
|
// src/ecosystem/rust.ts
|
|
4829
4785
|
import { readFile, stat as stat2, writeFile } from "node:fs/promises";
|
|
4830
4786
|
import path2 from "node:path";
|
|
@@ -4871,6 +4827,17 @@ var RustEcosystem = class extends Ecosystem {
|
|
|
4871
4827
|
pkg.version = newVersion;
|
|
4872
4828
|
await writeFile(filePath, stringify(cargo));
|
|
4873
4829
|
}
|
|
4830
|
+
async dependencies() {
|
|
4831
|
+
const cargo = await this.readCargoToml();
|
|
4832
|
+
const deps = [];
|
|
4833
|
+
for (const section of ["dependencies", "build-dependencies"]) {
|
|
4834
|
+
const sectionData = cargo[section];
|
|
4835
|
+
if (sectionData) {
|
|
4836
|
+
deps.push(...Object.keys(sectionData));
|
|
4837
|
+
}
|
|
4838
|
+
}
|
|
4839
|
+
return deps;
|
|
4840
|
+
}
|
|
4874
4841
|
manifestFiles() {
|
|
4875
4842
|
return ["Cargo.toml"];
|
|
4876
4843
|
}
|
|
@@ -4885,7 +4852,96 @@ var RustEcosystem = class extends Ecosystem {
|
|
|
4885
4852
|
}
|
|
4886
4853
|
};
|
|
4887
4854
|
|
|
4855
|
+
// src/utils/crate-graph.ts
|
|
4856
|
+
async function sortCratesByDependencyOrder(cratePaths) {
|
|
4857
|
+
if (cratePaths.length <= 1) return cratePaths;
|
|
4858
|
+
const crateInfos = await Promise.all(
|
|
4859
|
+
cratePaths.map(async (cratePath) => {
|
|
4860
|
+
const eco = new RustEcosystem(cratePath);
|
|
4861
|
+
const name = await eco.packageName();
|
|
4862
|
+
const deps = await eco.dependencies();
|
|
4863
|
+
return { cratePath, name, deps };
|
|
4864
|
+
})
|
|
4865
|
+
);
|
|
4866
|
+
const nameSet = new Set(crateInfos.map((c) => c.name));
|
|
4867
|
+
const nameToPath = new Map(crateInfos.map((c) => [c.name, c.cratePath]));
|
|
4868
|
+
const internalDeps = /* @__PURE__ */ new Map();
|
|
4869
|
+
const inDegree = /* @__PURE__ */ new Map();
|
|
4870
|
+
for (const name of nameSet) {
|
|
4871
|
+
inDegree.set(name, 0);
|
|
4872
|
+
}
|
|
4873
|
+
for (const crate of crateInfos) {
|
|
4874
|
+
const filtered = crate.deps.filter((d2) => nameSet.has(d2));
|
|
4875
|
+
internalDeps.set(crate.name, filtered);
|
|
4876
|
+
for (const _dep of filtered) {
|
|
4877
|
+
inDegree.set(crate.name, (inDegree.get(crate.name) ?? 0) + 1);
|
|
4878
|
+
}
|
|
4879
|
+
}
|
|
4880
|
+
const queue = [];
|
|
4881
|
+
for (const [name, degree] of inDegree) {
|
|
4882
|
+
if (degree === 0) queue.push(name);
|
|
4883
|
+
}
|
|
4884
|
+
const sorted = [];
|
|
4885
|
+
while (queue.length > 0) {
|
|
4886
|
+
const current = queue.shift();
|
|
4887
|
+
sorted.push(current);
|
|
4888
|
+
for (const [name, deps] of internalDeps) {
|
|
4889
|
+
if (deps.includes(current)) {
|
|
4890
|
+
const newDegree = (inDegree.get(name) ?? 0) - 1;
|
|
4891
|
+
inDegree.set(name, newDegree);
|
|
4892
|
+
if (newDegree === 0) queue.push(name);
|
|
4893
|
+
}
|
|
4894
|
+
}
|
|
4895
|
+
}
|
|
4896
|
+
if (sorted.length !== nameSet.size) {
|
|
4897
|
+
throw new Error("Circular dependency detected among configured crates");
|
|
4898
|
+
}
|
|
4899
|
+
return sorted.map((name) => nameToPath.get(name));
|
|
4900
|
+
}
|
|
4901
|
+
|
|
4902
|
+
// src/utils/rollback.ts
|
|
4903
|
+
var rollbacks = [];
|
|
4904
|
+
function addRollback(rollback2, context) {
|
|
4905
|
+
rollbacks.push({ fn: rollback2, ctx: context });
|
|
4906
|
+
}
|
|
4907
|
+
var called = false;
|
|
4908
|
+
async function rollback() {
|
|
4909
|
+
if (called) return void 0;
|
|
4910
|
+
called = true;
|
|
4911
|
+
if (rollbacks.length <= 0) return void 0;
|
|
4912
|
+
console.log("Rollback...");
|
|
4913
|
+
const results = await Promise.allSettled(
|
|
4914
|
+
rollbacks.map(({ fn, ctx }) => fn(ctx))
|
|
4915
|
+
);
|
|
4916
|
+
const failures = results.filter(
|
|
4917
|
+
(r) => r.status === "rejected"
|
|
4918
|
+
);
|
|
4919
|
+
if (failures.length > 0) {
|
|
4920
|
+
for (const failure of failures) {
|
|
4921
|
+
console.error(
|
|
4922
|
+
`Rollback operation failed: ${failure.reason instanceof Error ? failure.reason.message : failure.reason}`
|
|
4923
|
+
);
|
|
4924
|
+
}
|
|
4925
|
+
console.log(
|
|
4926
|
+
"Rollback completed with errors. Some operations may require manual recovery."
|
|
4927
|
+
);
|
|
4928
|
+
} else {
|
|
4929
|
+
console.log("Rollback completed");
|
|
4930
|
+
}
|
|
4931
|
+
}
|
|
4932
|
+
|
|
4933
|
+
// src/utils/listr.ts
|
|
4934
|
+
function createListr(...args) {
|
|
4935
|
+
const listr = new Listr(...args);
|
|
4936
|
+
listr.isRoot = () => false;
|
|
4937
|
+
listr.externalSignalHandler = rollback;
|
|
4938
|
+
return listr;
|
|
4939
|
+
}
|
|
4940
|
+
|
|
4888
4941
|
// src/utils/package.ts
|
|
4942
|
+
import { readFile as readFile2, stat as stat3, writeFile as writeFile2 } from "node:fs/promises";
|
|
4943
|
+
import path3 from "node:path";
|
|
4944
|
+
import process7 from "node:process";
|
|
4889
4945
|
var cachedPackageJson = {};
|
|
4890
4946
|
var cachedJsrJson = {};
|
|
4891
4947
|
function patchCachedJsrJson(contents, { cwd = process7.cwd() } = {}) {
|
|
@@ -5120,7 +5176,7 @@ function collectRegistries(ctx) {
|
|
|
5120
5176
|
|
|
5121
5177
|
// src/registry/crates.ts
|
|
5122
5178
|
import path4 from "node:path";
|
|
5123
|
-
import { exec as exec3 } from "tinyexec";
|
|
5179
|
+
import { exec as exec3, NonZeroExitError } from "tinyexec";
|
|
5124
5180
|
|
|
5125
5181
|
// src/registry/registry.ts
|
|
5126
5182
|
var Registry = class {
|
|
@@ -5128,6 +5184,8 @@ var Registry = class {
|
|
|
5128
5184
|
this.packageName = packageName;
|
|
5129
5185
|
this.registry = registry;
|
|
5130
5186
|
}
|
|
5187
|
+
async dryRunPublish(_manifestDir) {
|
|
5188
|
+
}
|
|
5131
5189
|
};
|
|
5132
5190
|
|
|
5133
5191
|
// src/registry/crates.ts
|
|
@@ -5202,9 +5260,24 @@ var CratesRegistry = class extends Registry {
|
|
|
5202
5260
|
await exec3("cargo", args, { throwOnError: true });
|
|
5203
5261
|
return true;
|
|
5204
5262
|
} catch (error) {
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
|
|
5263
|
+
const stderr = error instanceof NonZeroExitError ? error.output?.stderr : void 0;
|
|
5264
|
+
const message = stderr ? `Failed to run \`cargo publish\`:
|
|
5265
|
+
${stderr}` : "Failed to run `cargo publish`";
|
|
5266
|
+
throw new CratesError(message, { cause: error });
|
|
5267
|
+
}
|
|
5268
|
+
}
|
|
5269
|
+
async dryRunPublish(manifestDir) {
|
|
5270
|
+
try {
|
|
5271
|
+
const args = ["publish", "--dry-run"];
|
|
5272
|
+
if (manifestDir) {
|
|
5273
|
+
args.push("--manifest-path", path4.join(manifestDir, "Cargo.toml"));
|
|
5274
|
+
}
|
|
5275
|
+
await exec3("cargo", args, { throwOnError: true });
|
|
5276
|
+
} catch (error) {
|
|
5277
|
+
const stderr = error instanceof NonZeroExitError ? error.output?.stderr : void 0;
|
|
5278
|
+
const message = stderr ? `Dry-run failed for \`cargo publish\`:
|
|
5279
|
+
${stderr}` : "Dry-run failed for `cargo publish`";
|
|
5280
|
+
throw new CratesError(message, { cause: error });
|
|
5208
5281
|
}
|
|
5209
5282
|
}
|
|
5210
5283
|
async isPublished() {
|
|
@@ -5293,13 +5366,8 @@ function createCratesPublishTask(packagePath) {
|
|
|
5293
5366
|
var cratesAvailableCheckTasks = createCratesAvailableCheckTask();
|
|
5294
5367
|
var cratesPublishTasks = createCratesPublishTask();
|
|
5295
5368
|
|
|
5296
|
-
// src/tasks/jsr.ts
|
|
5297
|
-
import process8 from "node:process";
|
|
5298
|
-
import { ListrEnquirerPromptAdapter } from "@listr2/prompt-adapter-enquirer";
|
|
5299
|
-
import npmCli from "@npmcli/promise-spawn";
|
|
5300
|
-
|
|
5301
5369
|
// src/registry/jsr.ts
|
|
5302
|
-
import { exec as exec4, NonZeroExitError } from "tinyexec";
|
|
5370
|
+
import { exec as exec4, NonZeroExitError as NonZeroExitError2 } from "tinyexec";
|
|
5303
5371
|
|
|
5304
5372
|
// src/utils/db.ts
|
|
5305
5373
|
import { createCipheriv, createDecipheriv, createHash } from "node:crypto";
|
|
@@ -5478,7 +5546,7 @@ var JsrRegisry = class extends Registry {
|
|
|
5478
5546
|
this.packageCreationUrls = void 0;
|
|
5479
5547
|
return true;
|
|
5480
5548
|
} catch (error) {
|
|
5481
|
-
const stderr = error instanceof
|
|
5549
|
+
const stderr = error instanceof NonZeroExitError2 ? error.output?.stderr : void 0;
|
|
5482
5550
|
if (stderr?.includes("don't exist")) {
|
|
5483
5551
|
const urls = [...stderr.matchAll(/https:\/\/jsr\.io\/new\S+/g)].map(
|
|
5484
5552
|
(m) => m[0]
|
|
@@ -5497,6 +5565,28 @@ ${stderr}` : ""}`,
|
|
|
5497
5565
|
);
|
|
5498
5566
|
}
|
|
5499
5567
|
}
|
|
5568
|
+
async dryRunPublish() {
|
|
5569
|
+
try {
|
|
5570
|
+
await exec4(
|
|
5571
|
+
"jsr",
|
|
5572
|
+
[
|
|
5573
|
+
"publish",
|
|
5574
|
+
"--dry-run",
|
|
5575
|
+
"--allow-dirty",
|
|
5576
|
+
"--token",
|
|
5577
|
+
`${JsrClient.token}`
|
|
5578
|
+
],
|
|
5579
|
+
{ throwOnError: true }
|
|
5580
|
+
);
|
|
5581
|
+
} catch (error) {
|
|
5582
|
+
const stderr = error instanceof NonZeroExitError2 ? error.output?.stderr : void 0;
|
|
5583
|
+
throw new JsrError(
|
|
5584
|
+
`Dry-run failed for \`jsr publish\`${stderr ? `
|
|
5585
|
+
${stderr}` : ""}`,
|
|
5586
|
+
{ cause: error }
|
|
5587
|
+
);
|
|
5588
|
+
}
|
|
5589
|
+
}
|
|
5500
5590
|
async version() {
|
|
5501
5591
|
return await this.jsr(["--version"]);
|
|
5502
5592
|
}
|
|
@@ -5738,7 +5828,7 @@ async function jsrRegistry() {
|
|
|
5738
5828
|
}
|
|
5739
5829
|
|
|
5740
5830
|
// src/registry/npm.ts
|
|
5741
|
-
import { exec as exec5, NonZeroExitError as
|
|
5831
|
+
import { exec as exec5, NonZeroExitError as NonZeroExitError3 } from "tinyexec";
|
|
5742
5832
|
var NpmError = class extends AbstractError {
|
|
5743
5833
|
constructor() {
|
|
5744
5834
|
super(...arguments);
|
|
@@ -5795,7 +5885,7 @@ var NpmRegistry = class extends Registry {
|
|
|
5795
5885
|
await this.npm(["whoami"]);
|
|
5796
5886
|
return true;
|
|
5797
5887
|
} catch (error) {
|
|
5798
|
-
if (error instanceof
|
|
5888
|
+
if (error instanceof NonZeroExitError3) {
|
|
5799
5889
|
return false;
|
|
5800
5890
|
}
|
|
5801
5891
|
throw new NpmError("Failed to run `npm whoami`", { cause: error });
|
|
@@ -5873,7 +5963,7 @@ var NpmRegistry = class extends Registry {
|
|
|
5873
5963
|
await this.npm(["publish", "--provenance", "--access", "public"]);
|
|
5874
5964
|
return true;
|
|
5875
5965
|
} catch (error) {
|
|
5876
|
-
if (error instanceof
|
|
5966
|
+
if (error instanceof NonZeroExitError3 && error.output?.stderr.includes("EOTP")) {
|
|
5877
5967
|
return false;
|
|
5878
5968
|
}
|
|
5879
5969
|
throw this.classifyPublishError(error);
|
|
@@ -5885,12 +5975,28 @@ var NpmRegistry = class extends Registry {
|
|
|
5885
5975
|
await this.npm(args);
|
|
5886
5976
|
return true;
|
|
5887
5977
|
} catch (error) {
|
|
5888
|
-
if (error instanceof
|
|
5978
|
+
if (error instanceof NonZeroExitError3 && error.output?.stderr.includes("EOTP")) {
|
|
5889
5979
|
return false;
|
|
5890
5980
|
}
|
|
5891
5981
|
throw this.classifyPublishError(error);
|
|
5892
5982
|
}
|
|
5893
5983
|
}
|
|
5984
|
+
async dryRunPublish() {
|
|
5985
|
+
try {
|
|
5986
|
+
await this.npm(["publish", "--dry-run"]);
|
|
5987
|
+
} catch (error) {
|
|
5988
|
+
throw this.classifyPublishError(error);
|
|
5989
|
+
}
|
|
5990
|
+
}
|
|
5991
|
+
async twoFactorAuthMode() {
|
|
5992
|
+
try {
|
|
5993
|
+
const output = await this.npm(["profile", "get", "--json"]);
|
|
5994
|
+
const profile = JSON.parse(output);
|
|
5995
|
+
return profile?.tfa?.mode ?? null;
|
|
5996
|
+
} catch {
|
|
5997
|
+
return null;
|
|
5998
|
+
}
|
|
5999
|
+
}
|
|
5894
6000
|
async isPackageNameAvaliable() {
|
|
5895
6001
|
return isValidPackageName(this.packageName);
|
|
5896
6002
|
}
|
|
@@ -5901,7 +6007,7 @@ var NpmRegistry = class extends Registry {
|
|
|
5901
6007
|
};
|
|
5902
6008
|
}
|
|
5903
6009
|
classifyPublishError(error) {
|
|
5904
|
-
if (error instanceof
|
|
6010
|
+
if (error instanceof NonZeroExitError3) {
|
|
5905
6011
|
const stderr = error.output?.stderr ?? "";
|
|
5906
6012
|
if (stderr.includes("EOTP")) {
|
|
5907
6013
|
return new NpmError("OTP required for publishing", { cause: error });
|
|
@@ -5927,7 +6033,71 @@ async function npmRegistry() {
|
|
|
5927
6033
|
return new NpmRegistry(packageJson.name);
|
|
5928
6034
|
}
|
|
5929
6035
|
|
|
6036
|
+
// src/tasks/dry-run-publish.ts
|
|
6037
|
+
var npmDryRunPublishTask = {
|
|
6038
|
+
title: "Dry-run npm publish",
|
|
6039
|
+
task: async (_, task) => {
|
|
6040
|
+
const npm = await npmRegistry();
|
|
6041
|
+
task.output = "Running npm publish --dry-run...";
|
|
6042
|
+
await npm.dryRunPublish();
|
|
6043
|
+
}
|
|
6044
|
+
};
|
|
6045
|
+
var jsrDryRunPublishTask = {
|
|
6046
|
+
title: "Dry-run jsr publish",
|
|
6047
|
+
skip: () => !JsrClient.token,
|
|
6048
|
+
task: async (_, task) => {
|
|
6049
|
+
const jsr = await jsrRegistry();
|
|
6050
|
+
task.output = "Running jsr publish --dry-run...";
|
|
6051
|
+
await jsr.dryRunPublish();
|
|
6052
|
+
}
|
|
6053
|
+
};
|
|
6054
|
+
function createCratesDryRunPublishTask(packagePath) {
|
|
6055
|
+
const label = packagePath ? ` (${packagePath})` : "";
|
|
6056
|
+
return {
|
|
6057
|
+
title: `Dry-run cargo publish${label}`,
|
|
6058
|
+
task: async (_, task) => {
|
|
6059
|
+
const eco = new RustEcosystem(packagePath ?? process.cwd());
|
|
6060
|
+
const packageName = await eco.packageName();
|
|
6061
|
+
const registry = new CratesRegistry(packageName);
|
|
6062
|
+
task.output = "Running cargo publish --dry-run...";
|
|
6063
|
+
await registry.dryRunPublish(packagePath);
|
|
6064
|
+
}
|
|
6065
|
+
};
|
|
6066
|
+
}
|
|
6067
|
+
var cratesDryRunPublishTask = createCratesDryRunPublishTask();
|
|
6068
|
+
function registryDryRunTask(registryKey) {
|
|
6069
|
+
switch (registryKey) {
|
|
6070
|
+
case "npm":
|
|
6071
|
+
return npmDryRunPublishTask;
|
|
6072
|
+
case "jsr":
|
|
6073
|
+
return jsrDryRunPublishTask;
|
|
6074
|
+
case "crates":
|
|
6075
|
+
return cratesDryRunPublishTask;
|
|
6076
|
+
default:
|
|
6077
|
+
return npmDryRunPublishTask;
|
|
6078
|
+
}
|
|
6079
|
+
}
|
|
6080
|
+
var dryRunPublishTask = {
|
|
6081
|
+
title: "Validating publish (dry-run)",
|
|
6082
|
+
task: (ctx, parentTask) => {
|
|
6083
|
+
if (ctx.packages?.length) {
|
|
6084
|
+
const tasks = ctx.packages.flatMap(
|
|
6085
|
+
(pkg) => pkg.registries.map(
|
|
6086
|
+
(registryKey) => registryKey === "crates" ? createCratesDryRunPublishTask(pkg.path) : registryDryRunTask(registryKey)
|
|
6087
|
+
)
|
|
6088
|
+
);
|
|
6089
|
+
return parentTask.newListr(tasks, { concurrent: true });
|
|
6090
|
+
}
|
|
6091
|
+
return parentTask.newListr(collectRegistries(ctx).map(registryDryRunTask), {
|
|
6092
|
+
concurrent: true
|
|
6093
|
+
});
|
|
6094
|
+
}
|
|
6095
|
+
};
|
|
6096
|
+
|
|
5930
6097
|
// src/tasks/jsr.ts
|
|
6098
|
+
import process8 from "node:process";
|
|
6099
|
+
import { ListrEnquirerPromptAdapter } from "@listr2/prompt-adapter-enquirer";
|
|
6100
|
+
import npmCli from "@npmcli/promise-spawn";
|
|
5931
6101
|
var { open } = npmCli;
|
|
5932
6102
|
var JsrAvailableError = class extends AbstractError {
|
|
5933
6103
|
constructor(message, { cause } = {}) {
|
|
@@ -6160,7 +6330,6 @@ var NpmAvailableError = class extends AbstractError {
|
|
|
6160
6330
|
};
|
|
6161
6331
|
var npmAvailableCheckTasks = {
|
|
6162
6332
|
title: "Checking npm avaliable for publising",
|
|
6163
|
-
skip: (ctx) => !!ctx.preview,
|
|
6164
6333
|
task: async (ctx, task) => {
|
|
6165
6334
|
const npm = await npmRegistry();
|
|
6166
6335
|
if (!await npm.isLoggedIn()) {
|
|
@@ -6223,6 +6392,14 @@ var npmAvailableCheckTasks = {
|
|
|
6223
6392
|
More information: ${link2("npm naming rules", "https://github.com/npm/validate-npm-package-name?tab=readme-ov-file#naming-rules")}`
|
|
6224
6393
|
);
|
|
6225
6394
|
}
|
|
6395
|
+
if (!ctx.promptEnabled) {
|
|
6396
|
+
const tfaMode = await npm.twoFactorAuthMode();
|
|
6397
|
+
if (tfaMode === "auth-and-writes") {
|
|
6398
|
+
throw new NpmAvailableError(
|
|
6399
|
+
`npm account has 2FA enabled for writes (auth-and-writes). CI publish will fail with EOTP. Use an automation token or configure granular access token at https://www.npmjs.com/package/${npm.packageName}/access`
|
|
6400
|
+
);
|
|
6401
|
+
}
|
|
6402
|
+
}
|
|
6226
6403
|
}
|
|
6227
6404
|
};
|
|
6228
6405
|
var npmPublishTasks = {
|
|
@@ -6640,13 +6817,24 @@ function registryTask(registry) {
|
|
|
6640
6817
|
return npmPublishTasks;
|
|
6641
6818
|
}
|
|
6642
6819
|
}
|
|
6643
|
-
function collectPublishTasks(ctx) {
|
|
6820
|
+
async function collectPublishTasks(ctx) {
|
|
6644
6821
|
if (ctx.packages?.length) {
|
|
6645
|
-
|
|
6646
|
-
(pkg) => pkg.registries.map(
|
|
6647
|
-
(reg) => reg === "crates" ? createCratesPublishTask(pkg.path) : registryTask(reg)
|
|
6648
|
-
)
|
|
6822
|
+
const nonCratesTasks = ctx.packages.flatMap(
|
|
6823
|
+
(pkg) => pkg.registries.filter((reg) => reg !== "crates").map((reg) => registryTask(reg))
|
|
6649
6824
|
);
|
|
6825
|
+
const cratesPaths = ctx.packages.filter((pkg) => pkg.registries.includes("crates")).map((pkg) => pkg.path);
|
|
6826
|
+
if (cratesPaths.length === 0) {
|
|
6827
|
+
return nonCratesTasks;
|
|
6828
|
+
}
|
|
6829
|
+
const sortedPaths = await sortCratesByDependencyOrder(cratesPaths);
|
|
6830
|
+
const sequentialCratesTask = {
|
|
6831
|
+
title: "Publishing to crates.io (sequential)",
|
|
6832
|
+
task: (_ctx, task) => task.newListr(
|
|
6833
|
+
sortedPaths.map((p) => createCratesPublishTask(p)),
|
|
6834
|
+
{ concurrent: false }
|
|
6835
|
+
)
|
|
6836
|
+
};
|
|
6837
|
+
return [...nonCratesTasks, sequentialCratesTask];
|
|
6650
6838
|
}
|
|
6651
6839
|
return collectRegistries(ctx).map(registryTask);
|
|
6652
6840
|
}
|
|
@@ -6668,7 +6856,7 @@ async function run(options) {
|
|
|
6668
6856
|
await createListr(
|
|
6669
6857
|
options.publishOnly ? {
|
|
6670
6858
|
title: "Publishing",
|
|
6671
|
-
task: (ctx2, parentTask) => parentTask.newListr(collectPublishTasks(ctx2), {
|
|
6859
|
+
task: async (ctx2, parentTask) => parentTask.newListr(await collectPublishTasks(ctx2), {
|
|
6672
6860
|
concurrent: true
|
|
6673
6861
|
})
|
|
6674
6862
|
} : [
|
|
@@ -6706,6 +6894,10 @@ async function run(options) {
|
|
|
6706
6894
|
}
|
|
6707
6895
|
}
|
|
6708
6896
|
},
|
|
6897
|
+
{
|
|
6898
|
+
...dryRunPublishTask,
|
|
6899
|
+
skip: (ctx2) => options.skipPublish || !!ctx2.preview
|
|
6900
|
+
},
|
|
6709
6901
|
{
|
|
6710
6902
|
title: "Bumping version",
|
|
6711
6903
|
skip: (ctx2) => !!ctx2.preview,
|
|
@@ -6757,7 +6949,7 @@ async function run(options) {
|
|
|
6757
6949
|
{
|
|
6758
6950
|
skip: (ctx2) => options.skipPublish || !!ctx2.preview,
|
|
6759
6951
|
title: "Publishing",
|
|
6760
|
-
task: (ctx2, parentTask) => parentTask.newListr(collectPublishTasks(ctx2), {
|
|
6952
|
+
task: async (ctx2, parentTask) => parentTask.newListr(await collectPublishTasks(ctx2), {
|
|
6761
6953
|
concurrent: true
|
|
6762
6954
|
})
|
|
6763
6955
|
},
|