spike(LC-131): Windows installer from Linux via NSIS #225

Merged
nrupard merged 2 commits from spike/lc-131-nsis-from-linux into main 2026-05-26 21:09:04 +02:00
Owner

Spike for LC-131: prove the Windows installer can be built from Linux with NSIS, replacing the parked native-Windows-runner plan (LC-138, now closed won't-fix).

Why

The raw lets-chat-desktop.exe already cross-builds from Linux (mingw x86_64-pc-windows-gnu, Dockerfile.desktop-windows) and ships via the auto-updater. Only the first-install installer was missing, and cargo tauri build --bundles msi|nsis is hard-gated to a Windows host - the sole reason LC-138 existed. makensis (the NSIS compiler) has a native Linux build, so a Linux container can compile a Windows installer with no Windows host and no wine.

What's here

  • desktop/installer/lets-chat.nsi - Program Files install, Start-Menu shortcut, uninstaller + Add/Remove Programs entry, WebView2-runtime check (warns if absent), optional autostart. Parameterized.
  • ci-build/Dockerfile.desktop-windows-installer - standalone debian:trixie-slim + nsis stage that wraps the cross-built exe (staged in the build context) into lets-chat-desktop-setup-x86_64.exe. Kept separate from the existing windows Dockerfile/workflow so nothing currently shipping is disturbed.
  • desktop/installer/README.md - build flow + remaining work.

Proof (this branch, on Linux)

makensis v3.11 (Debian trixie) compiled the script and the Dockerfile produced a valid ~160 KB PE32 ... Nullsoft Installer self-extracting archive, extractable via docker create + docker cp exactly as the release workflow extracts the raw .exe. Linux-only toolchain confirmed viable.

Not in this spike (tracked in LC-131 for full implementation)

  • Wire the packaging step into build-desktop-windows.yml (extract raw exe -> build installer image -> publish the setup .exe to Generic Packages).
  • WebView2 bootstrap (currently warn-only).
  • Code signing from Linux via osslsigncode.
  • A real Windows 10+ install / uninstall test (the Linux build only proves the installer compiles + is a valid PE).

Spike branch - merge optional; the artifacts are the foundation for the LC-131 implementation.

Spike for LC-131: prove the Windows installer can be built **from Linux** with NSIS, replacing the parked native-Windows-runner plan (LC-138, now closed won't-fix). ## Why The raw `lets-chat-desktop.exe` already cross-builds from Linux (mingw `x86_64-pc-windows-gnu`, `Dockerfile.desktop-windows`) and ships via the auto-updater. Only the first-install **installer** was missing, and `cargo tauri build --bundles msi|nsis` is hard-gated to a Windows host - the sole reason LC-138 existed. `makensis` (the NSIS compiler) has a native Linux build, so a Linux container can compile a Windows installer with no Windows host and no wine. ## What's here - `desktop/installer/lets-chat.nsi` - Program Files install, Start-Menu shortcut, uninstaller + Add/Remove Programs entry, WebView2-runtime check (warns if absent), optional autostart. Parameterized. - `ci-build/Dockerfile.desktop-windows-installer` - standalone `debian:trixie-slim` + `nsis` stage that wraps the cross-built exe (staged in the build context) into `lets-chat-desktop-setup-x86_64.exe`. Kept separate from the existing windows Dockerfile/workflow so nothing currently shipping is disturbed. - `desktop/installer/README.md` - build flow + remaining work. ## Proof (this branch, on Linux) `makensis v3.11` (Debian trixie) compiled the script and the Dockerfile produced a valid **~160 KB `PE32 ... Nullsoft Installer self-extracting archive`**, extractable via `docker create` + `docker cp` exactly as the release workflow extracts the raw `.exe`. Linux-only toolchain confirmed viable. ## Not in this spike (tracked in LC-131 for full implementation) - Wire the packaging step into `build-desktop-windows.yml` (extract raw exe -> build installer image -> publish the setup `.exe` to Generic Packages). - WebView2 bootstrap (currently warn-only). - Code signing from Linux via `osslsigncode`. - A real Windows 10+ install / uninstall test (the Linux build only proves the installer compiles + is a valid PE). Spike branch - merge optional; the artifacts are the foundation for the LC-131 implementation.
spike(LC-131): build the Windows installer from Linux with NSIS
All checks were successful
check-secrets / Kingfisher (push) Successful in 4s
check-secrets / Nosey parker (push) Successful in 4s
check-secrets / TruffleHog (push) Successful in 4s
check-secrets / Kingfisher (pull_request) Successful in 4s
check-secrets / TruffleHog (pull_request) Successful in 4s
check-secrets / Nosey parker (pull_request) Successful in 5s
Check / clippy + fmt + tests (pull_request) Successful in 1m33s
05bf94b569
Proves the Linux-only installer path that replaces the parked native-Windows-runner plan (LC-138, closed won't-fix). The raw .exe already cross-builds from Linux via mingw; this wraps it in an installer without a Windows host, wine, or tauri-cli (whose --bundles msi|nsis is hard-gated to a Windows host).

- desktop/installer/lets-chat.nsi: NSIS script - Program Files install, Start-Menu shortcut, uninstaller + Add/Remove Programs registry, WebView2-runtime check (warn), optional autostart Run key. Parameterized by -DAPP_EXE / -DAPP_VERSION / -DOUT_FILE.
- ci-build/Dockerfile.desktop-windows-installer: standalone packaging stage (debian:trixie-slim + the nsis package) that runs makensis over the cross-built lets-chat-desktop.exe staged in the build context. Deliberately separate from Dockerfile.desktop-windows so the existing raw-exe build + its workflow extraction are untouched.
- desktop/installer/README.md: build flow, the spike result, and the remaining work for the full LC-131 (workflow wiring, WebView2 bootstrap, osslsigncode signing, a real Windows install test).

Spike result: makensis v3.11 on Debian trixie compiled the script and the Dockerfile produced a valid ~160 KB PE32 "Nullsoft Installer self-extracting archive", extractable via docker create + docker cp exactly as the release workflow does for the raw .exe. Linux-only toolchain confirmed viable.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
feat(desktop): build + publish the Windows installer from Linux (LC-131)
All checks were successful
check-secrets / Nosey parker (pull_request) Successful in 4s
check-secrets / TruffleHog (push) Successful in 7s
check-secrets / TruffleHog (pull_request) Successful in 7s
check-secrets / Kingfisher (push) Successful in 9s
check-secrets / Kingfisher (pull_request) Successful in 10s
Create release / Create release from merged PR (pull_request) Has been skipped
check-secrets / Nosey parker (push) Successful in 8s
Check / clippy + fmt + tests (pull_request) Successful in 1m43s
1732bff4b1
Completes LC-131 on the Linux-only NSIS path (the native-runner plan LC-138 is closed won't-fix). Everything verifiable on Linux is wired and proven; signing + a real Windows install test remain ops/manual steps (documented).

- WebView2 bootstrap: ci-build/Dockerfile.desktop-windows-installer downloads Microsoft's Evergreen bootstrapper and bundles it via -DWEBVIEW2_BOOTSTRAPPER; lets-chat.nsi runs it /silent /install when the runtime is absent at install time (falls back to a warning when the define is absent, i.e. the standalone spike build). Installer is ~1.75 MB with it bundled.
- CI: build-desktop-windows.yml now keeps the plain lets-chat-desktop.exe staged, builds the installer Dockerfile after the raw exe, and publishes lets-chat-desktop-setup-windows-x86_64.exe to the Generic Packages registry alongside the binary. Trigger paths include the new Dockerfile + desktop/installer/**.
- README documents the build flow, what's done, and the ops-gated remainder (osslsigncode signing once a cert is provisioned; a real Windows 10+ install/uninstall + WebView2-on-clean-VM test, which the Linux build cannot cover).

Verified on Linux: makensis compiles the script with and without the WebView2 define; the installer Dockerfile builds end-to-end to a valid PE32 Nullsoft installer (extractable via docker create+cp as the workflow does); the workflow YAML parses.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
nrupard deleted branch spike/lc-131-nsis-from-linux 2026-05-26 21:09:04 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/lets-chat!225
No description provided.