Skip to content

Add desktop distribution support#38

Draft
mikoding9 wants to merge 18 commits into
PyPSA:mainfrom
open-energy-transition:desktop-distribution
Draft

Add desktop distribution support#38
mikoding9 wants to merge 18 commits into
PyPSA:mainfrom
open-energy-transition:desktop-distribution

Conversation

@mikoding9
Copy link
Copy Markdown

Adds Wails desktop distribution work, bundled wheel setup, platform build docs, and macOS/Windows packaging notes.

mikoding9 added 17 commits May 24, 2026 23:32
…_ONLY env var

- add pg_advisory_lock around alembic upgrades to prevent race conditions
  when multiple containers start simultaneously
- pass connection via alembic config attributes so lock is held across migration
- rename SERVE_FRONTEND env var to BACKEND_ONLY for clarity
- add architecture diagram and compose config
- document Windows desktop distribution plan (Wails + uv sidecars)
- resolve open questions: wheel build, version pinning, auth, NSIS installer
Scaffolds the desktop/ directory with the Wails v2 control plane:
port conflict detection, startup sequence with status events, system
tray (Windows, energye/systray), and a dark splash screen that
navigates the WebView to localhost:8765 once services are ready.

Stubs for ProcessManager, Setup, and prereq checking are in place
for Phases 2-3. Builds clean on macOS and cross-compiles for Windows/amd64.
Full ProcessManager lifecycle: spawn snakedispatch then pypsa-app,
health-poll each with 60s timeout, crash-recovery up to 3 restarts
with linear back-off, and graceful shutdown (SIGTERM/CTRL_BREAK +
5s timeout + SIGKILL). Logs rotate via lumberjack (10 MB, 3 backups).

Adds paths.go for data-dir and venv-script resolution, and
build-tagged terminate_*.go for platform-correct shutdown signals.
setup.go: first-launch venv creation and package install via uv,
with progress range, sentinel file, bundled-wheels or PyPI fallback,
and output streamed to logs/setup.log. Auto-detects local source by
walking up from cwd and scanning sibling directories.

config.go: writes snakedispatch.yaml idempotently on every launch,
resolving pixi from PATH and scratch_dir from appDataDir.

paths.go: adds snakedispatch/ to ensureDirs.

app.go: wires setup + config into runStartupSequence. Replaces
domReady timer with a frontend:ready handshake to eliminate stuck
Initialising state. Adds build-tagged beforeClose for macOS.
- client.ts: toast.error on all non-401/non-cancelled HTTP errors; remove
  redundant per-page toast.error calls across runs, networks, and admin pages
- setup.go: skip venvReady check for local-dev packages so source changes
  are picked up on restart; use --reinstall-package to avoid full reinstalls
- desktop/proxy.go: HTTP reverse-proxy helper for Wails WebView
- replace native confirm() dialogs (blocked in WebView) with custom Dialog components
- fix dev source detection when running as macOS app bundle
- set Cache-Control: no-store on HTML responses to prevent WebView serving stale index.html
- fix infinite skeleton on run detail page when auth is disabled
- suppress spurious toast for /auth/me 400 (expected when auth is disabled)
- remove deprecated ENABLE_AUTH env var; auth state now derived from /auth/providers
- add default_snakemake_args (--cores 1) to snakedispatch config template
- pin @tanstack/svelte-table and run pre-commit
Adds desktop/build/windows/installer/project.nsi with: bundled uv.exe
and pre-built Python wheels, Git/Pixi prerequisite detection, and a
corrected uninstaller that removes only %PROGRAMFILES%\pypsa-desktop\
while preserving user data at %APPDATA%\pypsa-desktop\.

Also un-ignores desktop/build/ source assets in .gitignore, adds
wails.json info block, wheel staging dirs, and installer build instructions.
- about.go: embed versions.yaml at build time; detect Python version from
  venv; ShowAbout() shows native dialog with all three versions
- notify_windows.go / notify_other.go: Windows toast on fatal sidecar crash;
  no-op on other platforms
- systray_windows.go: add About menu item between Show Window and Quit
- app.go: watchCrashes() notifies before WindowShow so the user is alerted
  even when minimised to the tray
- bundledUVPath() and bundledWheelsDir() handle darwin via os.Executable()
  so the app bundle locates uv and wheels relative to Contents/MacOS/
- inferPythonVersion() scans wheel filenames for cpXYZ tags to select the
  correct interpreter at runtime (falls back to 3.13 in dev/online mode)
- fix desktop run logging and runtime path resolution
- add build/darwin/.gitignore to exclude binary uv and *.whl files
- desktop-build-and-distribute.md: step-by-step guide for Windows, Linux,
  and macOS; covers wheel collection, Wails binary, NSIS installer, DMG
  creation, Gatekeeper bypass, notarisation, and the offline bundle approach
- macos-intel-build-notes.md: documents 8 obstacles and solutions for
  building x86_64 bundles from an arm64 machine (Rosetta, Bottleneck wheel,
  create-dmg AppleScript, uv cross-download)
- add .gitignore for darwin-x86 build staging directory
- update settings docs
…tion

- Proven full Windows installer build works from macOS: mingw-w64, makensis,
  wails build -platform windows/amd64 -nsis
- Add desktop/build/windows/.gitignore (uv.exe, installer/tmp/)
- Replace uv pip download (doesn't exist) with uv export + python3 -m pip
  download --platform win_amd64 with environment marker filtering
- Fix --target flag to -platform in wails build command
- Collapse Step 6W into 5W: makensis runs automatically when in PATH
- Fix project structure paths in desktop-distribution.md
- Fix prerequisites table: offline install is Yes, no internet needed post-install
- Update Decision #1: no Windows machine required for distribution builds
@mikoding9 mikoding9 marked this pull request as draft May 25, 2026 09:32
@mikoding9
Copy link
Copy Markdown
Author

@lkstrp Feel free to give feedback

Reinstalling the app previously left the old snakedispatch venv intact
because the setup_complete sentinel was preserved across uninstall/reinstall.
The installer now deletes the sentinel so the first launch after an upgrade
always reinstalls both venvs from the freshly bundled wheels.
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