From 64a0c66e9c622cf7db34e5aeef073914eada4b4d Mon Sep 17 00:00:00 2001 From: Antonella Sgarlatta Date: Fri, 9 Oct 2026 00:29:36 -0300 Subject: [PATCH] chore: Fixes auto-update issues due to overwritten latest.yml files --- .github/workflows/desktop.release.reuse.yml | 17 +++- .../scripts/merge-update-manifests.mjs | 81 +++++++++++++++++++ 2 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 packages/desktop/scripts/merge-update-manifests.mjs diff --git a/.github/workflows/desktop.release.reuse.yml b/.github/workflows/desktop.release.reuse.yml index 44d4ef0d471..f13e32c7e4f 100644 --- a/.github/workflows/desktop.release.reuse.yml +++ b/.github/workflows/desktop.release.reuse.yml @@ -42,8 +42,11 @@ jobs: run: | yarn run electron-builder --mac --x64 --publish=never --c.extraMetadata.version=${{ env.APP_VERSION }} node scripts/fixMacZip.js ${{ env.APP_VERSION }} + mkdir -p dist/update-meta && cp dist/latest-mac.yml dist/update-meta/mac-x64.yml - name: MacArm64 - run: yarn run electron-builder --mac --arm64 --publish=never --c.extraMetadata.version=${{ env.APP_VERSION }} + run: | + yarn run electron-builder --mac --arm64 --publish=never --c.extraMetadata.version=${{ env.APP_VERSION }} + mkdir -p dist/update-meta && cp dist/latest-mac.yml dist/update-meta/mac-arm64.yml - name: Upload uses: actions/upload-artifact@v4.0.0 @@ -55,6 +58,7 @@ jobs: packages/desktop/dist/*.blockmap packages/desktop/dist/*.yml packages/desktop/dist/*.yaml + packages/desktop/dist/update-meta/** Linux-AppImage-X64: name: Linux AppImage X64 @@ -91,6 +95,7 @@ jobs: - name: AppImageX64 run: | yarn run electron-builder --linux --x64 -c.linux.target=AppImage --publish=never --c.extraMetadata.version=${{ env.APP_VERSION }} + mkdir -p dist/update-meta && cp dist/latest-linux.yml dist/update-meta/linux-appimage-x64.yml - name: Upload uses: actions/upload-artifact@v4.0.0 @@ -100,6 +105,7 @@ jobs: packages/desktop/dist/*.AppImage packages/desktop/dist/*.yml packages/desktop/dist/*.yaml + packages/desktop/dist/update-meta/** Linux-AppImage-ARM64: name: Linux AppImage ARM64 @@ -136,6 +142,7 @@ jobs: - name: AppImageArm64 run: | yarn run electron-builder --linux --arm64 -c.linux.target=AppImage --publish=never --c.extraMetadata.version=${{ env.APP_VERSION }} + mkdir -p dist/update-meta && cp dist/latest-linux-arm64.yml dist/update-meta/linux-appimage-arm64.yml - name: Upload uses: actions/upload-artifact@v4.0.0 @@ -145,6 +152,7 @@ jobs: packages/desktop/dist/*.AppImage packages/desktop/dist/*.yml packages/desktop/dist/*.yaml + packages/desktop/dist/update-meta/** Linux-Dir-X64: name: Linux Dir X64 @@ -247,6 +255,7 @@ jobs: run: | yarn run webpack --config desktop.webpack.prod.js --env deb yarn run electron-builder --linux --x64 -c.linux.target=deb --publish=never --c.extraMetadata.version=${{ env.APP_VERSION }} + mkdir -p dist/update-meta && cp dist/latest-linux.yml dist/update-meta/linux-deb-x64.yml - name: Upload uses: actions/upload-artifact@v4.0.0 @@ -256,6 +265,7 @@ jobs: packages/desktop/dist/*.deb packages/desktop/dist/*.yml packages/desktop/dist/*.yaml + packages/desktop/dist/update-meta/** Linux-Deb-ARM64: name: Linux Deb ARM64 @@ -292,6 +302,7 @@ jobs: run: | yarn run webpack --config desktop.webpack.prod.js --env deb yarn run electron-builder --linux --arm64 -c.linux.target=deb --publish=never --c.extraMetadata.version=${{ env.APP_VERSION }} + mkdir -p dist/update-meta && cp dist/latest-linux-arm64.yml dist/update-meta/linux-deb-arm64.yml - name: Upload uses: actions/upload-artifact@v4.0.0 @@ -301,6 +312,7 @@ jobs: packages/desktop/dist/*.deb packages/desktop/dist/*.yml packages/desktop/dist/*.yaml + packages/desktop/dist/update-meta/** Linux-Snap: name: Linux Snap @@ -397,6 +409,9 @@ jobs: - name: Generate Checksums run: node scripts/sums.mjs + - name: Merge update manifests + run: node scripts/merge-update-manifests.mjs + - name: Generate Release Notes uses: ./actions/release-notes with: diff --git a/packages/desktop/scripts/merge-update-manifests.mjs b/packages/desktop/scripts/merge-update-manifests.mjs new file mode 100644 index 00000000000..b4fd76b6e97 --- /dev/null +++ b/packages/desktop/scripts/merge-update-manifests.mjs @@ -0,0 +1,81 @@ +import fs from 'fs' +import path from 'path' +import { fileURLToPath } from 'url' +import yaml from 'js-yaml' + +const distDir = path.join(path.dirname(fileURLToPath(import.meta.url)), '../dist') +const metaDir = path.join(distDir, 'update-meta') + +/** output manifest -> preserved fragment ids in dist/update-meta/ */ +const MANIFESTS = { + 'latest-mac.yml': ['mac-x64', 'mac-arm64'], + 'latest-linux.yml': ['linux-appimage-x64', 'linux-deb-x64'], + 'latest-linux-arm64.yml': ['linux-appimage-arm64', 'linux-deb-arm64'], +} + +/** preferred top-level path for electron-updater */ +const PRIMARY_URL = { + 'latest-mac.yml': [/-mac-x64\.zip$/i, /-mac-arm64\.zip$/i], + 'latest-linux.yml': [/-linux-x86_64\.AppImage$/i, /-linux-amd64\.deb$/i], + 'latest-linux-arm64.yml': [/-linux-arm64\.AppImage$/i, /-linux-arm64\.deb$/i], +} + +function readMeta(id) { + const filePath = path.join(metaDir, `${id}.yml`) + return fs.existsSync(filePath) ? yaml.load(fs.readFileSync(filePath, 'utf8')) : null +} + +function mergeFiles(docs) { + const byUrl = new Map() + for (const doc of docs) { + for (const entry of doc?.files ?? []) { + if (entry?.url) { + byUrl.set(entry.url, { ...byUrl.get(entry.url), ...entry }) + } + } + } + return [...byUrl.values()].sort((a, b) => a.url.localeCompare(b.url)) +} + +function pickPrimary(files, manifestName) { + for (const pattern of PRIMARY_URL[manifestName] ?? []) { + const match = files.find((f) => pattern.test(f.url)) + if (match) { + return match + } + } + return files[0] +} + +for (const [manifestName, fragmentIds] of Object.entries(MANIFESTS)) { + const docs = fragmentIds.map(readMeta).filter(Boolean) + if (docs.length === 0) { + continue + } + + const versions = [...new Set(docs.map((d) => d.version).filter(Boolean))] + if (versions.length > 1) { + throw new Error(`${manifestName}: conflicting versions ${versions.join(', ')}`) + } + + const files = mergeFiles(docs) + if (files.length === 0) { + continue + } + + const primary = pickPrimary(files, manifestName) + const merged = { + version: versions[0], + files, + path: primary.url, + sha512: primary.sha512, + releaseDate: docs + .map((d) => d.releaseDate) + .filter(Boolean) + .sort() + .at(-1), + } + + fs.writeFileSync(path.join(distDir, manifestName), yaml.dump(merged, { lineWidth: Infinity })) + console.log(`${manifestName}: ${files.length} file(s)`) +}