@ucdjs/release-scripts 0.1.0-beta.52 → 0.1.0-beta.54
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +87 -19
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -569,6 +569,63 @@ function toGitError(operation, error) {
|
|
|
569
569
|
stderr: formatted.stderr
|
|
570
570
|
};
|
|
571
571
|
}
|
|
572
|
+
function isMissingGitIdentityError(error) {
|
|
573
|
+
const formatted = formatUnknownError(error);
|
|
574
|
+
const combined = `${formatted.message}\n${formatted.stderr ?? ""}`;
|
|
575
|
+
return combined.includes("Author identity unknown") || combined.includes("empty ident name") || combined.includes("Please tell me who you are");
|
|
576
|
+
}
|
|
577
|
+
async function ensureLocalGitIdentity(workspaceRoot) {
|
|
578
|
+
try {
|
|
579
|
+
const actor = process.env.GITHUB_ACTOR?.trim();
|
|
580
|
+
const name = process.env.GIT_AUTHOR_NAME?.trim() || process.env.GIT_COMMITTER_NAME?.trim() || actor || "github-actions[bot]";
|
|
581
|
+
const email = process.env.GIT_AUTHOR_EMAIL?.trim() || process.env.GIT_COMMITTER_EMAIL?.trim() || (actor ? `${actor}@users.noreply.github.com` : "github-actions[bot]@users.noreply.github.com");
|
|
582
|
+
logger.warn("Git author identity missing. Configuring repository-local git identity for this run.");
|
|
583
|
+
await runIfNotDry("git", [
|
|
584
|
+
"config",
|
|
585
|
+
"user.name",
|
|
586
|
+
name
|
|
587
|
+
], { nodeOptions: {
|
|
588
|
+
cwd: workspaceRoot,
|
|
589
|
+
stdio: "pipe"
|
|
590
|
+
} });
|
|
591
|
+
await runIfNotDry("git", [
|
|
592
|
+
"config",
|
|
593
|
+
"user.email",
|
|
594
|
+
email
|
|
595
|
+
], { nodeOptions: {
|
|
596
|
+
cwd: workspaceRoot,
|
|
597
|
+
stdio: "pipe"
|
|
598
|
+
} });
|
|
599
|
+
logger.info(`Configured git identity: ${farver.dim(`${name} <${email}>`)}`);
|
|
600
|
+
return ok(void 0);
|
|
601
|
+
} catch (error) {
|
|
602
|
+
return err(toGitError("ensureLocalGitIdentity", error));
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
async function commitWithRetryOnMissingIdentity(message, workspaceRoot, operation) {
|
|
606
|
+
const runCommit = async () => runIfNotDry("git", [
|
|
607
|
+
"commit",
|
|
608
|
+
"-m",
|
|
609
|
+
message
|
|
610
|
+
], { nodeOptions: {
|
|
611
|
+
cwd: workspaceRoot,
|
|
612
|
+
stdio: "pipe"
|
|
613
|
+
} });
|
|
614
|
+
try {
|
|
615
|
+
await runCommit();
|
|
616
|
+
return ok(void 0);
|
|
617
|
+
} catch (error) {
|
|
618
|
+
if (!isMissingGitIdentityError(error)) return err(toGitError(operation, error));
|
|
619
|
+
const configured = await ensureLocalGitIdentity(workspaceRoot);
|
|
620
|
+
if (!configured.ok) return configured;
|
|
621
|
+
try {
|
|
622
|
+
await runCommit();
|
|
623
|
+
return ok(void 0);
|
|
624
|
+
} catch (retryError) {
|
|
625
|
+
return err(toGitError(operation, retryError));
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
572
629
|
async function isWorkingDirectoryClean(workspaceRoot) {
|
|
573
630
|
try {
|
|
574
631
|
return ok((await run("git", ["status", "--porcelain"], { nodeOptions: {
|
|
@@ -725,14 +782,8 @@ async function commitChanges(message, workspaceRoot) {
|
|
|
725
782
|
const isClean = await isWorkingDirectoryClean(workspaceRoot);
|
|
726
783
|
if (!isClean.ok || isClean.value) return ok(false);
|
|
727
784
|
logger.info(`Committing changes: ${farver.dim(message)}`);
|
|
728
|
-
await
|
|
729
|
-
|
|
730
|
-
"-m",
|
|
731
|
-
message
|
|
732
|
-
], { nodeOptions: {
|
|
733
|
-
cwd: workspaceRoot,
|
|
734
|
-
stdio: "pipe"
|
|
735
|
-
} });
|
|
785
|
+
const committed = await commitWithRetryOnMissingIdentity(message, workspaceRoot, "commitChanges");
|
|
786
|
+
if (!committed.ok) return committed;
|
|
736
787
|
return ok(true);
|
|
737
788
|
} catch (error) {
|
|
738
789
|
const gitError = toGitError("commitChanges", error);
|
|
@@ -761,14 +812,8 @@ async function commitPaths(paths, message, workspaceRoot) {
|
|
|
761
812
|
stdio: "pipe"
|
|
762
813
|
} })).stdout.trim() === "") return ok(false);
|
|
763
814
|
logger.info(`Committing changes: ${farver.dim(message)}`);
|
|
764
|
-
await
|
|
765
|
-
|
|
766
|
-
"-m",
|
|
767
|
-
message
|
|
768
|
-
], { nodeOptions: {
|
|
769
|
-
cwd: workspaceRoot,
|
|
770
|
-
stdio: "pipe"
|
|
771
|
-
} });
|
|
815
|
+
const committed = await commitWithRetryOnMissingIdentity(message, workspaceRoot, "commitPaths");
|
|
816
|
+
if (!committed.ok) return committed;
|
|
772
817
|
return ok(true);
|
|
773
818
|
} catch (error) {
|
|
774
819
|
const gitError = toGitError("commitPaths", error);
|
|
@@ -2257,6 +2302,16 @@ function toNPMError(operation, error, code) {
|
|
|
2257
2302
|
status: formatted.status
|
|
2258
2303
|
};
|
|
2259
2304
|
}
|
|
2305
|
+
function classifyPublishErrorCode(error) {
|
|
2306
|
+
const formatted = formatUnknownError(error);
|
|
2307
|
+
const combined = [formatted.message, formatted.stderr].filter(Boolean).join("\n");
|
|
2308
|
+
if (combined.includes("E403") || combined.toLowerCase().includes("access token expired or revoked")) return "E403";
|
|
2309
|
+
if (combined.includes("EPUBLISHCONFLICT") || combined.includes("E409") || combined.includes("409 Conflict") || combined.includes("Failed to save packument")) return "EPUBLISHCONFLICT";
|
|
2310
|
+
if (combined.includes("EOTP")) return "EOTP";
|
|
2311
|
+
}
|
|
2312
|
+
function wait(ms) {
|
|
2313
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
2314
|
+
}
|
|
2260
2315
|
/**
|
|
2261
2316
|
* Get the NPM registry URL
|
|
2262
2317
|
* Respects NPM_CONFIG_REGISTRY environment variable, defaults to npmjs.org
|
|
@@ -2328,7 +2383,13 @@ async function publishPackage(packageName, version, workspaceRoot, options) {
|
|
|
2328
2383
|
if (publishTag) args.push("--tag", publishTag);
|
|
2329
2384
|
const env = { ...process.env };
|
|
2330
2385
|
if (options.npm.provenance) env.NPM_CONFIG_PROVENANCE = "true";
|
|
2331
|
-
|
|
2386
|
+
const maxAttempts = 4;
|
|
2387
|
+
const backoffMs = [
|
|
2388
|
+
3e3,
|
|
2389
|
+
8e3,
|
|
2390
|
+
15e3
|
|
2391
|
+
];
|
|
2392
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) try {
|
|
2332
2393
|
await runIfNotDry("pnpm", args, { nodeOptions: {
|
|
2333
2394
|
cwd: workspaceRoot,
|
|
2334
2395
|
stdio: "inherit",
|
|
@@ -2336,9 +2397,16 @@ async function publishPackage(packageName, version, workspaceRoot, options) {
|
|
|
2336
2397
|
} });
|
|
2337
2398
|
return ok(void 0);
|
|
2338
2399
|
} catch (error) {
|
|
2339
|
-
const
|
|
2340
|
-
|
|
2400
|
+
const code = classifyPublishErrorCode(error);
|
|
2401
|
+
if (code === "EPUBLISHCONFLICT" && attempt < maxAttempts) {
|
|
2402
|
+
const delay = backoffMs[attempt - 1] ?? backoffMs[backoffMs.length - 1];
|
|
2403
|
+
logger.warn(`Publish conflict for ${packageName}@${version} (attempt ${attempt}/${maxAttempts}). Retrying in ${Math.ceil(delay / 1e3)}s...`);
|
|
2404
|
+
await wait(delay);
|
|
2405
|
+
continue;
|
|
2406
|
+
}
|
|
2407
|
+
return err(toNPMError("publishPackage", error, code));
|
|
2341
2408
|
}
|
|
2409
|
+
return err(toNPMError("publishPackage", /* @__PURE__ */ new Error(`Failed to publish ${packageName}@${version} after ${maxAttempts} attempts`), "EPUBLISHCONFLICT"));
|
|
2342
2410
|
}
|
|
2343
2411
|
|
|
2344
2412
|
//#endregion
|