{{ message }}
feat: Linux portable builds (CPU + NVIDIA) and release workflow#220
Merged
Conversation
added 3 commits
June 24, 2026 11:39
Adds a Linux .tar.gz portable package mirroring the existing Windows/macOS
build paths. Bundles a python-build-standalone runtime (CPU torch + demucs)
plus the Tauri binary so users extract and run ./StemDeck.
- scripts/linux/make-portable.sh: stages PBS Python, force-installs CPU-only
torch, builds the Tauri binary, and produces StemDeck-Linux-x64.tar.gz with
the backend/app + python/ layout find_repo_root resolves at runtime.
- .github/workflows/linux-release.yml: builds on hosted ubuntu-latest on
release publish; installs Tauri v2 apt deps + uv, ClamAV-scans, uploads.
- packaging/linux/{README-LINUX,THIRD_PARTY_NOTICES}.txt: extract-and-run
instructions noting ffmpeg + WebKitGTK are system (apt) prerequisites.
FFmpeg is not bundled: the Linux shell expects ffmpeg on PATH. NVIDIA/CUDA
and AppImage variants are intentionally deferred to later phases.
The Linux backend failed to start with 'ModuleNotFoundError: No module named encodings'. PYTHONHOME was being set to python/bin instead of the prefix python/, so CPython looked for its stdlib under python/bin/lib and could not boot. Linux bundles python-build-standalone exactly like macOS, which detects its own prefix by walking up from bin/ and must NOT have PYTHONHOME set. The two PYTHONHOME sites were gated #[cfg(not(target_os = "macos"))], wrongly including Linux alongside Windows. Only Windows -- whose portable venv keeps the stdlib under base/Lib -- needs PYTHONHOME, so gate both sites (start_backend and python_stdlib_ok) to #[cfg(windows)]. This also fixes the latent inconsistency where probe_runtime reported Python ready (python_stdlib_ok set PYTHONHOME=python, the correct prefix) while start_backend set PYTHONHOME=python/bin and failed.
Adds a second Linux package, StemDeck-Linux-x64.NVIDIA.tar.gz, with CUDA-enabled torch baked in (mirrors the Windows NVIDIA variant). - make-portable.sh: CPU_ONLY toggle (default 1). CPU_ONLY=0 keeps the project's default torch wheel, which on Linux x86_64 is the CUDA build, and omits the cpu-only marker so the desktop shell detects the GPU and uses CUDA at runtime. No app-side changes needed -- the CUDA detection/ install path in main.rs is already cfg(not(macos)) and covers Linux. - linux-release.yml: builds both variants in one job. CPU first (full Tauri build), then NVIDIA with SKIP_TAURI_BUILD=1 reusing the same binary. Adds a free-disk-space step (CUDA bundle is several GB) and drops each uncompressed stage after taring to stay within the hosted runner's disk. - README-LINUX.txt: documents both variants and the NVIDIA driver prerequisite (nvidia-smi must work; CUDA runtime is bundled, no toolkit install needed; falls back to CPU when no GPU).
added 2 commits
June 24, 2026 15:28
Targets the org's self-hosted wsl2 runner ([self-hosted, linux, x64]) instead of hosted ubuntu-latest, matching the Windows/macOS release jobs. Drops the free-disk-space step: it was a hosted-runner workaround and would needlessly rm system directories on a persistent self-hosted box (WSL2's virtual disk has ample room for the CUDA bundle).
Lets you run the full two-variant build + ClamAV scan on the self-hosted runner without publishing a release, to validate the runner toolchain and the CUDA build. Resolves the version from a manual input (default 0.0.0, must be valid PEP 440) instead of the branch ref, and skips the upload step on non-release events.
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.

What
Adds Linux support as portable
.tar.gzpackages — Phase 1+2 of bringing StemDeck to Ubuntu/Linux. Mirrors the existing Windows (portable zip) and macOS (runtime pack) build paths. Ships two variants:StemDeck-Linux-x64.tar.gzStemDeck-Linux-x64.NVIDIA.tar.gzEach bundles a self-contained Python runtime (torch + demucs) plus the Tauri binary, so users extract and run
./StemDeckwith no toolchain.Why a tarball, not
.deb/aptStemDeck's real payload is the bundled torch/demucs venv.
apt/.debis built around a host-managed dependency tree served from a repo — the exact thing a bundled runtime exists to escape. A portable tarball matches the Windows philosophy and avoids fighting apt over torch/CUDA versions..deband AppImage remain deferred.Files
scripts/linux/make-portable.shCPU_ONLYtoggle selects CPU vs NVIDIA..github/workflows/linux-release.ymlubuntu-latestonrelease: published; apt deps + uv, ClamAV scan, upload.packaging/linux/README-LINUX.txtpackaging/linux/THIRD_PARTY_NOTICES.txtImplementation notes
uvfetches a python-build-standalone install copied whole intopython/(the macOS approach, not avenv). Required because the desktop shell'spython_stdlib_present()looks forpython/lib/pythonX.Y/os.py, which a plain venv lacks.torch==2.6.0+cpu --force-reinstall --no-depsswap (same as the Windows script; Linux PyPI wheels bundle CUDA otherwise) + acpu-onlymarker so the shell skips GPU detection.main.rsis alreadycfg(not(macos))and covers Linux; at first launch it detects the GPU and uses CUDA.ubuntu-latest(no GPU needed to build a CUDA package). One job builds CPU first, then NVIDIA reusing the same Tauri binary (SKIP_TAURI_BUILD=1); a free-disk step + dropping each uncompressed stage keeps the large CUDA bundle within the runner's disk.ffmpegonPATH) and WebKitGTK (Tauri links the system libs). NVIDIA needs only a working driver (nvidia-smi); the CUDA runtime is bundled.Bundled bugfix: PYTHONHOME on Linux
Includes a fix to
desktop/src-tauri/src/main.rssurfaced by end-to-end testing: the backend failed to start withModuleNotFoundError: No module named 'encodings'becausePYTHONHOMEwas set topython/bininstead of the prefixpython/. Linux uses python-build-standalone like macOS (auto-detects its prefix frombin/) and must not havePYTHONHOMEset. Both sites were gated#[cfg(not(target_os = "macos"))], wrongly including Linux; now gated#[cfg(windows)].Testing
bash -non the script; workflow YAML validated; Windowscargo checkclean (no new warnings) — confirms the Rust change does not regress the Windows release.Not yet verified (reviewer/maintainer follow-up)
ubuntu-latestdisk limits (the free-disk step is defensive but unproven for this payload), and (2) runtime GPU use, which can only be confirmed on a real Linux + NVIDIA machine (WSL is not a valid test).🤖 Generated with Claude Code