Dev #26

Open
overseer wants to merge 65 commits from dev into main
Showing only changes of commit 18db26c265 - Show all commits
+20 -5
View File
@@ -16,6 +16,21 @@ const VERSION = SHA.slice(0, 8);
const API = `${SERVER}/api/v1/repos/${REPO}`;
const H = { Authorization: `token ${TOKEN}` };
// The runner's network to Gitea is flaky (ECONNRESET mid-publish leaves a
// half-created release). Retry transient fetch failures so the multi-step
// publish is atomic-enough in practice.
const rfetch = async (url, opts = {}, tries = 4) => {
for (let i = 1; ; i++) {
try {
return await fetch(url, opts);
} catch (e) {
if (i >= tries) throw e;
console.log(`fetch ${url} failed (${e.cause?.code || e.message}); retry ${i}/${tries - 1}`);
await new Promise((r) => setTimeout(r, 1000 * i));
}
}
};
const ok = async (r) => {
if (!r.ok) throw new Error(`${r.status} ${r.url}\n${await r.text()}`);
const t = await r.text();
@@ -31,14 +46,14 @@ const files = {
};
// Roll the release forward to this commit: delete the old release + tag.
const existing = await fetch(`${API}/releases/tags/${TAG}`, { headers: H });
const existing = await rfetch(`${API}/releases/tags/${TAG}`, { headers: H });
if (existing.ok) {
const rel = await existing.json();
await fetch(`${API}/releases/${rel.id}`, { method: 'DELETE', headers: H });
await rfetch(`${API}/releases/${rel.id}`, { method: 'DELETE', headers: H });
}
await fetch(`${API}/tags/${TAG}`, { method: 'DELETE', headers: H }); // ignore if absent
await rfetch(`${API}/tags/${TAG}`, { method: 'DELETE', headers: H }); // ignore if absent
const rel = await ok(await fetch(`${API}/releases`, {
const rel = await ok(await rfetch(`${API}/releases`, {
method: 'POST',
headers: { ...H, 'Content-Type': 'application/json' },
body: JSON.stringify({
@@ -53,7 +68,7 @@ const rel = await ok(await fetch(`${API}/releases`, {
for (const [name, buf] of Object.entries(files)) {
const fd = new FormData();
fd.append('attachment', new Blob([buf]), name);
await ok(await fetch(`${API}/releases/${rel.id}/assets?name=${encodeURIComponent(name)}`, {
await ok(await rfetch(`${API}/releases/${rel.id}/assets?name=${encodeURIComponent(name)}`, {
method: 'POST', headers: H, body: fd,
}));
console.log(`uploaded ${name}`);