Skip to content

feat(linux): bundle an AppImage alongside the .deb - #209

Merged
lambdalisue merged 3 commits into
mainfrom
feat/linux-appimage
Aug 7, 2026
Merged

feat(linux): bundle an AppImage alongside the .deb#209
lambdalisue merged 3 commits into
mainfrom
feat/linux-appimage

Conversation

@lambdalisue

Copy link
Copy Markdown
Member

Why

The .deb installs only on Debian and Ubuntu. On Fedora — and on openSUSE or
Arch — there is currently no runnable release artifact at all; the only
documented way in is a source build or the Nix package.

dx 0.7.9 can emit an .rpm, but it has no RPM-specific dependency settings:
bundle_linux_rpm reads deb_settings.depends and writes those names straight
into the RPM Requires (packages/cli/src/bundler/linux.rs:257,420-423). The
package would demand libwebkit2gtk-4.1-0, libgtk-3-0t64 | libgtk-3-0, … —
Debian names no RPM distro can resolve, and | is not even valid RPM syntax.
So the Linux build now emits an AppImage next to the .deb instead.

What changed

  • desktop/justfile[linux] build bundles deb + appimage from the same
    build, and sweeps stale artifacts first (CI caches desktop/target, and
    non-release runs leave 0.0.0-stamped packages the release glob would attach).
    [linux] verify-bundle now requires and checks both formats.
  • scripts/verify-linux-bundle.sh — dispatches on extension. The AppImage is
    self-extracted, its binary gets the same /nix/store checks, and the bundled
    usr/lib is scanned too: linuxdeploy rewrites RUNPATH to $ORIGIN and copies
    the host's libraries in, so a devShell build would otherwise pass the header
    check while shipping store libraries. The artifact itself is then launched via
    APPIMAGE_EXTRACT_AND_RUN=1.
  • .github/workflows/build.yml — both Linux legs upload the AppImage, and the
    release attaches *.AppImage.
  • README.md — Linux section split into Debian/Ubuntu (.deb) and everything
    else (.AppImage).

Verification status

Not verifiable locally (macOS): this PR run is the first real test of the
linuxdeploy step. Checked statically instead — just --evaluate, bash -n on
the script and both recipe bodies, YAML parse of the workflow, and a read of
the dx bundler confirming Icon=arto matches the installed
usr/share/icons/hicolor/*/apps/arto.png (linuxdeploy's most common hard
failure), that .icns entries are warned about and skipped, and that deb and
appimage coexist in one invocation.

Still unconfirmed and worth testing on a real Fedora box before this is treated
as done: whether the AppImage actually launches. WebKitGTK spawns
WebKitWebProcess / WebKitNetworkProcess from a compiled-in libexec path that
linuxdeploy does not bundle, so a host WebKitGTK at a different version may
break it even when installed.

🤖 Generated with Claude Code

The .deb installs only on Debian and Ubuntu, which left every other
distribution — Fedora, openSUSE, Arch — with no runnable artifact other than
the Nix package. An AppImage covers them from the same build.

An .rpm would be the obvious alternative, but dx 0.7 has no RPM-specific
dependency settings: it feeds `[bundle.deb] depends` straight into the RPM
`Requires`, so the package would demand Debian package names that no RPM
distro can resolve, and would fail at install time.

The bundle directory is swept before bundling because CI caches it and
non-release runs leave artifacts stamped 0.0.0 behind, which the release
upload glob would attach alongside the real ones.

The verifier gains an AppImage path: the artifact is self-extracted and its
binary checked exactly like the packaged one, and the bundled libraries are
checked too. linuxdeploy rewrites RUNPATH to $ORIGIN and copies the host's
libraries in, so a devShell build would otherwise pass the header check
while shipping a directory full of /nix/store libraries.
The Linux legs would build the AppImage but upload only the .deb, so the
artifact non-Debian distributions depend on would never reach a release.
The Linux section told every reader to install a .deb, which the package
manager on Fedora and other RPM distributions cannot use — leaving a source
build or Nix as the only documented way in.
@lambdalisue
lambdalisue marked this pull request as ready for review August 2, 2026 02:22
Copilot AI review requested due to automatic review settings August 2, 2026 02:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR expands Linux release distribution by producing and publishing an AppImage alongside the existing .deb, addressing non-Debian/Ubuntu distributions where the .deb is not usable.

Changes:

  • Updated the Linux bundle verification script to support validating both .deb and .AppImage artifacts.
  • Modified the desktop justfile Linux recipes to build, sweep stale artifacts, and verify both packaging formats.
  • Adjusted the GitHub Actions workflow and README to upload/attach and document the AppImage release path.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
scripts/verify-linux-bundle.sh Adds artifact-type dispatch for .deb vs .AppImage, including extraction and runtime launch checks for AppImages.
README.md Documents .deb for Debian/Ubuntu and .AppImage for other distros, including basic dependency note for Fedora.
desktop/justfile Builds both .deb and .AppImage from one Linux build, deletes stale cached artifacts, and verifies presence of both formats.
.github/workflows/build.yml Uploads AppImages from Linux build jobs and attaches *.AppImage assets to releases.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +77 to +88
if [[ "$kind" == "appimage" && -d "$root/usr/lib" ]]; then
# The header check above is not sufficient for an AppImage: linuxdeploy
# rewrites RUNPATH to $ORIGIN/../lib and copies every library it resolved on
# the build host into the AppDir. A devShell build would therefore have its
# /nix/store RUNPATH laundered out of the headers while the bundled libraries
# are the store's own. Inspect what was actually shipped alongside it.
if refs="$(grep -rlF /nix/store "$root/usr/lib")"; then
echo "Error: bundled libraries come from the build environment:" >&2
echo "$refs" >&2
status=1
fi
fi
@lambdalisue
lambdalisue merged commit 162d4e2 into main Aug 7, 2026
16 checks passed
@lambdalisue
lambdalisue deleted the feat/linux-appimage branch August 7, 2026 12:58
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.

2 participants