ci: build Linux AppImages for x86_64 and arm64 - #6
Merged
Conversation
build-linux has been disabled since cc03493 ("Temporarily disable Linux and Windows builds to iterate on macOS signing"). Windows was restored in 018ca0c, Linux never was. Rework it into an arch-parameterised matrix producing two AppImages: - x86_64 on ubuntu-24.04, aarch64 on ubuntu-24.04-arm (both native, no emulation). The aarch64 build targets Raspberry Pi OS Trixie. - ubuntu-22.04 is gone: it and ubuntu-22.04-arm start deprecating 2026-09-17 and workflows on those labels are terminated with an error. - libfuse2 does not exist on Ubuntu 24.04; libfuse2t64 provides libfuse.so.2. - QTDIR is per-arch: aqt installs linux_gcc_arm64 into gcc_arm64, not gcc_64. - AppRun/appimagetool URLs and the produced filename are arch-derived. - Add the Node/web-dmx build step, which only Windows and macOS got in ce0fda1. The CMake install rule is guarded by EXISTS, so without it the Linux AppImage silently shipped without the SPA. - release-mcp now needs build-linux, so it cannot publish before the Linux artifacts upload. Narrow the matrix to build-v5-mcp, matching what Windows and macOS already do. Drop continue-on-error so failures are actually visible. Add three verification steps: AppImage payload architecture, web-dmx presence, and a glibc ceiling check (<= 2.39) on the aarch64 leg. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f9495b72-0428-415e-9a53-50e1ed80df8c
Two failures from the first Linux CI run on this branch. x86_64 failed at configure with "Neither libftdi-0.X nor libftdi-1.X found!". Root cause was earlier: cache-apt-pkgs-action hit a 404 for a superseded libudev-dev .deb, installed zero packages, and still reported the step as successful. Replace it with plain apt-get, which fails loudly, and assert libftdi1/libusb-1.0 via pkg-config so a dependency problem is diagnosed where it happens instead of 90s later. Also pass --no-install-recommends; one of the two 404s was gdb's libc6-dbg recommend, which the build does not need. aarch64 got through configure, build and the test suite, then failed at install: file INSTALL cannot find "/Users/abossard/Desktop/projects/qlcplus/resources/fixtures/ADB" Three generated CMake files were committed by accident in 8b4897b. resources/fixtures/CMakeFiles/CMakeDirectoryInformation.cmake pins CMAKE_RELATIVE_PATH_TOP_SOURCE to that absolute path, and the CREATE_LINK loop in resources/fixtures/CMakeLists.txt symlinks the source CMakeFiles dir into a fresh build tree, so relative install() paths resolved against another machine's checkout. Untrack all three and ignore in-source CMake output so it cannot recur. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f9495b72-0428-415e-9a53-50e1ed80df8c
Review found both new verification steps asserting less than their output claimed. The glibc gate printed "runs on Raspberry Pi OS Trixie" while checking only GLIBC symbol versions. The payload also needs GLIBCXX_3.4.32 and libstdc++ is not bundled, so a Qt/GCC bump could break Pi compatibility with the gate still green. Check both ABI axes, gate against what the target actually provides (Trixie/Debian 13: glibc 2.41, GCC 14 -> GLIBCXX_3.4.33), and narrow the message to the symbol floors it really verifies -- the ~29 unbundled host libraries are still unchecked. Test Load AppImage ran with the build host's Qt on LD_LIBRARY_PATH, QT_PLUGIN_PATH and QML2_IMPORT_PATH, and asked for --platform offscreen, which is not shipped inside the AppImage. It could only ever have resolved through /opt/Qt, so the step could not tell a self-contained AppImage from one rescued by the host. Clear those variables and use the bundled minimal plugin. Verified locally before pushing: the rewritten gate passes on the real artifact's values (GLIBC 2.38, GLIBCXX 3.4.32), passes at the exact boundary, and fails on a GLIBCXX-only regression that the previous version would have let through, on a too-new glibc, and on a broken scan that finds no symbols at all. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f9495b72-0428-415e-9a53-50e1ed80df8c
Follow-up to 6797f84. Four issues, one of them a regression I introduced. The '|| true' I added to reach the zero-symbol diagnostic also converted a PARTIAL scan failure from red to green: if objdump failed on one file but succeeded on others, the step reported the maximum of whatever happened to scan and passed. Scan once, up front, and fail the step if find/xargs/objdump fails; keep '|| true' only on the grep, where it means "matched nothing" and the explicit test -n reports it. Scanning once also halves the work now that there are two axes. Test Load AppImage asserted the exit code only, so the "print the APPVERSION string" half of the criterion was never machine-checked. A literal grep for APPVERSION would have failed: it is 5.3.0-GIT-abc1234 with dashes, while the banner prints spaces. Map dashes back before comparing. env -u listed five variables and missed QML_IMPORT_PATH, the Qt6 spelling of QML2_IMPORT_PATH. Not currently exported by install-qt-action, but it would silently reintroduce host QML if that changes. Also clear QT_QPA_PLATFORM and QTDIR, the latter set at job level. The step now prints the child's view of all eight, so the log carries positive evidence they were cleared rather than resting on env -u semantics. Verified locally: partial-scan failure, objdump broken everywhere, and a missing AppDir are all red with a diagnostic; a healthy scan finding no symbols is still red with its own message; real values (2.38 / 3.4.32) and a GLIBCXX-only regression behave as before. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f9495b72-0428-415e-9a53-50e1ed80df8c
Review ran the published artifacts in Debian containers and found three things. Qt's QML modules install relocatable .o files (~1 MB) into the AppImage. They are dead weight, and objdump -T rejects them, so the ABI scan would fail on them if their mode ever gained +x -- demonstrated by chmod u+x on one, which turned the step red on an otherwise-healthy build. They are excluded today only by their 0644 mode. Delete them instead. Verified on the real artifact: 4540 -> 4537 files, nothing else removed, and the app still starts on Debian 13 arm64 afterwards. The APPVERSION assertion added in b8a206d degenerates to grep -qF "" if APPVERSION ever parses as empty, which matches any output and makes AC5 self-satisfying. Nothing upstream fails in that case because the artifact filename stays internally consistent. Guard it. The AppImage bundles Qt but not the GL/audio/font stack, so it exits 127 with libGLX.so.0 on a bare system -- CI never noticed because the runner has those preinstalled. Document the nine packages, the Bookworm incompatibility with its exact symbol errors, and the FUSE-less run methods. Every claim in that file was executed in a container first, including that AppRun must be used rather than the binary directly, since chrpath sets a CWD-relative RPATH. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f9495b72-0428-415e-9a53-50e1ed80df8c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Re-enables the Linux CI build and publishes AppImages for both 64-bit architectures.
build-linuxhad been disabled withif: falsesince cc03493 ("Temporarily disable Linux and Windows builds to iterate on macOS signing"). Windows was restored in 018ca0c; Linux never was. As a resultmcp-latesthas had no Linux asset at all.What changes
Reworks
build-linuxinto a two-leg architecture matrix:ubuntu-24.04qlcplus-v5-…-x86_64.AppImageubuntu-24.04-armqlcplus-v5-…-aarch64.AppImageBoth build natively, no emulation. The matrix is narrowed to
build-v5-mcp, matching what Windows and macOS already do.ubuntu-22.04is gone: it andubuntu-22.04-armbegin deprecation on 2026-09-17, after which workflows on those labels are terminated with an error (runner-images#14254).release-mcpnow needsbuild-linux, so it cannot publish before the Linux artifacts upload.Bugs found on the way
Three only surfaced once the job actually ran:
cache-apt-pkgs-actionreported success after installing zero packages. It hit a 404 on a supersededlibudev-devdeb; the build then failed 90 seconds later at configure with a misleading "Neither libftdi-0.X nor libftdi-1.X found!". Replaced with plainapt-getplus apkg-configassertion so a dependency problem is reported where it happens. Alsolibfuse2does not exist on Ubuntu 24.04 —libfuse2t64provideslibfuse.so.2.CMAKE_RELATIVE_PATH_TOP_SOURCEto a developer's absolute path. The aarch64 leg built and passed the full test suite, then failed at install trying to read/Users/…on a Linux runner. Untracked, and in-source CMake output is now gitignored.web-dmxstep that Windows and macOS received in ce0fda1. The CMake install rule is guarded byEXISTS, so the AppImage would have silently shipped without the SPA.Verification
Beyond a green run, the published artifacts were executed in containers:
rc=0, correct version bannerGLIBC_2.38/GLIBCXX_3.4.32rc=0rc=0Bookworm rejects exactly the two symbol versions the new ABI gate measures, which is what the gate is for.
Three verification steps were added to the job:
GLIBCXX_3.4.32and libstdc++ is not bundled, so a single-axis check could stay green while Pi compatibility broke.minimalplatform plugin, so the test cannot pass by silently linking against the runner's/opt/Qt. It also asserts the version string, not just the exit code.Raspberry Pi
The aarch64 AppImage targets Raspberry Pi OS Trixie (64-bit). It does not run on Bookworm — that ships glibc 2.36 and GLIBCXX_3.4.30, below what an Ubuntu 24.04 build requires. CI enforces the Trixie floors on every build, so an AppImage that would fail this way is never published.
The AppImage bundles Qt but not the GL/audio/font stack, so it exits 127 on a bare system.
docs/linux-appimage.mdlists the nine required packages, the Bookworm incompatibility, and how to run without FUSE.