Files
paseo/scripts/upload-release-assets.test.mjs
Mohamed Boudra 3cc4ae2866 ci(desktop): retry release asset uploads
uploads.github.com returned HTTP 500 five times during the v0.9.0-beta.1
release, each costing a ~50 minute rebuild. The upload step passed every
artifact to one gh invocation, so a single failed asset discarded the rest
and failed the job.

Upload each asset separately with bounded retries, shared by the macOS,
Linux and Windows jobs.
2026-09-17 22:50:13 +02:00

55 lines
1.5 KiB
JavaScript

import assert from "node:assert/strict";
import test from "node:test";
import { collectAssets, uploadWithRetry } from "./upload-release-assets.mjs";
const noSleep = () => Promise.resolve();
test("retries a failing asset and keeps its siblings", async () => {
const calls = [];
const exitCodes = { "a.dmg": [1, 1, 0], "b.zip": [0] };
const exitCode = await uploadWithRetry(
{ release: "rel", files: ["a.dmg", "b.zip"], repo: "getpaseo/paseo" },
{
sleep: noSleep,
upload: ({ file }) => {
calls.push(file);
return exitCodes[file].shift();
},
},
);
assert.equal(exitCode, 0);
assert.deepEqual(calls, ["a.dmg", "a.dmg", "a.dmg", "b.zip"]);
});
test("gives up after the attempt limit and reports failure", async () => {
let calls = 0;
const exitCode = await uploadWithRetry(
{ release: "rel", files: ["a.dmg", "b.zip"], repo: "getpaseo/paseo" },
{
attempts: 3,
sleep: noSleep,
upload: () => {
calls += 1;
return 1;
},
},
);
assert.equal(exitCode, 1);
// Stops at the first unrecoverable file rather than attempting b.zip.
assert.equal(calls, 3);
});
test("collects release files and skips manifests", () => {
const files = collectAssets("/release", {
readDir: () => ["Paseo.dmg", "beta-mac.yml", "Paseo.zip", "nested"],
stat: (file) => ({ isFile: () => !file.endsWith("nested") }),
});
assert.deepEqual(files, ["/release/Paseo.dmg", "/release/Paseo.zip"]);
});