diff --git a/apps/desktop/scripts/release-codeberg.mjs b/apps/desktop/scripts/release-codeberg.mjs index 1cbc5b4f9d..e556b44a3a 100644 --- a/apps/desktop/scripts/release-codeberg.mjs +++ b/apps/desktop/scripts/release-codeberg.mjs @@ -77,18 +77,23 @@ async function main() { } const release = await getOrCreateRelease(); - const existing = new Map((release.assets ?? []).map((a) => [a.name, a.id])); + const existing = new Map((release.assets ?? []).map((a) => [a.name, a])); for (const file of files) { const name = basename(file); - if (existing.has(name)) { - await api(`/repos/${OWNER}/${REPO}/releases/${release.id}/assets/${existing.get(name)}`, { - method: "DELETE", - }); - } const filePath = join(distDir, file); - const sizeMB = (statSync(filePath).size / 1e6).toFixed(0); - process.stdout.write(`Uploading ${name} (${sizeMB} MB)... `); + const size = statSync(filePath).size; + const already = existing.get(name); + // Resume: skip assets already uploaded at the same size (lets a re-run + // finish where it left off instead of re-uploading everything). + if (already && already.size === size) { + console.log(`Skipping ${name} (already uploaded)`); + continue; + } + if (already) { + await api(`/repos/${OWNER}/${REPO}/releases/${release.id}/assets/${already.id}`, { method: "DELETE" }); + } + process.stdout.write(`Uploading ${name} (${(size / 1e6).toFixed(0)} MB)... `); // Upload via curl: Node's built-in fetch (undici) times out on large files // (UND_ERR_HEADERS_TIMEOUT). curl streams from disk with no such limit. execFileSync(