Skip to content

Migrate Jpackage default to Hydraulic Conveyor #2051

Merged
maxrave-dev merged 19 commits into
devfrom
feat/conveyor-packaging
May 22, 2026
Merged

Migrate Jpackage default to Hydraulic Conveyor #2051
maxrave-dev merged 19 commits into
devfrom
feat/conveyor-packaging

Conversation

@maxrave-dev
Copy link
Copy Markdown
Owner

No description provided.

- composeApp/icon/dmg-background.png — 2800x1600 source asset
- scripts/wrap-mac-dmg.sh — create-dmg + UDRW + volicon + UDZO pipeline
- desktop-package.yml — add wrap-mac-dmg job (macos-14, needs build-desktop-packages)
- conveyor.conf — auto-infer site.base-url, keep updates=none
- composeApp/build.gradle.kts — revert curated VLC plugin lists to full set
- Split Mac universal.dmg → arm64.dmg + intel64.dmg per machine,
  saves ~25-40 MB per user download (universal was 84.9 MB fat
  binary vs arm64 48.8 MB + intel64 54.8 MB shipped separately)
- Add Windows ARM64 (winarm64.zip from VideoLAN 3.0.23) — opens
  ARM Windows PC support (Surface Pro X, Snapdragon Copilot+ PCs)
- Drop linux.aarch64.glibc machine — VideoLAN ships no Linux ARM
  binary; mahozad/vlc-plugins-linux is amd64-only, so including
  this would ship an AppImage that crashes on first VLCJ load
- Restrict `make site` to mac+windows machines — Conveyor's Linux
  tarball intermediate task was failing even with targets=[], so
  pass -Kapp.machines explicitly to skip the Linux pipeline that
  already ran in the prior `make linux-app` step
- Factor shared Mac DMG + Windows zip extraction into helper
  functions; each per-arch task is now a thin doLast wrapper
get.videolan.org returns a 302 redirect to a different mirror per
request. Java's URL.openStream() follows same-protocol same-host
redirects but silently saves the 302 HTML response body when the
mirror lands on a cross-protocol redirect or returns an error
page — producing "Cannot expand ZIP" downstream.

CI run 26264936101 hit this on the win64 mirror lottery despite
local + winarm64 + Mac DMG downloads succeeding (they got lucky
mirrors that round). Switch to curl -fsSL with retry, which
follows redirects robustly across protocols and fails non-zero
on HTTP errors instead of saving error bodies.
Conveyor's -K flag accepts HOCON list syntax, not CSV. The CSV form
"-Kapp.machines=mac.amd64,mac.aarch64,..." was parsed as a single
machine spec and failed with "Unrecognized machine attribute
'amd64,mac'". Switch to "-Kapp.machines=[mac.amd64,...]" per the
Conveyor docs example "-Kapp.inputs=[a,b,c]".

Verified locally with `conveyor -Kapp.machines=[mac.amd64,
mac.aarch64,windows.amd64,windows.aarch64] make` — output drops all
linux invokables (linux-app, linux-tarball, debian-package,
base-configured-inputs/linux.amd64.glibc) and lists `site` as
unambiguously invokable, confirming the override replaces the
machines list as intended.
Conveyor stdlib preset /stdlib/jdk/21/openjdk.conf (Eclipse Temurin)
does not ship a windows.aarch64 build, so `make site` failed with
"JAR files were imported but no JVM inputs were supplied for
'windows.aarch64'" right after Mac archs + Windows x64 succeeded.

Surgical override: add Microsoft Build of OpenJDK 21 windows-aarch64
zip as an additional input for that one machine. Keep Temurin from
the stdlib include for the other 4 platforms — battle-tested with
Compose Multiplatform, minimal change surface.

Pin via aka.ms redirect so the URL stays stable across point
releases (currently 21.0.11).

Verified locally with `conveyor -Kapp.machines=[mac.amd64,
mac.aarch64,windows.amd64,windows.aarch64] make site` — all 6
package artifacts produced in 226s (mac-aarch64.zip 167M,
mac-amd64.zip 174M, windows-aarch64.zip 180M, windows-amd64.zip
191M, .arm64.msix 183M, .x64.msix 194M), plus download.html,
.appinstaller for both archs, and the .exe wrapper.
CI's `desktop-windows` artifact previously shipped the raw Conveyor
output (.msix + .appinstaller + .exe wrapper) which is unusable for
end users: the .exe wrapper and .appinstaller both fetch
${site.base-url}/simpmusic.crt and simpmusic-arm64.appinstaller
from GitHub Releases /latest/download/, which return 404 until we
publish a release with those files. simpmusic.crt was also missing
from the upload entirely.

Replace the upload step with a per-arch bundling step that produces
two self-contained zips end users can actually install:

  SimpMusic-Windows-x64-installer.zip
    ├── install.bat                       (UAC self-elevate, certutil
    │                                       add cert, Add-AppxPackage)
    ├── simpmusic.crt                     (Conveyor self-signed code
    │                                       signing cert, stable across
    │                                       builds via CONVEYOR_SIGNING_KEY)
    └── simpmusic-<ver>.x64.msix          (the actual app)

  SimpMusic-Windows-arm64-installer.zip
    ├── install.bat
    ├── simpmusic.crt
    └── simpmusic-<ver>.arm64.msix

The install.bat detects host arch via %PROCESSOR_ARCHITECTURE% and
picks the matching MSIX from the same folder — single bundle per
arch, double-click to install, no network round-trip.

Tested locally with `conveyor make site -Kapp.machines=windows.aarch64`
+ the bundle loop; install.bat verified on a real Windows ARM64 host
(cert imports to Cert:\LocalMachine\TrustedPeople, MSIX sideloads via
Add-AppxPackage, app launches native ARM64 — confirmed via Task
Manager Details tab Architecture column).
`wmic` was deprecated in Windows 10 21H1 and is no longer installed
on Windows 11 by default, so our previous VM detection
(`wmic computersystem get model`) silently returned an empty string
on every Win 11 host. That left isVM = false → undecorated +
transparent window → Parallels Win 11 ARM rendered nothing or
flipped into a fullscreen-with-invisible-overlay state where clicks
were eaten by the transparent surface.

Replace the probe chain with:
  1. PowerShell `Get-CimInstance Win32_ComputerSystem`
     (modern wmic replacement, ships with every Windows 10/11)
  2. Legacy `wmic computersystem get manufacturer,model`
     (fallback for older hosts where PowerShell is locked down)

Also widen the vendor token list (Parallels, VirtualBox, VMware,
QEMU, KVM, Xen, Hyper-V) and probe BOTH Manufacturer and Model,
since Parallels-on-ARM only puts the brand string in Manufacturer
("Parallels Software International Inc.") while Model reads as
"Parallels ARM Virtual Machine" — the old single-Model probe would
have missed it even if wmic still worked.

Verified on Parallels Desktop running Windows 11 ARM64: app window
now opens with a native title bar and renders correctly; previous
invisible-window + fullscreen-glitch + click-eating-overlay states
all gone.
Remove windows.aarch64 from the Conveyor machines list, the bundled
Microsoft JDK windows-aarch64 input, the workflow's -Kapp.machines
override, and the install.bat arch-detection loop. End users on
Windows 11 ARM64 (Surface Pro X, Snapdragon Copilot+ PC, Parallels
ARM, etc.) get the x64 msix running under Prism emulation, which
works correctly.

Reason: androidx.sqlite:sqlite-bundled-jvm 2.6.2 (and even
2.7.0-alpha05) does not ship a windows_arm64 sqliteJni.dll. The
bundled Room driver fails at first connection with "Cannot find a
suitable SQLite binary for windows 11 | aarch64", which we cannot
work around without compiling the native ourselves. The rest of the
ARM Windows toolchain (Skiko, VLC, Microsoft JDK) does have ARM64
builds, so we can re-enable windows.aarch64 once Google ships the
upstream sqlite native — the supporting plumbing is preserved in
git history (commit ebe1577 + 16872e1).

Side effect: CI artifact `desktop-windows` is now a single
SimpMusic-Windows-installer.zip (~190 MB) instead of separate
SimpMusic-Windows-{x64,arm64}-installer.zip. install.bat no longer
needs %PROCESSOR_ARCHITECTURE% logic; it just globs simpmusic-*.msix
and installs whatever it finds, which is simpler to maintain and
matches what end users actually need.

Verified locally with `conveyor -Kapp.machines=windows.amd64 make
site` → bundle loop → SimpMusic-Windows-installer.zip (193 MB,
3 files) → sideload + launch on Parallels Win 11 ARM (with the VM
detection fix from the previous commit, the window now renders
correctly).
Picks up core@eb836db which sets VLC_PLUGIN_PATH in
DefaultVlcDiscoverer.onSetPluginPath so libvlc_new() can locate
the bundled plugins subdirectory on the Conveyor-built Linux
AppImage. Without this, libvlc_new() returned NULL and Koin
failed to construct VlcPlayerAdapter, crashing the app at startup
with "Failed to get a new native library instance".
Signed-off-by: maxrave-dev <ndtminh2608@gmail.com>
@maxrave-dev maxrave-dev merged commit 0a794cd into dev May 22, 2026
1 check passed
@maxrave-dev maxrave-dev deleted the feat/conveyor-packaging branch May 22, 2026 12:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant