feat(build): cross-platform desktop packaging; bump to 0.1.0
Build & Release / Run Tests (push) Has been cancelled
Traceability Validation / Check Requirement Traces (push) Has been cancelled
Build & Release / Build Linux (push) Has been cancelled
Build & Release / Build Android (push) Has been cancelled
Publish Documentation / Build & publish docs to gitea-pages (push) Has been cancelled
🏗️ Build and Test JellyTau / Android Compile Check (push) Has been cancelled
Build & Release / Create Release (push) Has been cancelled
🏗️ Build and Test JellyTau / Run Tests (push) Has been cancelled

Adds Docker-based packaging for Linux desktop (deb/rpm), Arch
(.pkg.tar.zst via makepkg), and Windows. Windows cross-compiles from
Linux via the official Tauri path — the x86_64-pc-windows-msvc target
driven by cargo-xwin — and produces an NSIS installer (nsis via
tauri.conf.json targets, since the CLI rejects --bundles nsis on a Linux
host). Verified end to end: builds jellytau.exe + jellytau_x64-setup.exe.

Unifies everything on one registry builder image (Dockerfile.builder):
Android SDK/NDK, rpm/file, clang(+clang-cl)/lld/llvm/nsis, cargo-xwin and
the msvc target. Packaging tools sit in a trailing layer so tool changes
rebuild in ~1min instead of ~15. Desktop stages are thin FROM
${BUILDER_IMAGE} layers; Arch uses a separate archlinux image.

CLAUDE.md: CI must install no system toolchains — everything lives in the
image. Bumps version 0.0.18 -> 0.1.0 (Windows support + webview audio +
equalizer).

TRACES: UR-003, UR-005 | DR-004
This commit is contained in:
2026-07-24 23:49:50 +02:00
parent d4e2cd120c
commit 742ad88a29
14 changed files with 555 additions and 4 deletions
+91
View File
@@ -0,0 +1,91 @@
# Desktop packaging (Linux, Arch, Windows)
How to produce distributable desktop packages for JellyTau. All three flows can
run in Docker so no host toolchain setup is required. Outputs land in `./dist`.
## One builder image (shared with CI)
The deb/rpm and Windows-cross flows build on the **unified registry builder**
([../Dockerfile.builder](../Dockerfile.builder) →
`gitea.tourolle.paris/dtourolle/jellytau-builder`), the same image CI uses. It
carries every packaging tool: Android SDK/NDK, `rpm`/`file` (Linux bundler),
`cargo-xwin` + `lld` + `llvm` + `nsis` + the `x86_64-pc-windows-msvc` rust target
(Windows). There is **one** dependency source of truth — no per-stage tool
installs.
The desktop stages in [../Dockerfile](../Dockerfile) are thin `FROM
${BUILDER_IMAGE}` environments; the actual build runs at container-run time on
your bind-mounted source (like the `dev` service), so source edits need no image
rebuild.
**If you changed `Dockerfile.builder`** (e.g. added a tool), rebuild and push it
first, or the packaging flows use the stale registry image:
```bash
scripts/build-builder-image.sh # build + push :latest to the registry
# ...or iterate locally without pushing:
docker build -f Dockerfile.builder -t jellytau-builder:latest .
BUILDER_IMAGE=jellytau-builder:latest bun run docker:build:windows
```
Arch uses a separate `archlinux` image ([../Dockerfile.arch](../Dockerfile.arch))
because `makepkg` is Arch-specific — it is not part of the unified builder.
| Target | Format | Docker command | Functional? |
|--------|--------|----------------|-------------|
| Debian/Ubuntu, Fedora | `.deb`, `.rpm` | `bun run docker:build:linux` | ✅ yes |
| Arch Linux | `.pkg.tar.zst` | `bun run docker:build:arch` | ✅ yes |
| Windows | NSIS installer + `.exe` | `bun run docker:build:windows` | ✅ yes (unsigned) |
## Linux: deb + rpm
Tauri's bundler produces these natively. The build runs on the existing Ubuntu
builder image ([../Dockerfile](../Dockerfile), `desktop-linux-build` stage):
```bash
bun run docker:build:linux # deb + rpm -> ./dist
# or, on a host with the Tauri Linux deps installed:
BUNDLES="deb,rpm" scripts/build-desktop-linux.sh
```
Runtime dependency: the app links libmpv (audio) and WebKitGTK (webview + HTML5
transcoded video). The deb/rpm declare these.
> Note: `appimage` is also a valid Tauri target if you want a portable bundle —
> add it to `BUNDLES`.
## Arch Linux: pacman package
**Tauri has no `pacman` bundle target** (as of tauri-cli 2.9.x — valid targets
are deb/rpm/appimage/msi/nsis/app/dmg). So we ship a hand-written PKGBUILD in
[../packaging/arch/PKGBUILD](../packaging/arch/PKGBUILD) and build it with
`makepkg` on an Arch base image ([../Dockerfile.arch](../Dockerfile.arch)):
```bash
bun run docker:build:arch # .pkg.tar.zst -> ./dist
```
The PKGBUILD is AUR-ready: swap its `source=()` for a release tarball/VCS URL to
publish. Runtime deps: `webkit2gtk-4.1`, `mpv`, `gtk3`, `libayatana-appindicator`.
`makepkg` refuses to run as root, so the Docker stage builds as a non-root
`builder` user. Because the image `COPY`s the source at build time, the
`arch-build` compose service does **not** bind-mount the repo — rebuild the image
to pick up source changes.
## Windows: NSIS installer cross-compiled from Linux
Produces a working (unsigned) NSIS installer + `.exe` via the official Tauri
cross-compile path — the `x86_64-pc-windows-msvc` target driven by `cargo-xwin`.
Video plays via WebView2 and audio via the webview `<audio>` backend. See
[build-windows.md](build-windows.md) for the full explanation.
```bash
bun run docker:build:windows # NSIS installer + .exe -> ./dist
WIN_BUNDLES=none bun run docker:build:windows # exe only, skip bundling
```
The Docker `windows-cross` stage is a thin layer over the builder, which carries
`cargo-xwin` + `lld` + `llvm` + `nsis` + the `x86_64-pc-windows-msvc` target.
Cross-compilation is Tauri's "last resort" path (less tested than building on
Windows); a `windows-latest` CI job is the fallback if it misbehaves.