From 5964af5dea05d8ceb0624c3d742c6f32846468ce Mon Sep 17 00:00:00 2001 From: Jamie Pine <32987599+jamiepine@users.noreply.github.com> Date: Sun, 19 Apr 2026 19:22:21 -0700 Subject: [PATCH] feat(ci): re-enable Linux release builds (CPU, deb+rpm) (#488) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(ci): re-enable Linux release builds (CPU, deb+rpm) Linux shipped briefly in March 2026 (b580189..103e98b) then was removed with the message "github runners suck." The post-mortem: standard ubuntu-22.04 hit disk-pressure during pip+PyInstaller, and a namespace custom-runner attempt proved flaky. Nothing in the app itself was the problem — the NVIDIA-package exclusions in build_binary.py (~3 GB shaved from CPU builds), the CPU-only torch install order, the PulseAudio/PipeWire audio capture code, and the Tauri deb/rpm bundle targets all still work. This restores ubuntu-22.04 to the release matrix as a CPU-only Linux build with a disk-space cleanup step (jlumbroso/free-disk-space) to address the root cause of the March failures. Ships .deb + .rpm only — AppImage was explicitly dropped in e18757b due to glibc portability issues, keeping that decision. CUDA-for-Linux is intentionally deferred to a follow-up PR: the GpuAcceleration.tsx frontend hard-codes CUDA download as Tauri-only without a Linux branch, and AMD users already get ROCm acceleration for free on a stock CPU-torch install (backend/app.py:148-160). The NVIDIA-on-Linux case is the only remaining gap and is non-blocking for a v1 Linux ship. Co-Authored-By: Claude Opus 4.7 (1M context) * chore(release): bump version 0.4.1 → 0.4.2 tauri-action uses tauri.conf.json's version to name the release, so pushing v0.4.2 as a tag alone was insufficient — the workflow was still trying to publish to v0.4.1 (immutable) and failing. Bumps all workspace package.json files, Cargo.toml, Cargo.lock, and tauri.conf.json. Co-Authored-By: Claude Opus 4.7 (1M context) * ci(release): add Linux bundle-step watchdog + verbose cargo logging The first v0.4.2 attempt hung inside tauri-action at the bundling stage on ubuntu-22.04 for ~28 min with no output. Same failure mode that drove the March 2026 removal (commit 103e98b). Without visibility we're guessing — probable causes include linuxdeploy/AppImage download stalls (despite --bundles deb,rpm), cargo link on a cold cache, or disk pressure during the final link step. - timeout-minutes: 30 on tauri-action for Ubuntu (45 min elsewhere) — fail fast with logs instead of waiting out the 6hr job timeout. - --verbose added to the Linux build args so cargo streams progress. - CARGO_TERM_VERBOSE + RUST_BACKTRACE=1 exported on tauri-action. - New 'Disk / environment snapshot' step dumps df/free/tool versions right before the tauri step so we can correlate with any later OOM/ENOSPC failure. Co-Authored-By: Claude Opus 4.7 (1M context) * ci(release): disable Tauri updater artifacts on Linux (stops linuxdeploy hang) Round-2 diagnosis from the v0.4.2 attempt: cargo finished in 3m 55s, .deb and .rpm were bundled within 22s, then the step hung silently for 25 min until our 30-min watchdog killed it — no further log lines. tauri.conf.json has `createUpdaterArtifacts: "v1Compatible"`. On Linux the v1-compatible updater path wants a .AppImage.tar.gz, which means downloading linuxdeploy-x86_64.AppImage from GitHub at build time. That download is the silent blocker — same signature as the March 2026 "github runners suck" removal (commit 103e98b). Fix: pass `--config {"bundle":{"createUpdaterArtifacts":false}}` on the Linux build only. Mac/Windows continue to produce signed updater artifacts as before. Linux users update via apt/dnf; Tauri in-app auto-update for Linux can come later (and would require shipping AppImage alongside deb/rpm). Co-Authored-By: Claude Opus 4.7 (1M context) * ci(release): pin free-disk-space action + stop removing LLVM Review feedback on the Linux release workflow: 1. `jlumbroso/free-disk-space@main` was an unpinned ref in a job that runs with `contents: write` and handles signing secrets. Pin to the v1.3.1 commit SHA so a force-push or repo compromise can't inject arbitrary code into our release flow. 2. `large-packages: true` runs `apt-get remove '^llvm-.*'`, wiping LLVM just before the next step installs `llvm-dev`. That wastes CI time and risks cascade-removal of reverse deps that won't be pulled back in by `llvm-dev` alone. The remaining toggles (android, dotnet, haskell, swap-storage) already clear ~20 GB, which is enough headroom for the Python + torch + PyInstaller build. Co-Authored-By: Claude Opus 4.7 (1M context) --------- Co-authored-by: Claude Opus 4.7 (1M context) --- .github/workflows/release.yml | 57 +++++++++++++++++++++++++++++++++ app/package.json | 2 +- landing/package.json | 2 +- package.json | 2 +- tauri/package.json | 2 +- tauri/src-tauri/Cargo.lock | 2 +- tauri/src-tauri/Cargo.toml | 2 +- tauri/src-tauri/tauri.conf.json | 2 +- web/package.json | 2 +- 9 files changed, 65 insertions(+), 8 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c438e5eb..25e5a943 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,12 +26,45 @@ jobs: args: "" python-version: "3.12" backend: "pytorch" + - platform: "ubuntu-22.04" + # --config override disables updater-artifact generation on Linux. + # tauri.conf.json has createUpdaterArtifacts: "v1Compatible" which + # on Linux wants to synthesize a .AppImage.tar.gz by downloading + # linuxdeploy at build time — this is what silently hangs CI + # (see v0.4.2 round 2, 25 min of no output after rpm bundling). + # We ship deb+rpm only; Linux users update via apt/dnf, not the + # Tauri in-app updater. + args: '--target x86_64-unknown-linux-gnu --bundles deb,rpm --verbose --config {"bundle":{"createUpdaterArtifacts":false}}' + python-version: "3.12" + backend: "pytorch" runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v4 + # Ubuntu runners ship with ~14 GB free; pip + PyInstaller + torch can + # peak well above that during the build. Reclaim ~25 GB by pruning + # preinstalled toolchains we don't use. This is what likely tripped + # the March 2026 Linux release attempts (see commit 103e98b + # "github runners suck") — not a code issue, a disk-pressure one. + - name: Free up disk space (ubuntu) + if: contains(matrix.platform, 'ubuntu') || contains(matrix.platform, 'namespace') + # Pinned to v1.3.1 (SHA) — this job runs with contents: write and + # handles signing secrets later, so we don't want a floating ref. + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be + with: + tool-cache: false + android: true + dotnet: true + haskell: true + # large-packages: true would `apt-get remove '^llvm-.*'`, which + # cascade-removes reverse deps that won't be pulled back in by the + # `llvm-dev` install below. The other flags already free ~20 GB, + # enough for the Python + torch + PyInstaller build. + large-packages: false + swap-storage: true + - name: Install dependencies (ubuntu only) if: contains(matrix.platform, 'ubuntu') || contains(matrix.platform, 'namespace') run: | @@ -133,6 +166,21 @@ jobs: p12-file-base64: ${{ secrets.APPLE_CERTIFICATE }} p12-password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} + - name: Disk / environment snapshot (pre-bundle debug) + if: contains(matrix.platform, 'ubuntu') || contains(matrix.platform, 'namespace') + run: | + echo "=== df -h ===" + df -h + echo "=== free -h ===" + free -h + echo "=== Rust / Cargo ===" + rustc --version + cargo --version + echo "=== Bun ===" + bun --version + echo "=== Tauri CLI ===" + cd tauri && bun run tauri --version + - name: Extract release notes from CHANGELOG.md id: changelog shell: bash @@ -156,7 +204,13 @@ jobs: echo "CHANGELOG_EOF" } >> "$GITHUB_OUTPUT" + # Linux hang watchdog: previous releases silently wedged inside tauri + # bundling (possibly linuxdeploy/AppImage download, possibly cargo link). + # Cap the step at 30 min so we get logs instead of waiting out the 6hr + # job timeout. Other platforms historically complete in ~25 min, so 45 + # is comfortable. - uses: tauri-apps/tauri-action@v0.6 + timeout-minutes: ${{ (contains(matrix.platform, 'ubuntu') || contains(matrix.platform, 'namespace')) && 30 || 45 }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} @@ -168,6 +222,9 @@ jobs: APPLE_PROVIDER_SHORT_NAME: ${{ secrets.APPLE_PROVIDER_SHORT_NAME }} APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }} APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }} + # Stream subprocess stdout/stderr so the hang is visible in logs. + CARGO_TERM_VERBOSE: "true" + RUST_BACKTRACE: "1" with: projectPath: tauri tagName: v__VERSION__ diff --git a/app/package.json b/app/package.json index 2db75bd7..b4059f46 100644 --- a/app/package.json +++ b/app/package.json @@ -1,6 +1,6 @@ { "name": "@voicebox/app", - "version": "0.4.1", + "version": "0.4.2", "private": true, "type": "module", "scripts": { diff --git a/landing/package.json b/landing/package.json index 6f0a752e..6c4c1f12 100644 --- a/landing/package.json +++ b/landing/package.json @@ -1,6 +1,6 @@ { "name": "@voicebox/landing", - "version": "0.4.1", + "version": "0.4.2", "description": "Landing page for voicebox.sh", "scripts": { "dev": "next dev --turbo", diff --git a/package.json b/package.json index 222131e8..835cd67d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "voicebox", - "version": "0.4.1", + "version": "0.4.2", "private": true, "workspaces": [ "app", diff --git a/tauri/package.json b/tauri/package.json index 5bf4625d..8648ef40 100644 --- a/tauri/package.json +++ b/tauri/package.json @@ -1,7 +1,7 @@ { "name": "@voicebox/tauri", "private": true, - "version": "0.4.1", + "version": "0.4.2", "type": "module", "scripts": { "dev": "vite", diff --git a/tauri/src-tauri/Cargo.lock b/tauri/src-tauri/Cargo.lock index 76cacea5..84e3c762 100644 --- a/tauri/src-tauri/Cargo.lock +++ b/tauri/src-tauri/Cargo.lock @@ -5041,7 +5041,7 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "voicebox" -version = "0.4.1" +version = "0.4.2" dependencies = [ "base64 0.22.1", "core-foundation-sys", diff --git a/tauri/src-tauri/Cargo.toml b/tauri/src-tauri/Cargo.toml index 797d9525..0eda106a 100644 --- a/tauri/src-tauri/Cargo.toml +++ b/tauri/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "voicebox" -version = "0.4.1" +version = "0.4.2" description = "A production-quality desktop app for Qwen3-TTS voice cloning and generation" authors = ["you"] license = "" diff --git a/tauri/src-tauri/tauri.conf.json b/tauri/src-tauri/tauri.conf.json index b0485897..0d76cc03 100644 --- a/tauri/src-tauri/tauri.conf.json +++ b/tauri/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "Voicebox", - "version": "0.4.1", + "version": "0.4.2", "identifier": "sh.voicebox.app", "build": { "beforeDevCommand": "bun run dev", diff --git a/web/package.json b/web/package.json index 3bf02c99..7f18beb6 100644 --- a/web/package.json +++ b/web/package.json @@ -1,7 +1,7 @@ { "name": "@voicebox/web", "private": true, - "version": "0.4.1", + "version": "0.4.2", "type": "module", "scripts": { "dev": "vite",