mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
* fix(ci): retry npm installs Transient registry and package-download failures should delay a job briefly instead of requiring a manual rerun. Apply one bounded retry policy across CI, deploy, and release workflows. * fix(ci): preserve retries for historical Android tags Manual Android rebuilds may check out releases from before the shared retry script existed. Keep that install step self-contained and allow the shared helper's injected runner to be asynchronous. * fix(ci): preserve retries for desktop release refs * refactor(ci): use shared npm retry helper everywhere
60 lines
1.5 KiB
JavaScript
60 lines
1.5 KiB
JavaScript
import { spawnSync } from "node:child_process";
|
|
import { resolve as resolvePath } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const DEFAULT_ATTEMPTS = 3;
|
|
const DEFAULT_BACKOFF_MS = 20_000;
|
|
|
|
function runNpm(args) {
|
|
const command = process.platform === "win32" ? "npm.cmd" : "npm";
|
|
const result = spawnSync(command, args, {
|
|
shell: process.platform === "win32",
|
|
stdio: "inherit",
|
|
});
|
|
|
|
if (result.error) {
|
|
console.error(`Failed to start npm: ${result.error.message}`);
|
|
return 1;
|
|
}
|
|
|
|
return result.status ?? 1;
|
|
}
|
|
|
|
function wait(delayMs) {
|
|
return new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
}
|
|
|
|
export async function runWithRetry(
|
|
args,
|
|
{ attempts = DEFAULT_ATTEMPTS, backoffMs = DEFAULT_BACKOFF_MS, run = runNpm, sleep = wait } = {},
|
|
) {
|
|
let exitCode = 1;
|
|
|
|
for (let attempt = 1; attempt <= attempts; attempt += 1) {
|
|
exitCode = await run(args);
|
|
if (exitCode === 0) {
|
|
return 0;
|
|
}
|
|
|
|
if (attempt < attempts) {
|
|
const delayMs = attempt * backoffMs;
|
|
console.warn(
|
|
`npm failed with exit code ${exitCode}; retrying in ${delayMs / 1000}s (${attempt + 1}/${attempts})`,
|
|
);
|
|
await sleep(delayMs);
|
|
}
|
|
}
|
|
|
|
return exitCode;
|
|
}
|
|
|
|
if (process.argv[1] && fileURLToPath(import.meta.url) === resolvePath(process.argv[1])) {
|
|
const args = process.argv.slice(2);
|
|
if (args.length === 0) {
|
|
console.error("Usage: node scripts/npm-retry.mjs <npm arguments...>");
|
|
process.exitCode = 2;
|
|
} else {
|
|
process.exitCode = await runWithRetry(args);
|
|
}
|
|
}
|