y feat(installer): version from APP_VERSION + Bambuddy icon

- 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.
This commit is contained in:
maziggy
2026-06-10 13:09:03 +02:00
parent 4b2babe752
commit 91686e22f1
3 changed files with 24 additions and 13 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

+12 -4
View File
@@ -49,8 +49,12 @@ ArchitecturesInstallIn64BitMode=x64compatible
; Admin required: we register a Windows service and write to ProgramData
PrivilegesRequired=admin
PrivilegesRequiredOverridesAllowed=
UninstallDisplayIcon={app}\bin\nssm.exe
SetupIconFile=
; Bambuddy branding — bambuddy.ico is a multi-resolution .ico (16/32/48/
; 64/128/256) generated from frontend/public/img/favicon.png; lives next
; to this .iss so the SourcePath-relative reference works during compile
; and the [Files] entry stages it into {app} for Add/Remove Programs.
SetupIconFile=bambuddy.ico
UninstallDisplayIcon={app}\bambuddy.ico
; Don't allow installing to a network drive — service won't start cleanly
DisableDirPage=no
DisableReadyPage=no
@@ -76,6 +80,10 @@ Source: "build\staging\bin\*"; DestDir: "{app}\bin"; Flags: recursesubdirs ignor
Source: "build\staging\service\*"; DestDir: "{app}\service"; Flags: recursesubdirs ignoreversion
; Version stamp
Source: "build\staging\VERSION"; DestDir: "{app}"; Flags: ignoreversion
; App icon — used by UninstallDisplayIcon (Add/Remove Programs) and the
; Start Menu / desktop shortcuts. Lives at the install root so the
; UninstallDisplayIcon path stays stable when the [Files] tree changes.
Source: "bambuddy.ico"; DestDir: "{app}"; Flags: ignoreversion
[Dirs]
; ProgramData layout — created with permissions LocalSystem can write to
@@ -84,10 +92,10 @@ Name: "{commonappdata}\Bambuddy\data"; Permissions: users-modify
Name: "{commonappdata}\Bambuddy\logs"; Permissions: users-modify
[Icons]
Name: "{group}\Open Bambuddy Dashboard"; Filename: "http://localhost:{#DefaultPort}"; IconFilename: "{app}\bin\nssm.exe"
Name: "{group}\Open Bambuddy Dashboard"; Filename: "http://localhost:{#DefaultPort}"; IconFilename: "{app}\bambuddy.ico"
Name: "{group}\Bambuddy Logs"; Filename: "{commonappdata}\Bambuddy\logs"
Name: "{group}\Uninstall Bambuddy"; Filename: "{uninstallexe}"
Name: "{commondesktop}\Bambuddy"; Filename: "http://localhost:{#DefaultPort}"; IconFilename: "{app}\bin\nssm.exe"; Tasks: desktopicon
Name: "{commondesktop}\Bambuddy"; Filename: "http://localhost:{#DefaultPort}"; IconFilename: "{app}\bambuddy.ico"; Tasks: desktopicon
[Run]
; Register and start the Windows service
+12 -9
View File
@@ -271,17 +271,20 @@ def write_version_file() -> None:
Inno Setup include file so the .iss script can pick it up at compile
time without a fragile file-read hack.
Reads from pyproject.toml's [project] version line for the source of
truth. Falls back to ``0.0.0+dev`` if not parseable.
Reads ``APP_VERSION`` from ``backend/app/core/config.py`` — that's the
canonical version used by every other surface in Bambuddy (the FastAPI
OpenAPI title, /system info, the support bundle, the spoolbuddy update
check). pyproject.toml has its own stale ``version = "0.1.5"`` that
isn't kept in sync; reading it would ship a wrong-versioned installer.
"""
version = "0.0.0+dev"
pyproject = REPO_ROOT / "pyproject.toml"
if pyproject.exists():
for line in pyproject.read_text().splitlines():
line = line.strip()
if line.startswith("version =") or line.startswith('version="'):
# version = "0.1.5" -> 0.1.5
version = line.split("=", 1)[1].strip().strip('"').strip("'")
config_py = REPO_ROOT / "backend" / "app" / "core" / "config.py"
if config_py.exists():
for raw in config_py.read_text().splitlines():
stripped = raw.strip()
if stripped.startswith("APP_VERSION"):
# APP_VERSION = "0.2.5b1" -> 0.2.5b1
version = stripped.split("=", 1)[1].strip().strip('"').strip("'")
break
(STAGING / "VERSION").write_text(version)