Skip to content

ci: build Linux releases (AppImage + portable tar.gz) - #91

Merged
toonoumi merged 2 commits into
mainfrom
feature/linux-release-build
Jul 4, 2026
Merged

ci: build Linux releases (AppImage + portable tar.gz)#91
toonoumi merged 2 commits into
mainfrom
feature/linux-release-build

Conversation

@toonoumi

@toonoumi toonoumi commented Jul 4, 2026

Copy link
Copy Markdown
Owner

Summary

Tag releases now also build Linux binaries, in two formats:

  • FreeCCR_Linux_<version>-x86_64.AppImage — single-file, double-click-and-run. Built with appimagetool's static runtime, so it does not need libfuse2 on users' machines.
  • FreeCCR_Linux_<version>-x86_64.tar.gz — the raw Nuitka standalone folder ("portable folder" style, as the Linux Mint user on the issue suggested). Extract anywhere, run FreeCCR/FreeCCR. No Python, no venv, no apt packages.

Why one build covers Ubuntu, Fedora, Mint, etc.

Linux binaries link against the build machine's glibc, and glibc is only forward-compatible — so the job builds on ubuntu-22.04 (glibc 2.35), the oldest still-supported GitHub runner. One x86_64 build then runs on:

  • Ubuntu 22.04+ / Linux Mint 21+ / Pop!_OS 22.04+
  • Debian 12+
  • Fedora 36+ (current: 42)
  • openSUSE Leap 15.4+ / Tumbleweed, Arch/Manjaro, SteamOS 3

There's a comment in the workflow warning not to bump the runner to ubuntu-latest casually, since that silently cuts off older distros.

The libxcb-cursor0 problem

Qt ≥ 6.5's xcb platform plugin needs libxcb-cursor.so.0, which most distros don't preinstall — it's exactly the one package the Mint user had to sudo apt install (and then vendored into a local lib/ folder to stay portable). The workflow installs it on the build runner so Nuitka can bundle it, and a post-build step verifies it landed in the dist (copying it in manually if Nuitka excluded it). Users need to install nothing.

Smoke tests

Before packaging, the job boots the built bundle under Xvfb in two bare containers (ubuntu:22.04 and fedora:latest) that only have the libs every desktop distro ships by default — deliberately without libxcb-cursor0. The app must run for 25 s without crashing. This catches missing-library and missing-module bundling regressions on both .deb-world and .rpm-world before anything is released.

Testing without tagging

The workflow now also has a workflow_dispatch trigger:

  • Release-upload steps are skipped on non-tag runs (all three platforms).
  • The Linux job instead uploads its AppImage + tar.gz as a workflow artifact, so builds can be handed to testers (e.g. the Mint user) before cutting a release.

Verified on this branch: dispatch run 28689242973 — all three jobs green, both container smoke tests passed, release-upload steps correctly skipped on the non-tag run, and the Linux AppImage + tar.gz are downloadable as a workflow artifact from that run (handy for giving the Mint user a test build).

Release-notes reminder

The static release-notes body now exists in three places (Windows, macOS, Linux jobs) — keep all three in sync, and update "What's New" as usual when tagging. The Install section already includes Linux instructions.

🤖 Generated with Claude Code

https://claude.ai/code/session_015mARQRfzeYh6SZz2id9AM4

toonoumi and others added 2 commits July 3, 2026 16:58
Adds a build-linux job to the tag-release workflow:
- Builds on ubuntu-22.04 (oldest glibc) so one x86_64 binary covers
  Ubuntu 22.04+, Mint 21+, Debian 12+, Fedora 36+, openSUSE, Arch
- Nuitka standalone bundle incl. onnxruntime (parity with Windows)
- Bundles libxcb-cursor0, the Qt 6.5+ runtime dep most distros lack
- Smoke-tests the bundle in bare Ubuntu 22.04 and Fedora containers
  under Xvfb before packaging
- Ships both an AppImage (static runtime, no libfuse2 needed) and a
  portable tar.gz

Also adds workflow_dispatch so builds can be tested without tagging:
release upload steps are tag-gated, and the Linux job uploads its
output as a workflow artifact on non-tag runs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mARQRfzeYh6SZz2id9AM4
Nuitka excludes the whole system X11/xkb stack, not just
libxcb-cursor: the bare-container smoke test failed importing PySide6
(libxkbcommon.so.0 missing). Bundle every xcb extension/util lib the
Qt xcb QPA needs plus libxkbcommon(-x11), and give the smoke-test
containers only the truly universal host stack (libX11/libxcb core,
SM/ICE, GL, fontconfig, glib, dbus).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mARQRfzeYh6SZz2id9AM4
@toonoumi
toonoumi merged commit 9ccfbb9 into main Jul 4, 2026
3 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