From 80f2267a147cf7f5c1a41d7619a9ff5c2b005b73 Mon Sep 17 00:00:00 2001 From: BurntToasters <61037367+BurntToasters@users.noreply.github.com> Date: Thu, 1 Oct 2026 19:07:34 -0700 Subject: [PATCH] Tauri: Retire Linux DEB and RPM packages. Remove DEB/RPM build targets, signing rules, updater manifests, release validation, and documentation. Keep Linux AppImage and Flatpak as the supported v5 formats. --- CHANGELOG.md | 8 +-- README.md | 5 +- build-setup.md | 12 ++-- docs/RELEASE-STABLE.md | 7 +- package.json | 4 +- scripts/gpg-sign.d.ts | 4 -- scripts/gpg-sign.js | 102 ++-------------------------- scripts/release-policy.cjs | 10 --- scripts/validate-flatpak-dry-run.js | 14 ++-- scripts/validate-updater-live.js | 8 +-- scripts/verify-release-draft.js | 24 ++++--- src-tauri/tauri.conf.json | 8 +-- src/updater.ts | 8 +++ 13 files changed, 54 insertions(+), 160 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 736b442..2833f8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,16 +6,14 @@ | Windows | macOS | Linux | | :-- | :-- | :-- | | **EXE: [x64](https://github.com/BurntToasters/ROSI/releases/download/v5.0.0-beta.1/ROSI-Windows-x64.exe) / [arm64](https://github.com/BurntToasters/ROSI/releases/download/v5.0.0-beta.1/ROSI-Windows-arm64.exe)** | **[Universal DMG](https://github.com/BurntToasters/ROSI/releases/download/v5.0.0-beta.1/ROSI-MacOS-universal.dmg)** | **AppImage:** [x64](https://github.com/BurntToasters/ROSI/releases/download/v5.0.0-beta.1/ROSI-Linux-x64.AppImage) | -|
| **[Universal ZIP](https://github.com/BurntToasters/ROSI/releases/download/v5.0.0-beta.1/ROSI-MacOS-universal.zip)** | **DEB:** [x64](https://github.com/BurntToasters/ROSI/releases/download/v5.0.0-beta.1/ROSI-Linux-x64.deb) | -| | | **RPM:** [x64](https://github.com/BurntToasters/ROSI/releases/download/v5.0.0-beta.1/ROSI-Linux-x64.rpm) | -| | | **Flatpak:** [x64](https://github.com/BurntToasters/ROSI/releases/download/v5.0.0-beta.1/ROSI-Linux-x64.flatpak) | +|
| **[Universal ZIP](https://github.com/BurntToasters/ROSI/releases/download/v5.0.0-beta.1/ROSI-MacOS-universal.zip)** | **Flatpak:** [x64](https://github.com/BurntToasters/ROSI/releases/download/v5.0.0-beta.1/ROSI-Linux-x64.flatpak) | > macOS downloads require macOS 15 or later. > [!IMPORTANT] > The `.sig` files in this repo are NOT normal GPG signatures. They are for Tauri V2's updater to verify the integrity of updates before downloading and installing. > The `.asc` files are my normal GPG signatures which you can verify using my GPG Public Key: https://tuxedo.rosie.run/GPG/BurntToasters_0xF2FBC20F_public.asc -> ⚠️ Linux ARM64 AppImage/DEB/RPM are published only when that release is built for ARM64; Flatpak stays x64. +> ⚠️ ROSI 5 Linux downloads are x64-only: AppImage and Flatpak. ARM64 build wiring remains for future development, but ARM64 downloads are not supported in v5. ### ℹ️ Enjoying ROSI? Consider [❤️ Supporting Me! ❤️](https://rosie.run/support) @@ -28,7 +26,7 @@ ROSI! A cross platform yt-dlp GUI built on Tauri V2! - **Breaking:** ROSI 5 is a new app. The app identifier is now `run.rosie.rosi`, and v4 cannot auto-update to v5. Install v5 manually. - **NEW - v4 import:** On its first launch, ROSI 5 imports your ROSI 4 settings, queue, lifetime stats, and download activity. Values ROSI 5 does not accept fall back to defaults, and the ROSI 4 files are left untouched. - **Breaking - macOS:** ROSI 5 requires macOS 15 or later, matching the bundled FFmpeg build. -- **Breaking - Linux:** Linux ARM64 builds are paused; Linux x64 ships as AppImage, DEB, RPM, and Flatpak. +- **Linux - DEB and RPM builds are retired:** ROSI 5 supports Linux x64 AppImage and Flatpak downloads only. Linux ARM64 downloads are not supported in v5, although the build wiring remains for future development. DEB and RPM packaging is retired for v5 releases. - **Packaging:** Bundled helpers are now named `rosi-yt-dlp`, `rosi-ffmpeg`, and `rosi-ffprobe` so Linux packages never collide with distro `yt-dlp` / `ffmpeg` files. - **Licenses:** The licenses view now also lists every compiled Rust crate and shows the exact bundled yt-dlp and FFmpeg notices. - **Windows:** Dragging a link from the browser onto the download card or queue works again, and F5, Ctrl+R, Ctrl+P, and the page right-click menu no longer reload or print the app mid-download. diff --git a/README.md b/README.md index cb4cc0c..fa14ec1 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,9 @@ webview, so installers and memory use are much smaller. the v4 files untouched. - The in-app updater has **stable** and **beta** channels (Settings > Update channel). `auto` follows the installed version. -- Linux ships x64 AppImage, DEB, RPM, and a sideloaded Flatpak. Linux ARM64 - builds are paused; the build wiring remains for a future release. +- Linux ships an x64 AppImage and a sideloaded Flatpak. DEB and RPM packages + are no longer built or published. Linux ARM64 is not supported in v5; the + build wiring remains available for future development. ## System requirements diff --git a/build-setup.md b/build-setup.md index 34707c1..98a5d9f 100644 --- a/build-setup.md +++ b/build-setup.md @@ -27,15 +27,15 @@ ## Linux -- Build public AppImage and DEB artifacts on Ubuntu 24.04, the oldest supported - glibc baseline. Build and test RPM artifacts on Fedora 43. +- Build the public AppImage on Ubuntu 24.04, the oldest supported glibc + baseline. - `npm run setup:deb` installs the Ubuntu build, E2E (xvfb), 7-Zip (for `get:ffmpeg`), and Flatpak prerequisites. - Node.js `^22.22.2 || ^24.15.0 || >=26` - Rust (rustup) -- Linux releases ship x64 only (`npm run release:linux:x64`). The ARM64 wiring - (`release:linux:arm64`, `build:linux:arm64`) is kept for a future release and - must run on native ARM64 hardware. +- Linux v5 releases ship x64 only (`npm run release:linux:x64`). ARM64 wiring + (`release:linux:arm64`, `build:linux:arm64`) remains for future development + and is not part of the v5 release matrix. ## Rust toolchain policy @@ -164,7 +164,7 @@ been cryptographically matched to its artifact with the public key in The `b`, `r`, and `release:*` scripts intentionally reset and clean their Git worktrees. Run them only on disposable, isolated build VMs. Before publishing, verify that the draft contains the Windows x64/ARM64 NSIS installers, the -universal macOS DMG/ZIP, Linux x64 AppImage/DEB/RPM/Flatpak, updater +universal macOS DMG/ZIP, Linux x64 AppImage/Flatpak, updater manifests/signatures, SHA-256 lists, and GPG detached signatures (`npm run release:verify:draft`). diff --git a/docs/RELEASE-STABLE.md b/docs/RELEASE-STABLE.md index a839448..6a0d03e 100644 --- a/docs/RELEASE-STABLE.md +++ b/docs/RELEASE-STABLE.md @@ -149,9 +149,8 @@ npm run release:mac npm run release:linux ``` -Run `release:linux:arm64` only on the supported ARM64 release environment when -that artifact is part of the release. Do not use beta recovery overrides for a -stable release. +Linux ARM64 wiring is retained for future development but is not part of the +v5 release matrix. Do not use beta recovery overrides for a stable release. The platform release commands intentionally skip GUI E2E on the signing VM. That is acceptable only because step 4 and protected CI already proved the @@ -162,7 +161,7 @@ exact stable commit with E2E enabled. Before publishing, install each signed artifact on its platform and verify: launch, a real download, an FFmpeg conversion, the queue, notifications, the updater (stable and beta channels), macOS notarization and sidecar signatures, -and Linux desktop integration (AppImage/DEB/RPM/Flatpak launchers). +and Linux desktop integration (AppImage/Flatpak launchers). Fix and rebuild any failing artifact. Do not publish a draft that has not passed this matrix. diff --git a/package.json b/package.json index 4a64eea..fbf9581 100644 --- a/package.json +++ b/package.json @@ -101,8 +101,8 @@ "build:mac:universal": "npm run sync-version && npm run licenses && npm run prepare:sidecars && npm run build:mac:universal:prepared", "build:mac:zip": "node scripts/zip-macos.js", "mac:ssh:keychain": "bash scripts/mac-keychain-ssh.sh", - "build:linux:x64:prepared": "dotenv -e .env -- tauri build --target x86_64-unknown-linux-gnu --bundles appimage,deb,rpm -- --locked", - "build:linux:arm64:prepared": "dotenv -e .env -- tauri build --target aarch64-unknown-linux-gnu --bundles appimage,deb,rpm -- --locked", + "build:linux:x64:prepared": "dotenv -e .env -- tauri build --target x86_64-unknown-linux-gnu --bundles appimage -- --locked", + "build:linux:arm64:prepared": "dotenv -e .env -- tauri build --target aarch64-unknown-linux-gnu --bundles appimage -- --locked", "build:linux:prepared": "npm run build:linux:x64:prepared", "build:linux:x64": "npm run sync-version && npm run licenses && npm run prepare:sidecars && npm run build:linux:x64:prepared", "build:linux:arm64": "npm run sync-version && npm run licenses && node scripts/prepare-sidecars.js --target aarch64-unknown-linux-gnu && npm run build:linux:arm64:prepared", diff --git a/scripts/gpg-sign.d.ts b/scripts/gpg-sign.d.ts index 694deca..3ed98ef 100644 --- a/scripts/gpg-sign.d.ts +++ b/scripts/gpg-sign.d.ts @@ -13,10 +13,6 @@ export function artifactMatchesVersion( name: string, releaseVersion?: string, ): boolean; -export function rpmArtifactMatchesVersion( - name: string, - releaseVersion?: string, -): boolean; export function checksumTargetKeysForArtifactName( name: string, channelVariants?: UpdaterChannelVariant[], diff --git a/scripts/gpg-sign.js b/scripts/gpg-sign.js index 693b0b7..bd731fb 100644 --- a/scripts/gpg-sign.js +++ b/scripts/gpg-sign.js @@ -102,9 +102,6 @@ const REQUIRE_LINUX_AARCH64 = isExplicitTruthy( const REQUIRED_UPDATER_TARGETS = ( process.env.REQUIRED_UPDATER_TARGETS || "" ).trim(); -const ENFORCE_LINUX_X64_PACKAGE_SET = !/^(0|false|no|off)$/i.test( - String(process.env.ENFORCE_LINUX_X64_PACKAGE_SET || "").trim(), -); const ext = (e) => (n) => n.toLowerCase().endsWith(e); const rx = (r) => (n) => r.test(n); @@ -120,8 +117,6 @@ const ARTIFACT_RULES = [ rx(/^ROSI-Windows-(?:x64|arm64)\.exe$/i), ext(".msi"), ext(".dmg"), - ext(".deb"), - ext(".rpm"), ext(".flatpak"), rx(/\.appimage$/i), @@ -131,7 +126,7 @@ const ARTIFACT_RULES = [ rx(/\.app\.tar\.gz$/i), rx(/\.appimage\.tar\.gz$/i), - rx(/\.(?:exe|msi|dmg|deb|rpm|flatpak|appimage)\.sig$/i), + rx(/\.(?:exe|msi|dmg|flatpak|appimage)\.sig$/i), rx(/^ROSI(?:-MacOS-universal)?\.zip\.sig$/i), rx(/\.nsis\.zip\.sig$/i), rx(/\.tar\.gz\.sig$/i), @@ -144,8 +139,6 @@ const SIGN_RULES = [ ext(".exe"), ext(".msi"), ext(".dmg"), - ext(".deb"), - ext(".rpm"), ext(".flatpak"), rx(/\.appimage$/i), rx(/^ROSI(?:-MacOS-universal)?\.zip$/i), @@ -182,9 +175,6 @@ const SEARCH_DIRS = releaseArtifactSearchDirs(); function artifactMatchesVersion(name, releaseVersion = VERSION) { if (name === "latest.json" || isPerTargetManifest(name)) return true; - if (/\.rpm(?:\.sig)?$/i.test(name)) { - return rpmArtifactMatchesVersion(name, releaseVersion); - } const versions = name.match( /\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?/g, ); @@ -192,40 +182,6 @@ function artifactMatchesVersion(name, releaseVersion = VERSION) { return versions.some((candidate) => candidate === releaseVersion); } -function escapeRegExp(value) { - return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); -} - -function rpmArtifactMatchesVersion(name, releaseVersion = VERSION) { - if (!/\.rpm(?:\.sig)?$/i.test(name)) return false; - - const numericVersions = name.match(/\d+\.\d+\.\d+/g); - if (!numericVersions || numericVersions.length === 0) return true; - - const betaMatch = releaseVersion.match( - /^(\d+\.\d+\.\d+)-beta\.(0|[1-9]\d*)$/, - ); - const stableMatch = releaseVersion.match(/^(\d+\.\d+\.\d+)$/); - if (!betaMatch && !stableMatch) return false; - - const numericVersion = betaMatch?.[1] ?? stableMatch[1]; - const escapedNumericVersion = escapeRegExp(numericVersion); - const versionPattern = betaMatch - ? `${escapedNumericVersion}(?:-beta\\.${betaMatch[2]}|[._~]beta[._-]${betaMatch[2]})` - : escapedNumericVersion; - // RPM names conventionally end in NAME-VERSION-RELEASE.ARCH.rpm. Tauri and - // distro tooling vary the release and architecture tokens, and updater - // signatures append another .sig. A release must begin with a digit, which - // keeps a sanitized beta marker from matching a stable application version. - const rpmRelease = "[0-9][0-9A-Za-z_+~%^.-]*"; - const rpmArch = - "(?:x86_64|amd64|aarch64|arm64|i[3-6]86|noarch|ppc64le|ppc64|s390x|riscv64|armv[67]hl)"; - return new RegExp( - `(?:^|[^0-9A-Za-z])${versionPattern}(?:-${rpmRelease})?(?:\\.${rpmArch})?\\.rpm(?:\\.sig)?$`, - "i", - ).test(name); -} - const SIDECAR_MANIFEST = path.join( root, "src-tauri", @@ -358,12 +314,6 @@ function cleanArtifactBaseName(name) { if (/amd64\.AppImage$/i.test(name)) return "ROSI-Linux-x64.AppImage"; if (/aarch64\.AppImage$/i.test(name)) return "ROSI-Linux-arm64.AppImage"; - if (/amd64\.deb$/i.test(name)) return "ROSI-Linux-x64.deb"; - if (/aarch64\.deb$/i.test(name)) return "ROSI-Linux-arm64.deb"; - - if (/x86_64\.rpm$/i.test(name)) return "ROSI-Linux-x64.rpm"; - if (/aarch64\.rpm$/i.test(name)) return "ROSI-Linux-arm64.rpm"; - // The public Flatpak release currently targets Linux x64 only. Normalize // generic files left by older build scripts to the documented asset name. if (/^ROSI-Linux\.flatpak$/i.test(name)) return "ROSI-Linux-x64.flatpak"; @@ -382,7 +332,7 @@ function cleanArtifactName(name) { const FALLBACK_INSTALLER_PRIORITY = { windows: { nsis: 3, msi: 2 }, - linux: { appimage: 3, deb: 2, rpm: 1 }, + linux: { appimage: 3 }, darwin: { app: 3 }, }; @@ -446,28 +396,6 @@ function canPopulateFallbackTarget(_target) { return true; } -function assertLinuxX64PackageSet(byName) { - if (!ENFORCE_LINUX_X64_PACKAGE_SET) return; - const installers = new Set(); - for (const [name] of byName) { - if (name.endsWith(".sig")) continue; - const targets = resolveUpdaterTargets(name); - for (const target of targets) { - if (target.os === "linux" && target.arch === "x86_64") { - installers.add(target.installer); - } - } - } - if (installers.size === 0) return; - const requiredInstallers = ["appimage", "deb", "rpm"]; - const missing = requiredInstallers.filter((i) => !installers.has(i)); - if (missing.length > 0) { - throw new Error( - `Incomplete Linux x86_64 bundle set: missing ${missing.join(", ")} artifact(s).`, - ); - } -} - function resolveUpdaterTargets(name) { const targets = []; if (/\.app\.tar\.gz$/i.test(name)) { @@ -500,20 +428,6 @@ function resolveUpdaterTargets(name) { return targets; } - if (/\.deb$/i.test(name)) { - const arch = inferArchFromName(name); - if (!arch) return targets; - targets.push({ os: "linux", arch, installer: "deb" }); - return targets; - } - - if (/\.rpm$/i.test(name)) { - const arch = inferArchFromName(name); - if (!arch) return targets; - targets.push({ os: "linux", arch, installer: "rpm" }); - return targets; - } - return targets; } @@ -539,7 +453,6 @@ function generateUpdaterManifests(files) { for (const filePath of files) { byName.set(path.basename(filePath), filePath); } - assertLinuxX64PackageSet(byName); const signatureByBaseName = new Map(); for (const [name, filePath] of byName) { @@ -605,8 +518,8 @@ function generateUpdaterManifests(files) { manifest.platforms[installerKey] = { url, signature }; if (channel.targetSuffix) { // A beta check uses the full installer-aware key as its custom Tauri - // target. Give that key its own endpoint manifest so DEB/RPM installs - // never fall through to the AppImage fallback (and vice versa). + // target. Give that key its own endpoint manifest so installers do + // not fall through to the generic fallback. const installerManifestName = `latest-${installerKey}.json`; manifests.set(installerManifestName, { version: VERSION, @@ -1420,11 +1333,9 @@ function requiredPublishedBetaManifestNames() { "darwin-beta-aarch64-app", "linux-beta-x86_64", "linux-beta-x86_64-appimage", - "linux-beta-x86_64-deb", - "linux-beta-x86_64-rpm", ]); if (REQUIRE_LINUX_AARCH64) { - for (const suffix of ["", "-appimage", "-deb", "-rpm"]) { + for (const suffix of ["", "-appimage"]) { targets.add(`linux-beta-aarch64${suffix}`); } } @@ -1442,7 +1353,7 @@ function requiredPublishedBetaManifestNames() { function expectedPublishedBetaManifestNames(actualNames = []) { const expected = new Set(requiredPublishedBetaManifestNames()); const optionalGroups = [ - ["", "-appimage", "-deb", "-rpm"].map( + ["", "-appimage"].map( (suffix) => `latest-linux-beta-aarch64${suffix}.json`, ), ]; @@ -1804,7 +1715,6 @@ export { isGitHubConflict, isTransactionalStagingAssetName, listAllGithubPages, - rpmArtifactMatchesVersion, expectedPublishedBetaManifestNames, requiredPublishedBetaManifestNames, requiredLinuxTargetKeys, diff --git a/scripts/release-policy.cjs b/scripts/release-policy.cjs index 57b343f..ef07e64 100644 --- a/scripts/release-policy.cjs +++ b/scripts/release-policy.cjs @@ -12,10 +12,6 @@ const STABLE_FORBIDDEN_ENV = [ "ROSI_ALLOW_STUB_SIDECARS", ]; -// Stable must keep the Linux x64 deb/rpm/AppImage completeness assertion; -// only explicit disabling (ENFORCE_*=0/false) is refused, opt-in is fine. -const STABLE_FORBIDDEN_FALSY_ENV = ["ENFORCE_LINUX_X64_PACKAGE_SET"]; - // Stable uploads must target the canonical repository only; env retargeting // is a beta-fork recovery path and must not ship a stable feed elsewhere. const STABLE_CANONICAL_ENV = { @@ -52,11 +48,6 @@ function assertStableReleaseOverridesAllowed( const blocked = STABLE_FORBIDDEN_ENV.filter((name) => isExplicitTruthy(env[name]), ); - for (const name of STABLE_FORBIDDEN_FALSY_ENV) { - if (env[name] !== undefined && isExplicitFalsy(env[name])) { - blocked.push(name); - } - } if (blocked.length > 0) { throw new Error( `Stable release ${version} refuses ${blocked.join(", ")}. Those overrides are beta recovery paths only.`, @@ -96,7 +87,6 @@ if (require.main === module) { module.exports = { STABLE_FORBIDDEN_ENV, - STABLE_FORBIDDEN_FALSY_ENV, isExplicitFalsy, isExplicitTruthy, isStableReleaseVersion, diff --git a/scripts/validate-flatpak-dry-run.js b/scripts/validate-flatpak-dry-run.js index 2e724fd..387d529 100644 --- a/scripts/validate-flatpak-dry-run.js +++ b/scripts/validate-flatpak-dry-run.js @@ -146,12 +146,14 @@ if (fs.existsSync(tauriConfPath)) { fail("tauri.conf.json identifier must be run.rosie.rosi"); } const linux = tauriConf.bundle?.linux ?? {}; - for (const kind of ["deb", "rpm"]) { - if (linux[kind]?.desktopTemplate !== "linux/desktop-template.hbs") { - fail( - `bundle.linux.${kind}.desktopTemplate must be linux/desktop-template.hbs`, - ); - } + if (linux.appimage?.bundleMediaFramework !== false) { + fail("bundle.linux.appimage.bundleMediaFramework must be false"); + } + if ( + tauriConf.bundle?.targets?.includes("deb") || + tauriConf.bundle?.targets?.includes("rpm") + ) { + fail("bundle.targets must not include retired DEB/RPM targets"); } const externalBin = tauriConf.bundle?.externalBin ?? []; for (const sidecar of ["rosi-yt-dlp", "rosi-ffmpeg", "rosi-ffprobe"]) { diff --git a/scripts/validate-updater-live.js b/scripts/validate-updater-live.js index ebabbbe..49e8598 100644 --- a/scripts/validate-updater-live.js +++ b/scripts/validate-updater-live.js @@ -76,12 +76,8 @@ const TARGETS = [ "darwin-beta-x86_64-app", "linux-beta-x86_64", "linux-beta-x86_64-appimage", - "linux-beta-x86_64-deb", - "linux-beta-x86_64-rpm", "linux-beta-aarch64", "linux-beta-aarch64-appimage", - "linux-beta-aarch64-deb", - "linux-beta-aarch64-rpm", ]; const STANDARD_STABLE_TARGETS = [ @@ -103,8 +99,6 @@ const STANDARD_BETA_TARGETS = [ "darwin-beta-x86_64-app", "linux-beta-x86_64", "linux-beta-x86_64-appimage", - "linux-beta-x86_64-deb", - "linux-beta-x86_64-rpm", ]; const requestedExpectedVersion = @@ -262,7 +256,7 @@ export function resolveLiveUpdaterTargets(name) { ) { return []; } - if (/\.(exe|msi|dmg|deb|rpm|flatpak|appimage|zip)$/i.test(name)) { + if (/\.(exe|msi|dmg|flatpak|appimage|zip)$/i.test(name)) { return [{ os: "live", arch: "artifact" }]; } return []; diff --git a/scripts/verify-release-draft.js b/scripts/verify-release-draft.js index 251a8a0..e56d986 100644 --- a/scripts/verify-release-draft.js +++ b/scripts/verify-release-draft.js @@ -42,6 +42,8 @@ const { } = require("./release-draft-metadata.cjs"); const root = path.join(path.dirname(fileURLToPath(import.meta.url)), ".."); +const RETIRED_LINUX_PACKAGE_ASSET = + /(?:\.(?:deb|rpm)(?:\.(?:asc|sig))?$|^latest-linux(?:-beta)?-[a-z0-9_]+-(?:deb|rpm)\.json$)/i; function readPackageVersion(repositoryRoot = root) { return JSON.parse( @@ -62,16 +64,10 @@ export function requiredDraftInstallerNames({ "ROSI-MacOS-universal.dmg", "ROSI-MacOS-universal.zip", "ROSI-Linux-x64.AppImage", - "ROSI-Linux-x64.deb", - "ROSI-Linux-x64.rpm", "ROSI-Linux-x64.flatpak", ]; if (requireLinuxAarch64) { - names.push( - "ROSI-Linux-arm64.AppImage", - "ROSI-Linux-arm64.deb", - "ROSI-Linux-arm64.rpm", - ); + names.push("ROSI-Linux-arm64.AppImage"); } return names; } @@ -79,7 +75,7 @@ export function requiredDraftInstallerNames({ export function requiredDraftSidecarNames(installers) { return installers.flatMap((name) => { const names = [`${name}.asc`]; - if (/\.(?:exe|deb|rpm)$/i.test(name) || /\.AppImage$/i.test(name)) { + if (/\.exe$/i.test(name) || /\.AppImage$/i.test(name)) { names.unshift(`${name}.sig`); } return names; @@ -116,11 +112,9 @@ export function requiredDraftBetaManifestNames({ "darwin-beta-aarch64-app", "linux-beta-x86_64", "linux-beta-x86_64-appimage", - "linux-beta-x86_64-deb", - "linux-beta-x86_64-rpm", ]; if (requireLinuxAarch64) { - for (const suffix of ["", "-appimage", "-deb", "-rpm"]) { + for (const suffix of ["", "-appimage"]) { keys.push(`linux-beta-aarch64${suffix}`); } } @@ -200,6 +194,14 @@ export function assertDraftReleaseShape({ `Draft ${tag} is missing required assets: ${missing.join(", ")}.`, ); } + const retired = assetNames.filter((name) => + RETIRED_LINUX_PACKAGE_ASSET.test(name), + ); + if (retired.length > 0) { + throw new Error( + `Draft ${tag} contains retired DEB/RPM assets: ${retired.join(", ")}.`, + ); + } return { tag, missing }; } diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index c1478cc..c0fd47b 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -35,7 +35,7 @@ }, "bundle": { "active": true, - "targets": ["dmg", "app", "nsis", "appimage", "deb", "rpm"], + "targets": ["dmg", "app", "nsis", "appimage"], "publisher": "BurntToasters", "copyright": "Copyright (c) BurntToasters", "category": "Utility", @@ -87,12 +87,6 @@ "linux": { "appimage": { "bundleMediaFramework": false - }, - "deb": { - "desktopTemplate": "linux/desktop-template.hbs" - }, - "rpm": { - "desktopTemplate": "linux/desktop-template.hbs" } } }, diff --git a/src/updater.ts b/src/updater.ts index b33b17d..1021141 100644 --- a/src/updater.ts +++ b/src/updater.ts @@ -69,6 +69,12 @@ async function updateCheckTarget(): Promise { return isBetaVersion(await getVersion()) ? invoke('get_beta_updater_target') : undefined; } +async function retiredLinuxPackageMessage(): Promise { + const installedTarget = await invoke('get_beta_updater_target'); + if (!/^linux-beta-[a-z0-9_]+-(?:deb|rpm)$/i.test(installedTarget)) return null; + return 'DEB and RPM packages are no longer published for ROSI 5. Install the AppImage or Flatpak manually from the latest release to continue receiving updates.'; +} + async function checkFeed(target: string | undefined): Promise { const options = { ...(target ? { target } : {}), timeout: UPDATE_CHECK_TIMEOUT_MS }; try { @@ -102,6 +108,8 @@ export async function checkForUpdates(): Promise<{ error: string; message?: stri error: 'Flatpak builds update through a reinstalled bundle, not the in-app updater.', }; } + const retiredPackageMessage = await retiredLinuxPackageMessage(); + if (retiredPackageMessage) return { error: retiredPackageMessage }; if (downloading) return null; emitStatus({ status: 'checking' }); try {