Skip to content

feat(linux): ship an AppImage, with the tarball as the fallback - #113

Merged
StuartCameronCode merged 2 commits into
mainfrom
linux-appimage
Oct 5, 2026
Merged

StuartCameronCode merged 2 commits into
mainfrom
linux-appimage

Conversation

@StuartCameronCode

Copy link
Copy Markdown
Owner

Summary

The Linux release was a bare tarball: extract it and run ./vapourbox, with no desktop entry, no icon and no update path. package-linux.sh now also builds an AppImage and its .zsync from the same tree. The tarball stays as the fallback.

  • Scripts/package-linux.sh — builds VapourBox-X.Y.Z-linux-<arch>.AppImage + .AppImage.zsync alongside the tarball. --skip-appimage gives the tarball alone.
  • packaging/linux/ (new) — AppRun, the desktop entry, and a 256px icon rendered from the existing Swift source (generate-app-icons.sh regenerates it).
  • build-linux.yml — installs zsync and desktop-file-utils; uploads all three files per arch.
  • ci-build-and-release.sh, release.sh — the release upload picks up the AppImage and .zsync; release-notes text updated.
  • packaging_test.dart — lints the update filename, the upload lists, and the desktop/icon naming against APPLICATION_ID.
  • Docs — README install steps and download table, docs/BUILDING.md, a Linux section in CLAUDE.md.

Design notes

  • AppRun exports nothing (no LD_LIBRARY_PATH, no bundled GTK): its environment is inherited by the worker and by the ffmpeg/vspipe it spawns from the downloaded deps bundle.
  • Deps stay a first-launch download under $XDG_DATA_HOME. The AppImage mount is read-only, and deps are versioned separately in two CPU tiers.
  • Update information is gh-releases-zsync|…|latest|VapourBox-*-linux-<arch>.AppImage.zsync. A missing zsyncmake fails the build rather than embedding a pointer to a file that was never made.
  • appimagetool is pinned to 1.9.1 by version and SHA-256. The runtime it embeds is fetched by the tool at build time and is not pinned.

Not changed

  • The glibc 2.39 floor — that comes from the deps build, not the packaging.
  • An AppImage does not add itself to the menu or update itself; the README points to Gear Lever / AppImageLauncher / AppImageUpdate.
  • The app window still sets no icon of its own.

Test plan

  • flutter test test/packaging_test.dart passes locally (7 tests)
  • The AppImage step itself has not been run — it needs a Linux host. Dispatch before merging:
    gh workflow run build-linux.yml --ref linux-appimage -f version=0.0.0-test -f deps_tag=<current deps tag> -f arch=both
  • Download the artifact, chmod +x, launch on Ubuntu 24.04: deps download, a job encodes, preview renders
  • desktop-file-validate clean in the build log; .zsync present in the artifact for both arches

🤖 Generated with Claude Code

https://claude.ai/code/session_014GLXdGLfPwgYjW1AkonGqN

The Linux release was a bare tarball: extract it and run ./vapourbox, with
no desktop entry, no icon and no update path. package-linux.sh now also
builds an AppImage and its .zsync from the same tree.

- AppRun exports nothing, so no environment leaks into the worker or the
  ffmpeg/vspipe it spawns from the downloaded deps bundle.
- Deps stay a first-launch download under $XDG_DATA_HOME: the mount is
  read-only, and deps are versioned separately in two CPU tiers.
- Update information points at the latest GitHub release's .zsync. A
  missing zsyncmake fails the build rather than embedding a dead pointer.
- appimagetool is pinned to 1.9.1 by version and SHA-256.
- packaging_test.dart lints the update filename, the release upload lists
  and the desktop/icon naming against APPLICATION_ID.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014GLXdGLfPwgYjW1AkonGqN
@StuartCameronCode

Copy link
Copy Markdown
Owner Author

Test build of this branch is green on both architectures: https://github.com/StuartCameronCode/VapourBox/actions/runs/37301057770 (version 0.0.0-test, deps-v1.12.0).

Each artifact holds all three files — .AppImage (~13 MB), .AppImage.zsync, .tar.gz. The AppImages are static-pie ELF for the right architecture, the embedded update information reads gh-releases-zsync|StuartCameronCode|VapourBox|latest|VapourBox-*-linux-<arch>.AppImage.zsync, and the .zsync names the matching AppImage. appimagetool's only warnings are about missing AppStream metadata, which is optional.

Still unchecked: launching the AppImage on a real Linux desktop (deps download, an encode, a preview).

🤖 Generated with Claude Code

The AppImage lint tests asserted whole lines ending in \n. A Windows
checkout gives the workflow and desktop entry CRLF, so two of them
failed on the Windows CI job only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014GLXdGLfPwgYjW1AkonGqN
@StuartCameronCode
StuartCameronCode merged commit 117bb61 into main Oct 5, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant