diff --git a/.github/workflows/release-snap.yml b/.github/workflows/release-snap.yml index e28556373..f1063057f 100644 --- a/.github/workflows/release-snap.yml +++ b/.github/workflows/release-snap.yml @@ -1,27 +1,21 @@ -name: Release Snap (Slint, all-hosted) +name: release-snap -# All-hosted Snap pipeline for the native (Slint) qbz — BOTH arches. NOTHING -# runs on the dev box, so the lack of systemd/snapd there does not matter. Two -# independent tracks, each = build-binary -> dump-pack -> publish: -# amd64: build-binary (ubuntu-24.04, MIN-tier + 18 GB swap) -> snap -# (packaging/snap-slint/snapcraft.yaml, plugin: dump). -# arm64: build-binary-arm64 (native ubuntu-24.04-arm, free for public repos, -# reuses release-linux-aarch64.yml's cargo cache) -> snap-arm64 -# (packaging/snap-slint/snapcraft-arm64.yaml, plugin: dump). -# The heavy compile is on free public runners; the snap pack (dump, no compile) -# runs in seconds on a runner that has snapd. This CI upload is the SOLE publish -# path — no Launchpad / "Build from GitHub" is used (the root snapcraft.yaml is -# reference/local-dev only and is removed from the CI working copy below). +# All-hosted Snap pipeline — BOTH arches. Each track = build (the shared +# build-qt-linux.yml, which yields the self-contained AppDir) -> dump-pack -> +# publish. No compilation in snapcraft; the pack runs in seconds on a runner +# with snapd. This CI upload is the SOLE publish path: the Launchpad / +# "Build from GitHub" source recipe (root snapcraft.yaml) is DELETED — core24 +# has Qt 6.4.2 and the tree needs 6.8, so a source build there cannot even +# resolve its dependencies (it OOM'd on their amd64 fleet in the Slint era +# anyway). # -# NOTE: build-binary* duplicates the deb/rpm builders' compile. When the release -# pipeline is unified (build-once -> fan out to deb/rpm/appimage/snap/flatpak), -# these jobs become `download-artifact` of the shared per-arch binaries instead. +# Rewritten 2026-08-25 for the Slint -> Qt frontend switch. on: workflow_dispatch: inputs: tag: - description: "Release tag to package (e.g. v1.2.16). Defaults to the pushed tag." + description: "Release tag to package (e.g. v2.1.0). Defaults to the pushed tag." required: false type: string channel: @@ -41,185 +35,54 @@ concurrency: cancel-in-progress: false jobs: - build-binary: - runs-on: ubuntu-24.04 - timeout-minutes: 180 - steps: - - uses: actions/checkout@v7 + build-amd64: + uses: ./.github/workflows/build-qt-linux.yml + with: + arch: x86_64 - - name: Free disk + swap (sized for the ~30 GB qbz_ui peak) - run: | - sudo rm -rf /usr/share/dotnet /opt/ghc /usr/local/lib/android \ - /opt/hostedtoolcache /usr/local/share/boost /usr/share/swift \ - /usr/local/lib/node_modules || true - sudo docker image prune --all --force || true - ( sudo fallocate -l 18G /swap_extra \ - && sudo chmod 600 /swap_extra \ - && sudo mkswap /swap_extra \ - && sudo swapon /swap_extra ) || echo "extra swap skipped (non-fatal)" - free -h; df -h / - - - name: System dependencies - run: | - sudo apt-get update - sudo apt-get install -y --no-install-recommends \ - build-essential pkg-config cmake clang libclang-dev mold nasm \ - libasound2-dev libjack-jackd2-dev \ - libfontconfig1-dev libfreetype-dev \ - libxkbcommon-dev libwayland-dev libxcb1-dev \ - libgl1-mesa-dev libegl1-mesa-dev \ - libdbus-1-dev libssl-dev \ - libharfbuzz-dev libjbig2dec0-dev libopenjp2-7-dev \ - libjpeg-dev zlib1g-dev libgumbo-dev - - - name: Rust toolchain (pinned dated nightly) - uses: dtolnay/rust-toolchain@master - with: - toolchain: nightly-2026-06-23 - - - name: Cargo cache (Swatinem/rust-cache) - uses: Swatinem/rust-cache@v2 - with: - workspaces: crates -> target - shared-key: slint-linux - cache-on-failure: true - # share the SAME cache as build-slint.yml (same shared-key) so the - # heavy qbz_ui rlib is reused across both workflows. - save-if: false - - - name: Build qbz (memory-tuned MIN tier, swap-backed) - env: - CARGO_INCREMENTAL: '0' - CARGO_BUILD_JOBS: '1' - CARGO_PROFILE_RELEASE_CODEGEN_UNITS: '256' - CARGO_PROFILE_RELEASE_OPT_LEVEL: '2' - RUSTFLAGS: '-C link-arg=-fuse-ld=mold -Z threads=1' - run: | - cargo build --release --manifest-path crates/Cargo.toml -p qbz - strip crates/target/release/qbz || true - ls -lh crates/target/release/qbz - - - name: Upload binary artifact - uses: actions/upload-artifact@v7 - with: - name: qbz-bin-amd64 - path: crates/target/release/qbz - if-no-files-found: error - - build-binary-arm64: - # Native arm64 build (mirrors release-linux-aarch64.yml). Reuses that - # workflow's cargo cache (shared-key slint-linux-aarch64) so it does not - # recompile qbz_ui from cold when the aarch64 build already ran. - runs-on: ubuntu-24.04-arm - timeout-minutes: 180 - steps: - - uses: actions/checkout@v7 - - - name: Free disk + swap (sized for the ~30 GB qbz_ui peak) - run: | - sudo rm -rf /usr/share/dotnet /opt/ghc /usr/local/lib/android \ - /opt/hostedtoolcache /usr/local/share/boost /usr/share/swift \ - /usr/local/lib/node_modules || true - sudo docker image prune --all --force || true - ( sudo fallocate -l 18G /swap_extra \ - && sudo chmod 600 /swap_extra \ - && sudo mkswap /swap_extra \ - && sudo swapon /swap_extra ) || echo "extra swap skipped (non-fatal)" - free -h; df -h / - - - name: System dependencies - run: | - sudo apt-get update - sudo apt-get install -y --no-install-recommends \ - build-essential pkg-config cmake clang libclang-dev mold nasm \ - libasound2-dev libjack-jackd2-dev \ - libfontconfig1-dev libfreetype-dev \ - libxkbcommon-dev libwayland-dev libxcb1-dev \ - libgl1-mesa-dev libegl1-mesa-dev \ - libdbus-1-dev libssl-dev \ - libharfbuzz-dev libjbig2dec0-dev libopenjp2-7-dev \ - libjpeg-dev zlib1g-dev libgumbo-dev - - - name: Rust toolchain (pinned dated nightly) - uses: dtolnay/rust-toolchain@master - with: - toolchain: nightly-2026-06-23 - - - name: Cargo cache (Swatinem/rust-cache) - uses: Swatinem/rust-cache@v2 - with: - workspaces: crates -> target - shared-key: slint-linux-aarch64 - cache-on-failure: true - # reuse release-linux-aarch64.yml's cache (same shared-key); do not - # clobber it from here. - save-if: false - - - name: Build qbz (memory-tuned MIN tier, swap-backed) - env: - CARGO_INCREMENTAL: '0' - CARGO_BUILD_JOBS: '1' - CARGO_PROFILE_RELEASE_CODEGEN_UNITS: '256' - CARGO_PROFILE_RELEASE_OPT_LEVEL: '2' - # No x86 target-features here (aarch64 baseline has NEON). - RUSTFLAGS: '-C link-arg=-fuse-ld=mold -Z threads=1' - run: | - cargo build --release --manifest-path crates/Cargo.toml -p qbz - strip crates/target/release/qbz || true - ls -lh crates/target/release/qbz - - - name: Upload binary artifact - uses: actions/upload-artifact@v7 - with: - name: qbz-bin-arm64 - path: crates/target/release/qbz - if-no-files-found: error + build-arm64: + uses: ./.github/workflows/build-qt-linux.yml + with: + arch: aarch64 snap: - needs: build-binary + needs: build-amd64 runs-on: ubuntu-24.04 - # 30 min was too tight: the v2.0.0 tag run got axed mid-snapcraft (LXD - # setup + platform snaps + pack ran past it). The job does no compilation, - # but snapcraft's container bootstrap alone is highly variable on public - # runners — give it real headroom. + # No compilation here; the headroom is for snapcraft's LXD bootstrap, + # which is highly variable on hosted runners (a 30 min cap got the + # v2.0.0 run axed mid-pack). timeout-minutes: 90 # Credentials at job level so the publish step can gate on them: an empty / - # unset secret SKIPS publish instead of failing the whole run (the snap is - # still built and uploaded as an artifact). + # unset secret SKIPS publish instead of failing the whole run. env: SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }} steps: - uses: actions/checkout@v7 - - name: Download prebuilt binary + - name: Download AppDir uses: actions/download-artifact@v8 with: - name: qbz-bin-amd64 - path: dl + name: qbz-appdir-x86_64 - - name: Stage snap payload (binary + desktop + icon) and recipe + - name: Stage snap payload (AppDir tree + desktop + icon) and recipe run: | set -eux TAG="${{ github.event.inputs.tag || github.ref_name }}" VER="${TAG#v}" + tar -xf appdir.tar mkdir -p snap-payload - install -m755 dl/qbz snap-payload/qbz + cp -a AppDir/usr/bin AppDir/usr/lib AppDir/usr/plugins AppDir/usr/qml snap-payload/ cp packaging/snap/snap/gui/qbz.desktop snap-payload/qbz.desktop cp packaging/snap/snap/gui/qbz.png snap-payload/qbz.png - # Place the dump recipe where snapcraft looks for it, and stamp version. mkdir -p snap - cp packaging/snap-slint/snapcraft.yaml snap/snapcraft.yaml + cp packaging/snap-qt/snapcraft.yaml snap/snapcraft.yaml sed -i "s/^version:.*/version: '${VER}'/" snap/snapcraft.yaml - # The repo ROOT also carries snapcraft.yaml (the SOURCE-build recipe - # for Snap Store remote builders) and snapcraft resolves it over - # snap/snapcraft.yaml — the v2.0.0 run recompiled the whole - # workspace inside LXD and OOM'd the container. Remove the root - # recipes from the CI working copy so only the dump recipe exists. + # Belt and braces: no root recipe may shadow snap/snapcraft.yaml. rm -f snapcraft.yaml .snapcraft.yaml echo "Built snap version: ${VER}" - cat snap/snapcraft.yaml | head -20 + head -20 snap/snapcraft.yaml - - name: Build the snap (no compilation — dump of the prebuilt binary) + - name: Build the snap (dump of the prebuilt AppDir) id: build uses: snapcore/action-build@v1 @@ -238,42 +101,37 @@ jobs: release: ${{ github.event.inputs.channel || 'edge' }} snap-arm64: - needs: build-binary-arm64 + needs: build-arm64 runs-on: ubuntu-24.04-arm - # No compilation here (plugin: dump); the headroom is for snapcraft's LXD - # bootstrap, which is variable on hosted runners. timeout-minutes: 90 env: SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }} steps: - uses: actions/checkout@v7 - - name: Download prebuilt binary + - name: Download AppDir uses: actions/download-artifact@v8 with: - name: qbz-bin-arm64 - path: dl + name: qbz-appdir-aarch64 - - name: Stage snap payload (binary + desktop + icon) and recipe + - name: Stage snap payload (AppDir tree + desktop + icon) and recipe run: | set -eux TAG="${{ github.event.inputs.tag || github.ref_name }}" VER="${TAG#v}" + tar -xf appdir.tar mkdir -p snap-payload - install -m755 dl/qbz snap-payload/qbz + cp -a AppDir/usr/bin AppDir/usr/lib AppDir/usr/plugins AppDir/usr/qml snap-payload/ cp packaging/snap/snap/gui/qbz.desktop snap-payload/qbz.desktop cp packaging/snap/snap/gui/qbz.png snap-payload/qbz.png - # Place the arm64 dump recipe where snapcraft looks for it, stamp version. mkdir -p snap - cp packaging/snap-slint/snapcraft-arm64.yaml snap/snapcraft.yaml + cp packaging/snap-qt/snapcraft-arm64.yaml snap/snapcraft.yaml sed -i "s/^version:.*/version: '${VER}'/" snap/snapcraft.yaml - # Remove the root source-build recipe from the CI working copy so - # snapcraft resolves ONLY the dump recipe (see the amd64 job). rm -f snapcraft.yaml .snapcraft.yaml echo "Built snap version: ${VER} (arm64)" - cat snap/snapcraft.yaml | head -20 + head -20 snap/snapcraft.yaml - - name: Build the snap (no compilation — dump of the prebuilt binary) + - name: Build the snap (dump of the prebuilt AppDir) id: build uses: snapcore/action-build@v1 diff --git a/packaging/snap-slint/snapcraft-arm64.yaml b/packaging/snap-qt/snapcraft-arm64.yaml similarity index 52% rename from packaging/snap-slint/snapcraft-arm64.yaml rename to packaging/snap-qt/snapcraft-arm64.yaml index cad032324..2c89b2cba 100644 --- a/packaging/snap-slint/snapcraft-arm64.yaml +++ b/packaging/snap-qt/snapcraft-arm64.yaml @@ -1,16 +1,18 @@ -# QBZ (Slint) — arm64 Snap recipe that PACKAGES A PRE-BUILT BINARY (plugin: dump). +# QBZ (Qt) — arm64 Snap recipe that PACKAGES THE PRE-BUILT AppDir (plugin: dump). # -# arm64 sibling of snapcraft.yaml (amd64). Differences vs the amd64 recipe: -# - platforms: arm64 -# - the alsa-lib layout bind points at the aarch64 multiarch dir. -# Everything else (apps/plugs/slots/stage-packages) is identical; stage-packages -# resolve to arm64 automatically on the arm64 runner. Keep the runtime sections -# in sync with snapcraft.yaml (amd64) and the root snapcraft.yaml. +# release-snap.yml gets the self-contained AppDir from build-qt-linux.yml +# (the qbz binary + the Qt libraries + platform/QML plugins + qt.conf), stages +# it under ./snap-payload/ with the .desktop and icon, stamps `version:` from +# the tag, and runs `snapcraft` — NO compilation here. # -# release-snap.yml's arm64 track stages the prebuilt aarch64 qbz binary under -# ./snap-payload/, copies THIS file to snap/snapcraft.yaml, stamps `version:` -# from the tag, and runs `snapcraft` on a native ubuntu-24.04-arm runner -# (plugin: dump → no compilation). +# WHY THE AppDir AND NOT THE BARE BINARY (2026-08-25): the tree needs Qt >= 6.8 +# and core24 = Ubuntu 24.04 = Qt 6.4.2 without QtQuick.Effects, so neither +# stage-packages nor a source build (the old root snapcraft.yaml, deleted) can +# provide Qt. The gnome extension stays for the desktop platform plugs and the +# GL/Wayland runtime; Qt itself rides in $SNAP/opt/qbz. qt.conf (Prefix=../) +# and the $ORIGIN RPATH make that tree relocatable with no env. +# +# snapcraft.yaml (amd64) is this file with platforms/alsa-lib paths swapped. name: qbz-player # keep the existing registered Snap Store name title: "QBZ — Native Qobuz Client for Linux" @@ -22,10 +24,11 @@ description: | output, exclusive device access, and per-track sample-rate switching for external DACs — up to 24-bit / 192 kHz. - This is the native (Slint) build: a single self-contained binary, no web - runtime. Features: native Qobuz(TM) streaming, bit-perfect ALSA exclusive - mode, DAC passthrough, Hi-Res FLAC, queue/playlists/favorites/offline cache, - local library, Chromecast and DLNA, MPRIS media keys and desktop integration. + A single native process with a Qt/QML interface, no web runtime. Features: + native Qobuz(TM) streaming, bit-perfect ALSA exclusive mode, DAC passthrough, + Hi-Res FLAC, DSD, CD/SACD playback, queue/playlists/favorites/offline cache, + local library plus Plex, Jellyfin and Subsonic servers, Chromecast and DLNA, + MPRIS media keys and desktop integration. QBZ uses the Qobuz(TM) API but is not affiliated with, endorsed by, or certified by Qobuz. @@ -46,7 +49,7 @@ platforms: # ALSA config/plugin binds: without these the snap's alsa-lib cannot find the # host's ALSA configuration and plugin set, and the direct hw: (bit-perfect) -# path breaks. aarch64 multiarch dir here (vs x86_64 in the amd64 recipe). +# path breaks. layout: /usr/share/alsa: bind: $SNAP/usr/share/alsa @@ -57,12 +60,10 @@ layout: apps: qbz: - command: bin/qbz + command: opt/qbz/bin/qbz desktop: usr/share/applications/qbz.desktop - # The gnome extension provides the graphics/font platform (Mesa GL, EGL, - # fontconfig, wayland) that a femtovg-wgpu + winit app needs — it is NOT - # about GTK here, just the runtime platform. It wires desktop/wayland/x11/ - # gsettings plugs automatically. + # The gnome extension provides the graphics platform (Mesa GL, EGL, + # wayland, fontconfig) and wires desktop/wayland/x11/gsettings plugs. extensions: [gnome] plugs: - network @@ -84,12 +85,16 @@ slots: parts: qbz: plugin: dump - # release-snap.yml writes the prebuilt aarch64 binary + desktop + icon here: + # release-snap.yml writes AppDir/usr/{bin,lib,plugins,qml} + desktop + icon here: source: ./snap-payload organize: - qbz: bin/qbz + bin: opt/qbz/bin + lib: opt/qbz/lib + plugins: opt/qbz/plugins + qml: opt/qbz/qml qbz.desktop: usr/share/applications/qbz.desktop qbz.png: usr/share/icons/hicolor/256x256/apps/qbz.png + # Runtime the AppDir does NOT carry (linuxdeploy's blacklist). stage-packages: # Audio (the bit-perfect path) - libasound2t64 @@ -98,25 +103,29 @@ parts: - libjack-jackd2-0 # TLS / HTTP - libssl3t64 - # GPU stack for femtovg-wgpu (Vulkan first, GL fallback). The gnome - # extension ships Mesa GL; add the Vulkan ICD + loader explicitly since - # wgpu prefers Vulkan and the platform may not expose the ICD. - - libvulkan1 - - mesa-vulkan-drivers - - libegl1 - - libgl1 - # winit windowing (Wayland + X11) + # Qt's xcb + wayland platform plugins + - libxkbcommon0 + - libxkbcommon-x11-0 + - libxcb1 + - libxcb-cursor0 + - libxcb-icccm4 + - libxcb-image0 + - libxcb-keysyms1 + - libxcb-render-util0 + - libxcb-shape0 + - libxcb-xkb1 + - libxcb-randr0 + - libxcb-sync1 + - libxcb-xfixes0 + - libxcb-glx0 + - libx11-6 - libwayland-client0 - libwayland-cursor0 - libwayland-egl1 - - libxkbcommon0 - - libxcb1 - - libx11-6 - - libxcursor1 - - libxi6 - - libxrandr2 - # Fonts / text shaping (femtovg) + - libegl1 + - libgl1 + # Fonts - libfontconfig1 - libfreetype6 - # Tray (ksni) + portals + media controls over D-Bus + # Tray + portals + media controls over D-Bus - libdbus-1-3 diff --git a/packaging/snap-qt/snapcraft.yaml b/packaging/snap-qt/snapcraft.yaml new file mode 100644 index 000000000..00e43c7f6 --- /dev/null +++ b/packaging/snap-qt/snapcraft.yaml @@ -0,0 +1,131 @@ +# QBZ (Qt) — Snap recipe that PACKAGES THE PRE-BUILT AppDir (plugin: dump). +# +# release-snap.yml gets the self-contained AppDir from build-qt-linux.yml +# (the qbz binary + the Qt libraries + platform/QML plugins + qt.conf), stages +# it under ./snap-payload/ with the .desktop and icon, stamps `version:` from +# the tag, and runs `snapcraft` — NO compilation here. +# +# WHY THE AppDir AND NOT THE BARE BINARY (2026-08-25): the tree needs Qt >= 6.8 +# and core24 = Ubuntu 24.04 = Qt 6.4.2 without QtQuick.Effects, so neither +# stage-packages nor a source build (the old root snapcraft.yaml, deleted) can +# provide Qt. The gnome extension stays for the desktop platform plugs and the +# GL/Wayland runtime; Qt itself rides in $SNAP/opt/qbz. qt.conf (Prefix=../) +# and the $ORIGIN RPATH make that tree relocatable with no env. +# +# snapcraft-arm64.yaml is this file with platforms/alsa-lib paths swapped. + +name: qbz-player # keep the existing registered Snap Store name +title: "QBZ — Native Qobuz Client for Linux" +version: '0.0.0' # OVERWRITTEN by release-snap.yml from the tag (sed) +summary: Native Qobuz player for Linux with bit-perfect audio and DAC control +description: | + QBZ is a native Linux desktop client for Qobuz(TM), built for high-fidelity + playback with a native audio pipeline (direct ALSA and PipeWire), bit-perfect + output, exclusive device access, and per-track sample-rate switching for + external DACs — up to 24-bit / 192 kHz. + + A single native process with a Qt/QML interface, no web runtime. Features: + native Qobuz(TM) streaming, bit-perfect ALSA exclusive mode, DAC passthrough, + Hi-Res FLAC, DSD, CD/SACD playback, queue/playlists/favorites/offline cache, + local library plus Plex, Jellyfin and Subsonic servers, Chromecast and DLNA, + MPRIS media keys and desktop integration. + + QBZ uses the Qobuz(TM) API but is not affiliated with, endorsed by, or + certified by Qobuz. + +license: MIT +contact: https://github.com/vicrodh/qbz/discussions +website: https://qbz.lol +source-code: https://github.com/vicrodh/qbz +issues: https://github.com/vicrodh/qbz/issues + +grade: stable +confinement: strict +base: core24 +icon: packaging/snap/snap/gui/qbz.png + +platforms: + amd64: + +# ALSA config/plugin binds: without these the snap's alsa-lib cannot find the +# host's ALSA configuration and plugin set, and the direct hw: (bit-perfect) +# path breaks. +layout: + /usr/share/alsa: + bind: $SNAP/usr/share/alsa + /etc/alsa: + bind: $SNAP/etc/alsa + /usr/lib/x86_64-linux-gnu/alsa-lib: + bind: $SNAP/usr/lib/x86_64-linux-gnu/alsa-lib + +apps: + qbz: + command: opt/qbz/bin/qbz + desktop: usr/share/applications/qbz.desktop + # The gnome extension provides the graphics platform (Mesa GL, EGL, + # wayland, fontconfig) and wires desktop/wayland/x11/gsettings plugs. + extensions: [gnome] + plugs: + - network + - network-status + - audio-playback + - home + - removable-media + - alsa + - pipewire + - opengl + slots: + - mpris + +slots: + mpris: + interface: mpris + name: qbz + +parts: + qbz: + plugin: dump + # release-snap.yml writes AppDir/usr/{bin,lib,plugins,qml} + desktop + icon here: + source: ./snap-payload + organize: + bin: opt/qbz/bin + lib: opt/qbz/lib + plugins: opt/qbz/plugins + qml: opt/qbz/qml + qbz.desktop: usr/share/applications/qbz.desktop + qbz.png: usr/share/icons/hicolor/256x256/apps/qbz.png + # Runtime the AppDir does NOT carry (linuxdeploy's blacklist). + stage-packages: + # Audio (the bit-perfect path) + - libasound2t64 + - libasound2-plugins + - libpipewire-0.3-0 + - libjack-jackd2-0 + # TLS / HTTP + - libssl3t64 + # Qt's xcb + wayland platform plugins + - libxkbcommon0 + - libxkbcommon-x11-0 + - libxcb1 + - libxcb-cursor0 + - libxcb-icccm4 + - libxcb-image0 + - libxcb-keysyms1 + - libxcb-render-util0 + - libxcb-shape0 + - libxcb-xkb1 + - libxcb-randr0 + - libxcb-sync1 + - libxcb-xfixes0 + - libxcb-glx0 + - libx11-6 + - libwayland-client0 + - libwayland-cursor0 + - libwayland-egl1 + - libegl1 + - libgl1 + # Fonts + - libfontconfig1 + - libfreetype6 + # Tray + portals + media controls over D-Bus + - libdbus-1-3 diff --git a/packaging/snap-slint/snapcraft.yaml b/packaging/snap-slint/snapcraft.yaml deleted file mode 100644 index 9f26f7606..000000000 --- a/packaging/snap-slint/snapcraft.yaml +++ /dev/null @@ -1,126 +0,0 @@ -# QBZ (Slint) — Snap recipe that PACKAGES A PRE-BUILT BINARY (plugin: dump). -# -# This is NOT the Tauri snapcraft.yaml (../../snapcraft.yaml). That one builds -# from source (plugin: rust + npm tauri build, webkit2gtk). This one takes a -# qbz binary ALREADY built (e.g. on a 16 GB hosted runner with swap, or the -# self-hosted box) and just wraps it into a .snap — NO compilation here, so it -# runs in seconds on any runner that has snapd (the dev box does not need it). -# -# The CI job (release-snap.yml) stages the binary + .desktop + icon under -# ./snap-payload/ and substitutes `version:` from the release tag, then runs -# `snapcraft` (which lives on the hosted Ubuntu runner) + snapcore/action-publish. -# -# UNTESTED runtime confinement: the Slint app uses femtovg-wgpu (Vulkan/GL) + -# winit (Wayland/X11), NOT GTK/webkit. The stage-packages + plugs below are a -# best-effort first cut; the FIRST real `snapcraft` build + `snap run` on the -# runner will surface any missing lib / interface (I can't test snapd locally). - -name: qbz-player # keep the existing registered Snap Store name -title: "QBZ — Native Qobuz Client for Linux" -version: '0.0.0' # OVERWRITTEN by release-snap.yml from the tag (sed) -summary: Native Qobuz player for Linux with bit-perfect audio and DAC control -description: | - QBZ is a native Linux desktop client for Qobuz(TM), built for high-fidelity - playback with a native audio pipeline (direct ALSA and PipeWire), bit-perfect - output, exclusive device access, and per-track sample-rate switching for - external DACs — up to 24-bit / 192 kHz. - - This is the native (Slint) build: a single self-contained binary, no web - runtime. Features: native Qobuz(TM) streaming, bit-perfect ALSA exclusive - mode, DAC passthrough, Hi-Res FLAC, queue/playlists/favorites/offline cache, - local library, Chromecast and DLNA, MPRIS media keys and desktop integration. - - QBZ uses the Qobuz(TM) API but is not affiliated with, endorsed by, or - certified by Qobuz. - -license: MIT -contact: https://github.com/vicrodh/qbz/discussions -website: https://qbz.lol -source-code: https://github.com/vicrodh/qbz -issues: https://github.com/vicrodh/qbz/issues - -grade: stable -confinement: strict -base: core24 -icon: packaging/snap/snap/gui/qbz.png - -platforms: - amd64: - # arm64 is a separate job (needs an arm64 binary + runner); add later. - -# ALSA config/plugin binds: without these the snap's alsa-lib cannot find the -# host's ALSA configuration and plugin set, and the direct hw: (bit-perfect) -# path breaks. Restored from the 1.2.x recipe (review fix 2026-07-03). -layout: - /usr/share/alsa: - bind: $SNAP/usr/share/alsa - /etc/alsa: - bind: $SNAP/etc/alsa - /usr/lib/x86_64-linux-gnu/alsa-lib: - bind: $SNAP/usr/lib/x86_64-linux-gnu/alsa-lib - -apps: - qbz: - command: bin/qbz - desktop: usr/share/applications/qbz.desktop - # The gnome extension provides the graphics/font platform (Mesa GL, EGL, - # fontconfig, wayland) that a femtovg-wgpu + winit app needs — it is NOT - # about GTK here, just the runtime platform. It wires desktop/wayland/x11/ - # gsettings plugs automatically. - extensions: [gnome] - plugs: - - network - - network-status - - audio-playback - - home - - removable-media - - alsa - - pipewire - - opengl - slots: - - mpris - -slots: - mpris: - interface: mpris - name: qbz - -parts: - qbz: - plugin: dump - # release-snap.yml writes the prebuilt binary + desktop + icon here: - source: ./snap-payload - organize: - qbz: bin/qbz - qbz.desktop: usr/share/applications/qbz.desktop - qbz.png: usr/share/icons/hicolor/256x256/apps/qbz.png - stage-packages: - # Audio (the bit-perfect path) - - libasound2t64 - - libasound2-plugins - - libpipewire-0.3-0 - - libjack-jackd2-0 - # TLS / HTTP - - libssl3t64 - # GPU stack for femtovg-wgpu (Vulkan first, GL fallback). The gnome - # extension ships Mesa GL; add the Vulkan ICD + loader explicitly since - # wgpu prefers Vulkan and the platform may not expose the ICD. - - libvulkan1 - - mesa-vulkan-drivers - - libegl1 - - libgl1 - # winit windowing (Wayland + X11) - - libwayland-client0 - - libwayland-cursor0 - - libwayland-egl1 - - libxkbcommon0 - - libxcb1 - - libx11-6 - - libxcursor1 - - libxi6 - - libxrandr2 - # Fonts / text shaping (femtovg) - - libfontconfig1 - - libfreetype6 - # Tray (ksni) + portals + media controls over D-Bus - - libdbus-1-3 diff --git a/packaging/snap/snapcraft.yaml b/packaging/snap/snapcraft.yaml deleted file mode 120000 index 40a3a1bf2..000000000 --- a/packaging/snap/snapcraft.yaml +++ /dev/null @@ -1 +0,0 @@ -../../snapcraft.yaml \ No newline at end of file diff --git a/snapcraft.yaml b/snapcraft.yaml deleted file mode 100644 index 7e18d1ae3..000000000 --- a/snapcraft.yaml +++ /dev/null @@ -1,161 +0,0 @@ -# QBZ Snap recipe — SOURCE build of the Slint app (crates/ workspace). -# -# Rewritten 2026-07-02 for the Tauri -> Slint migration (v2.0). This root -# file is what `snapcraft` picks up when building from the repo (local -# builds / any builder pointed at the repo root). packaging/snap/snapcraft.yaml -# is a symlink to THIS file — keep it that way. -# -# NOTE: the CI release path (release-snap.yml) does NOT use this file — it -# builds the binary on a swap-equipped 16 GB runner and wraps it with the -# dump-plugin recipe in packaging/snap-slint/snapcraft.yaml. Reason: the -# qbz_ui rustc peaks ~30 GB (RSS+swap); small remote builders (e.g. -# Launchpad) will OOM building this recipe from source. Keep the runtime -# sections (apps/plugs/stage-packages) in sync with packaging/snap-slint/. - -name: qbz-player # keep the existing registered Snap Store name -title: "QBZ — Native Qobuz Client for Linux" -version: git -summary: Native Qobuz player for Linux with bit-perfect audio and DAC control -description: | - QBZ is a native Linux desktop client for Qobuz(TM), built for high-fidelity - playback with a native audio pipeline (direct ALSA and PipeWire), bit-perfect - output, exclusive device access, and per-track sample-rate switching for - external DACs — up to 24-bit / 192 kHz. - - This is the native (Slint) build: a single self-contained binary, no web - runtime. Features: native Qobuz(TM) streaming, bit-perfect ALSA exclusive - mode, DAC passthrough, Hi-Res FLAC, queue/playlists/favorites/offline cache, - local library, Chromecast and DLNA, MPRIS media keys and desktop integration. - - QBZ uses the Qobuz(TM) API but is not affiliated with, endorsed by, or - certified by Qobuz. - -license: MIT -contact: https://github.com/vicrodh/qbz/discussions -website: https://qbz.lol -source-code: https://github.com/vicrodh/qbz -issues: https://github.com/vicrodh/qbz/issues - -grade: stable -confinement: strict -base: core24 -icon: packaging/snap/snap/gui/qbz.png - -platforms: - amd64: - arm64: - -# ALSA config/plugin binds: without these the snap's alsa-lib cannot find the -# host's ALSA configuration and plugin set, and the direct hw: (bit-perfect) -# path breaks. Restored from the 1.2.x recipe (review fix 2026-07-03). -layout: - /usr/share/alsa: - bind: $SNAP/usr/share/alsa - /etc/alsa: - bind: $SNAP/etc/alsa - /usr/lib/x86_64-linux-gnu/alsa-lib: - bind: $SNAP/usr/lib/x86_64-linux-gnu/alsa-lib - /usr/lib/aarch64-linux-gnu/alsa-lib: - bind: $SNAP/usr/lib/aarch64-linux-gnu/alsa-lib - -apps: - qbz: - command: bin/qbz - desktop: usr/share/applications/qbz.desktop - # The gnome extension provides the graphics/font platform (Mesa GL, EGL, - # fontconfig, wayland) that a femtovg-wgpu + winit app needs — it is NOT - # about GTK here, just the runtime platform. It wires desktop/wayland/x11/ - # gsettings plugs automatically. - extensions: [gnome] - plugs: - - network - - network-status - - audio-playback - - home - - removable-media - - alsa - - pipewire - - opengl - slots: - - mpris - -slots: - mpris: - interface: mpris - name: qbz - -parts: - qbz: - plugin: nil - source: . - build-packages: - - curl - - pkg-config - - clang - - nasm - - mold - - libasound2-dev - - libjack-jackd2-dev - - libfontconfig1-dev - - libfreetype-dev - - libxkbcommon-dev - - libwayland-dev - - libxcb1-dev - - libgl1-mesa-dev - - libegl1-mesa-dev - - libdbus-1-dev - - libssl-dev - - libharfbuzz-dev - - libjbig2dec0-dev - - libopenjp2-7-dev - - libjpeg-dev - - zlib1g-dev - - libgumbo-dev - override-build: | - # Rust via rustup (the archive's rustc is too old for Slint). - export RUSTUP_HOME="$SNAPCRAFT_PART_BUILD/.rustup" - export CARGO_HOME="$SNAPCRAFT_PART_BUILD/.cargo" - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \ - sh -s -- -y --profile minimal --default-toolchain stable - export PATH="$CARGO_HOME/bin:$PATH" - - # MIN memory tier: the qbz_ui rustc peaks ~30 GB. Symbols are stripped - # by the workspace [profile.release]. - export CARGO_INCREMENTAL=0 - export CARGO_BUILD_JOBS=1 - export CARGO_PROFILE_RELEASE_CODEGEN_UNITS=256 - export CARGO_PROFILE_RELEASE_OPT_LEVEL=2 - export RUSTFLAGS="-C link-arg=-fuse-ld=mold" - cargo build --release --manifest-path crates/Cargo.toml -p qbz - - install -Dm755 crates/target/release/qbz "$SNAPCRAFT_PART_INSTALL/bin/qbz" - install -Dm644 packaging/linux/qbz.desktop \ - "$SNAPCRAFT_PART_INSTALL/usr/share/applications/qbz.desktop" - install -Dm644 packaging/icons/256x256.png \ - "$SNAPCRAFT_PART_INSTALL/usr/share/icons/hicolor/256x256/apps/qbz.png" - stage-packages: - # Audio (the bit-perfect path) - - libasound2t64 - - libasound2-plugins - - libpipewire-0.3-0 - - libjack-jackd2-0 - # GPU stack for femtovg-wgpu (Vulkan first, GL fallback) - - libvulkan1 - - mesa-vulkan-drivers - - libegl1 - - libgl1 - # winit windowing (Wayland + X11) - - libwayland-client0 - - libwayland-cursor0 - - libwayland-egl1 - - libxkbcommon0 - - libxcb1 - - libx11-6 - - libxcursor1 - - libxi6 - - libxrandr2 - # Fonts / text shaping (femtovg) - - libfontconfig1 - - libfreetype6 - # Tray (ksni) + portals + media controls over D-Bus - - libdbus-1-3