desktop: fix auto-update feed — Codeberg has no /releases/latest/download route
Forgejo/Codeberg 404s the GitHub-style latest/download path, so the feed baked into app-update.yml never worked (1.0.0/1.0.1 never saw updates). Point it at a rolling release on the fixed tag "updates" instead, and make release-codeberg.mjs sync latest.yml + the Windows installer to that release on every ship (channel files always replaced; curl retries added). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -54,17 +54,17 @@ async function api(path, init = {}) {
|
||||
return res;
|
||||
}
|
||||
|
||||
async function getOrCreateRelease() {
|
||||
let res = await api(`/repos/${OWNER}/${REPO}/releases/tags/${encodeURIComponent(tag)}`);
|
||||
async function getOrCreateRelease(tagName, { prerelease = false } = {}) {
|
||||
let res = await api(`/repos/${OWNER}/${REPO}/releases/tags/${encodeURIComponent(tagName)}`);
|
||||
if (res.status === 404) {
|
||||
res = await api(`/repos/${OWNER}/${REPO}/releases`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ tag_name: tag, name: tag, draft: false, prerelease: false }),
|
||||
body: JSON.stringify({ tag_name: tagName, name: tagName, draft: false, prerelease }),
|
||||
});
|
||||
console.log(`Created release ${tag}`);
|
||||
console.log(`Created release ${tagName}`);
|
||||
} else {
|
||||
console.log(`Reusing existing release ${tag}`);
|
||||
console.log(`Reusing existing release ${tagName}`);
|
||||
}
|
||||
return res.json();
|
||||
}
|
||||
@@ -79,7 +79,21 @@ async function main() {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const release = await getOrCreateRelease();
|
||||
const release = await getOrCreateRelease(tag);
|
||||
await syncAssets(release, files);
|
||||
|
||||
// Forgejo/Codeberg has NO GitHub-style /releases/latest/download/ route, so
|
||||
// app-update.yml points at a rolling release on the fixed tag "updates" —
|
||||
// re-point its channel file + Windows installer at the build we just shipped.
|
||||
const updaterFiles = files.filter((f) => f === "latest.yml" || /\.(exe|exe\.blockmap)$/.test(f));
|
||||
const updates = await getOrCreateRelease("updates", { prerelease: true });
|
||||
await syncAssets(updates, updaterFiles);
|
||||
|
||||
const webBase = API.replace(/\/api\/v1\/?$/, "");
|
||||
console.log(`\nDone. Updater feed: ${webBase}/${OWNER}/${REPO}/releases/download/updates/latest.yml`);
|
||||
}
|
||||
|
||||
async function syncAssets(release, files) {
|
||||
const existing = new Map((release.assets ?? []).map((a) => [a.name, a]));
|
||||
|
||||
for (const file of files) {
|
||||
@@ -88,8 +102,9 @@ async function main() {
|
||||
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) {
|
||||
// finish where it left off instead of re-uploading everything). Channel
|
||||
// files are tiny and change meaning per build — always replace those.
|
||||
if (already && already.size === size && !CHANNEL_FILES.has(name)) {
|
||||
console.log(`Skipping ${name} (already uploaded)`);
|
||||
continue;
|
||||
}
|
||||
@@ -104,6 +119,9 @@ async function main() {
|
||||
[
|
||||
"-sS",
|
||||
"--fail-with-body",
|
||||
"--retry",
|
||||
"4",
|
||||
"--retry-all-errors",
|
||||
"-X",
|
||||
"POST",
|
||||
"-H",
|
||||
@@ -116,9 +134,6 @@ async function main() {
|
||||
);
|
||||
console.log("done");
|
||||
}
|
||||
|
||||
const webBase = API.replace(/\/api\/v1\/?$/, "");
|
||||
console.log(`\nDone. Updater feed: ${webBase}/${OWNER}/${REPO}/releases/latest/download/latest.yml`);
|
||||
}
|
||||
|
||||
await main();
|
||||
|
||||
Reference in New Issue
Block a user