When the Windows build is triggered by a tag push (the path
docker-publish.sh and docker-publish-daily-beta.sh both take), use
the tag as the installer version instead of APP_VERSION. So a daily
tag v0.2.5b1-daily.20260610 produces
bambuddy-0.2.5b1-daily.20260610-windows-x64-setup.exe
matching the docker `daily` image and the GitHub prerelease. The
stable docker-publish.sh path is unchanged (tag v0.2.5b1 →
bambuddy-0.2.5b1-windows-x64-setup.exe). Manual workflow_dispatch
and local builds fall back to APP_VERSION as before.
nssm.cc returned 503 mid-CI-run, breaking the staging step. NSSM 2.24
hasn't shipped a new release since 2014, so the binary is effectively
static — vendoring under installers/windows/vendor/nssm.exe makes
builds reproducible and removes the only single-source download in
the pipeline. SHA-256 pinned in the comment in build.py for audit.
ffmpeg stays fetched from BtbN's GitHub mirror — it's actively
maintained and large (~80MB) so vendoring it would be unreasonable;
GitHub Releases are also far more reliable than nssm.cc.
- build.py now reads APP_VERSION from backend/app/core/config.py
(the canonical source used everywhere else — /system, support
bundles, FastAPI title) instead of pyproject.toml's stale 0.1.5.
Next installer is bambuddy-0.2.5b1-windows-x64-setup.exe.
- installers/windows/bambuddy.ico is a multi-resolution .ico
(16/32/48/64/128/256) generated from frontend/public/img/
favicon.png. Wired into SetupIconFile (installer .exe icon),
UninstallDisplayIcon (Add/Remove Programs), and the Start Menu /
desktop shortcuts — replaces the NSSM placeholder everywhere a
user sees Bambuddy on Windows.
vite.config.ts sets outDir to '../static' so the bundle lands at
<repo>/static/ — not frontend/dist/. Matches the runtime expectation
in config.py where static_dir = _app_dir / "static".
Also stage gcode_viewer/ next to static/ so the 3D preview iframe
routes in main.py (resolved via static_dir.parent / "gcode_viewer")
find their assets.
Strip macOS metadata files (.DS_Store, ._.*) from both copies — they
leak in from dev boxes and would only bloat the installer.
get-pip.py installs only pip itself; the embedded Python distribution
ships without setuptools or wheel. pip needs setuptools.build_meta as
the PEP 517 build backend for any sdist-only package — Bambuddy's
requirements.txt hits this on pyftpdlib 2.2.0 (sdist-only on PyPI).
Install both right after the pip bootstrap so requirements.txt installs
cleanly.
Lays down the Inno Setup + embedded Python pipeline for producing a
self-contained Bambuddy Windows installer .exe. The installer ships
an embedded Python 3.13, the pre-built React bundle, NSSM (service
supervisor) and ffmpeg — no host Python or Node required on the
target machine.
Architecture:
- Install: C:\Program Files\Bambuddy (admin install, one-time UAC)
- Data: C:\ProgramData\Bambuddy\data (preserved on uninstall)
- Service: registered via NSSM, runs as LocalSystem, autostart on boot
- UI: browser at http://localhost:8000 (Start Menu shortcut)
Files:
- installers/windows/build.py stages embedded Python + deps,
frontend bundle, NSSM, ffmpeg
- installers/windows/bambuddy.iss Inno Setup compiler script
- installers/windows/service/*.bat NSSM register/deregister
- .github/workflows/windows-installer.yml CI build on tag push + manual
dispatch, uploads .exe artifact
build.py hard-fails on non-Windows hosts; Wine cross-build is an
unsupported escape hatch behind --allow-non-windows. v1 ships unsigned
(SmartScreen warns on first run) — production signing will be wired up
via SignPath OSS once the application is approved.
See installers/windows/README.md for build prerequisites and the
embedded-Python ._pth gotchas.