From e97b840ee3a3dd708ce4a51751688e7f3ded295d Mon Sep 17 00:00:00 2001 From: Leandro Rodrigues Date: Fri, 16 Oct 2026 20:23:43 -0300 Subject: [PATCH] feat(appimage): publish zsync files for delta updates AppImages had no update information, so AppImageUpdate could not update them and every update meant downloading the whole bundle. Embed a gh-releases-zsync update string in the AppImage and have the build fail when the matching .zsync file is missing. The release workflows now carry the .zsync files as artifacts, require them for both architectures, list them in checksums.txt and attach them to the GitHub release. The update string matches the versioned AppImage names, so it keeps working across releases. Releases made before this change cannot be updated this way. --- .github/workflows/release-appimage.yml | 8 ++++++-- .github/workflows/release.yml | 4 +++- PACKAGING.md | 10 ++++++++++ README.md | 4 ++++ packaging/appimage/build.sh | 6 +++++- 5 files changed, 28 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release-appimage.yml b/.github/workflows/release-appimage.yml index 11c13d5..19aa06d 100644 --- a/.github/workflows/release-appimage.yml +++ b/.github/workflows/release-appimage.yml @@ -44,7 +44,9 @@ jobs: - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: name: appimage-x86_64 - path: dist/*.AppImage + path: | + dist/*.AppImage + dist/*.AppImage.zsync if-no-files-found: error # Fedora container because Arch has no official ARM64 image and Arch Linux ARM lacks @@ -77,5 +79,7 @@ jobs: - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: name: appimage-aarch64 - path: dist/*.AppImage + path: | + dist/*.AppImage + dist/*.AppImage.zsync if-no-files-found: error diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index be020bf..e83277b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -173,16 +173,18 @@ jobs: for arch in x86_64 aarch64; do test -s "dist/zaptide-${GITHUB_REF_NAME}-${arch}.flatpak" test -s "dist/zaptide-${GITHUB_REF_NAME}-${arch}.AppImage" + test -s "dist/zaptide-${GITHUB_REF_NAME}-${arch}.AppImage.zsync" test -s "dist/zaptide-${GITHUB_REF_NAME}-${arch}-linux-gnu.tar.gz" done - name: Checksums working-directory: dist - run: sha256sum *.flatpak *.AppImage *.tar.gz > checksums.txt + run: sha256sum *.flatpak *.AppImage *.AppImage.zsync *.tar.gz > checksums.txt - uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 with: files: | dist/*.flatpak dist/*.AppImage + dist/*.AppImage.zsync dist/*.tar.gz dist/checksums.txt fail_on_unmatched_files: true diff --git a/PACKAGING.md b/PACKAGING.md index 43ac356..88ee7ae 100644 --- a/PACKAGING.md +++ b/PACKAGING.md @@ -68,6 +68,16 @@ and Arch Linux ARM ships libadwaita 1.9. `build.sh` picks the `dnf` path when podman run --rm -v "$PWD":/src -w /src -e VERSION=dev registry.fedoraproject.org/fedora:45 ./packaging/appimage/build.sh ``` +Each AppImage embeds the update information +`gh-releases-zsync|luminusOS|zaptide|latest|zaptide-*-.AppImage.zsync`, and +the build writes the matching `.zsync` file next to it. The release publishes both, +so [AppImageUpdate](https://github.com/AppImageCommunity/AppImageUpdate) and +`appimageupdatetool` download only the changed blocks: + +```sh +appimageupdatetool zaptide.AppImage +``` + ## Build dependencies | Dependency | Fedora | Notes | diff --git a/README.md b/README.md index ee05f51..91f9825 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,10 @@ chmod +x ./zaptide.AppImage ./zaptide.AppImage ``` +Update an AppImage in place with +[AppImageUpdate](https://github.com/AppImageCommunity/AppImageUpdate); it +downloads only what changed. + On first launch, use WhatsApp's **Linked devices** menu to scan the QR code or link with your phone number. Recent history may take a few minutes to arrive. diff --git a/packaging/appimage/build.sh b/packaging/appimage/build.sh index 46f875f..0f02963 100755 --- a/packaging/appimage/build.sh +++ b/packaging/appimage/build.sh @@ -2,7 +2,7 @@ # Builds the ZapTide AppImage with quick-sharun. Run it as root inside an Arch # Linux container (Arch ships libadwaita 1.10 and has no 32-bit libs in /usr/lib): # podman run --rm -v "$PWD":/src -w /src archlinux ./packaging/appimage/build.sh -# The result is dist/zaptide-$ARCH.AppImage. +# The result is dist/zaptide-$VERSION-$ARCH.AppImage and its .zsync file. set -eux ARCH="$(uname -m)" @@ -42,6 +42,10 @@ export ICON=data/icons/zaptide.svg export DESKTOP=data/dev.luminusos.ZapTide.desktop export STARTUPWMCLASS=dev.luminusos.ZapTide export GTK_CLASS_FIX=1 +# Delta updates: AppImageUpdate reads this from the AppImage and fetches the +# .zsync published next to it in the latest GitHub release. +export UPINFO="gh-releases-zsync|luminusOS|zaptide|latest|zaptide-*-$ARCH.AppImage.zsync" ./quick-sharun /usr/bin/zaptide ./quick-sharun --make-appimage +test -s "$OUTPATH/$OUTNAME.zsync"