Make the AppImage updatable, and drop the deb and rpm
Secret Scan / scan (push) Successful in 4s
Build App (Preview) / compute-version (pull_request) Successful in 4s
Secret Scan / scan (pull_request) Successful in 3s
Build App (Preview) / create-release (pull_request) Successful in 2s
Build App (Preview) / build-macos (pull_request) Successful in 2m43s
Build App (Preview) / build-windows (pull_request) Successful in 4m51s
Build App (Preview) / build-linux (pull_request) Successful in 5m19s
Build App (Preview) / prune-previews (pull_request) Successful in 1s

An AppImage manager can adopt the current build but never update it: the image
carries no update information, which is the string that tells such a tool where
to look for a newer one. It also carries no AppStream metadata, so a manager
has nothing to show but a filename — appimagetool has been warning about that
on every build — and linuxdeploy leaves `Categories=` empty, which files the
app nowhere in a desktop menu.

All three are fixed while the image is already unpacked for the wayland fix, so
the cost is a few lines rather than a second pass. `unbundle-wayland-client.sh`
is now `finalize-appimage.sh`, since it does more than unbundle.

The update URL is a **fixed** `linux-latest` tag on the GitHub mirror, which is
where updates are pulled from — deliberately not `releases/latest`. `latest`
follows whichever release is newest, and the Gitea-to-GitHub backfill creates
one GitHub release per Gitea tag, including the `-win` and `-mac` tags that
carry no AppImage. A URL that can resolve to a release with no AppImage in it
fails on users' machines and nowhere else.

The output is named for that tag too, and that is not cosmetic: zsync records
a *relative* filename which a client resolves against the .zsync URL it
fetched, so a versioned name would send every client after the build it already
has. Verified by reading the generated header — `Filename: Triple-C_x86_64
.AppImage` — and the image's own `.upd_info` section, which is where the tag
actually lives. My first guard checked the .zsync for the tag and failed
correctly, which is how that distinction got found rather than shipped.

Range requests were confirmed against the mirror before building on them: 206
with a correct content-range, so updates are real deltas rather than an 85 MB
re-download.

The .deb and .rpm go. They are two more artifacts to build, publish and keep
working for an audience already served by the one file that runs on every
distribution, and neither could ever self-update — which is now the difference
that matters. Older releases keep theirs. The Linux job passes
`--bundles appimage` rather than changing `tauri.conf.json`, so macOS and
Windows are untouched.

Verified against the real 0.4.19 artifact: it repacks, the AppStream file and
filled-in Categories land inside the image, the update string resolves to the
fixed tag, and the wayland fallback still holds. Both publisher failure paths
refuse rather than half-publishing — no token, and missing artifacts.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011YPqHpjV4EL6RNEwrRKqQm
This commit is contained in:
2026-09-02 17:10:44 -07:00
co-authored by Claude Opus 5
parent a3bdf6f4da
commit 9fadfbc37a
7 changed files with 301 additions and 19 deletions
+5 -3
View File
@@ -41,14 +41,16 @@ Download the build for your platform from [GitHub Releases](https://github.com/s
|----------|------|---------|
| **Windows** | `Triple-C_<version>_x64-setup.exe` or `.msi` | Run the installer. |
| **macOS** | `Triple-C_<version>_universal.dmg` | Open the `.dmg` and drag Triple-C to Applications. |
| **Debian / Ubuntu** | `Triple-C_<version>_amd64.deb` | `sudo apt install ./Triple-C_<version>_amd64.deb` |
| **Fedora / RHEL** | `Triple-C-<version>-1.x86_64.rpm` | `sudo dnf install ./Triple-C-<version>-1.x86_64.rpm` |
| **Arch / CachyOS / other Linux** | `Triple-C_<version>_amd64.AppImage` | `chmod +x` it, then run it directly. See the AppImage notes below. |
| **Linux (all distributions)** | `Triple-C_<version>_amd64.AppImage` | `chmod +x` it, then run it directly. See the AppImage notes below. |
> **macOS note:** The app is not signed or notarized. On first launch, macOS Gatekeeper may block it — right-click the app and select "Open" to bypass, or remove the quarantine attribute: `xattr -cr /Applications/Triple-C.app`.
> **AppImage note:** Two things are worth knowing. Running an AppImage needs FUSE 2, which Arch and CachyOS do not install by default — `sudo pacman -S fuse2` once, or run it with `--appimage-extract-and-run` to sidestep FUSE entirely. And an AppImage is just an executable file: nothing registers it with the desktop, so it will not appear in your app launcher on its own. Run [`scripts/install-appimage.sh`](scripts/install-appimage.sh) to add a launcher entry and icons — see [Adding an AppImage to the app launcher](#adding-an-appimage-to-the-app-launcher).
> **Linux is AppImage only.** The `.deb` and `.rpm` were dropped. They were a second and third artifact to build, test and publish for an audience already served by the one file that runs on every distribution — and unlike the AppImage they could not be kept up to date automatically. Older releases still carry them if you need one.
> **Updates.** The AppImage carries update information, so an AppImage manager (Gear Lever, AppImageLauncher and similar) can adopt it and update it in place — pulling only the changed blocks rather than re-downloading 85 MB. It reads a fixed `linux-latest` tag on GitHub, so the URL never moves between versions.
> **No Arch package.** There was a `triple-c-bin` `.pkg.tar.zst` attached to some releases, built by a maintainer-triggered workflow. It was never on the AUR, so installing it meant downloading a file and running `pacman -U` — no better than the AppImage — and being manual-only it reached 1 release in 28, which made the promise of it worse than not making it. The `PKGBUILD` and its workflow are preserved on the `hold/arch-packaging` branch if an AUR package is ever worth doing properly.
### Adding an AppImage to the app launcher