feat(release): publish desktop updates from a tag through one feed

Desktop clients had two competing update sources: the runtime pointed at a
legacy GitLab registry while the Forgejo packages were filled in by
hardcoded, version-pinned scripts. Operators could not tell which feed was
authoritative, and no release could be reproduced from a tag.

Auto-update now reads a single canonical Forgejo registry feed, updated by
a version-agnostic publisher that runs from the tag on Forgejo, GitLab, and
GitHub CI alike. Channel, minimum supported version, forced install,
full-versus-delta thresholds, staged rollout, and a remote kill switch come
from one policy file the client fetches alongside the feed. Tag creation is
gated on a clean tree, matching version surfaces, and a changelog section.
This commit is contained in:
Yun Chan 2026-09-16 23:23:00 +09:00
parent 65ecc7aabc
commit 7953706142
21 changed files with 1619 additions and 90 deletions

View file

@ -100,8 +100,10 @@ for (const file of latestFiles) {
await uploadFile(file, `${latestPackageBaseUrl}/${encodeURIComponent(registryName)}`, "latest package");
}
for (const file of latestFiles.filter((candidate) => isUpdateMetadata(candidate.name))) {
for (const file of latestFiles.filter((candidate) => isYamlUpdateMetadata(candidate.name))) {
validateUpdateMetadataReferences(file, latestFiles);
}
for (const file of latestFiles.filter((candidate) => isUpdateMetadata(candidate.name))) {
await verifyPublicLatestFile(file, latestPackageBaseUrl);
}
@ -128,6 +130,10 @@ function isUpdateMetadata(name) {
return /(?:\.blockmap$|^(?:latest|alpha|beta)(?:-mac|-linux)?\.yml$)/.test(name);
}
function isYamlUpdateMetadata(name) {
return /^(?:latest|alpha|beta)(?:-mac|-linux)?\.yml$/.test(name);
}
async function buildDescription() {
const changelog = await readFile(
fileURLToPath(new URL("../../CHANGELOG.md", import.meta.url)),