docs: expand CI/CD guide with NSIS launch function, VBS fallback, and local build testing
- Replace MUI_FINISHPAGE_RUN_PARAMETERS with RUN_FUNCTION (fixes quoting) - Add embedded Python fallback to VBS hidden launcher - Add .onInit file-lock detection for running instances - Add section 11: local Windows build testing with NSIS - Expand troubleshooting table with common build/install issues
This commit is contained in:
@@ -342,12 +342,36 @@ InstallDir "$LOCALAPPDATA\${APPNAME}"
|
||||
RequestExecutionLevel user
|
||||
|
||||
; Optional: launch app after install (checkbox on finish page)
|
||||
; Direct bat approach (shows brief console flash):
|
||||
; !define MUI_FINISHPAGE_RUN "$INSTDIR\MyApp.bat"
|
||||
; Preferred: VBS hidden launcher (no console window at all):
|
||||
!define MUI_FINISHPAGE_RUN "wscript.exe"
|
||||
!define MUI_FINISHPAGE_RUN_PARAMETERS '"$INSTDIR\scripts\start-hidden.vbs"'
|
||||
; IMPORTANT: Do NOT use MUI_FINISHPAGE_RUN with MUI_FINISHPAGE_RUN_PARAMETERS —
|
||||
; NSIS Exec command chokes on the quoting. Use MUI_FINISHPAGE_RUN_FUNCTION instead:
|
||||
!define MUI_FINISHPAGE_RUN ""
|
||||
!define MUI_FINISHPAGE_RUN_TEXT "Launch ${APPNAME}"
|
||||
!define MUI_FINISHPAGE_RUN_FUNCTION LaunchApp
|
||||
|
||||
Function LaunchApp
|
||||
ExecShell "open" "wscript.exe" '"$INSTDIR\scripts\start-hidden.vbs"'
|
||||
Sleep 2000
|
||||
ExecShell "open" "http://localhost:8765/" ; Open Web UI after server starts
|
||||
FunctionEnd
|
||||
|
||||
; Detect running instance before install (file lock check)
|
||||
Function .onInit
|
||||
IfFileExists "$INSTDIR\python\python.exe" 0 done
|
||||
ClearErrors
|
||||
FileOpen $0 "$INSTDIR\python\python.exe" a
|
||||
IfErrors locked
|
||||
FileClose $0
|
||||
Goto done
|
||||
locked:
|
||||
MessageBox MB_YESNOCANCEL|MB_ICONEXCLAMATION \
|
||||
"${APPNAME} is currently running.$\n$\nYes = Stop and continue$\nNo = Continue anyway (may cause errors)$\nCancel = Abort" \
|
||||
IDYES kill IDNO done
|
||||
Abort
|
||||
kill:
|
||||
nsExec::ExecToLog 'wmic process where "ExecutablePath like $\'%AppName%python%$\'" call terminate'
|
||||
Sleep 2000
|
||||
done:
|
||||
FunctionEnd
|
||||
|
||||
; Sections
|
||||
Section "!Core (required)" SecCore ; App files + uninstaller
|
||||
@@ -365,17 +389,27 @@ Bat files briefly flash a console window even with `@echo off`. To avoid this,
|
||||
use a VBS wrapper that all shortcuts and the finish page point to:
|
||||
|
||||
```vbs
|
||||
Set fso = CreateObject("Scripting.FileSystemObject")
|
||||
Set WshShell = CreateObject("WScript.Shell")
|
||||
scriptDir = CreateObject("Scripting.FileSystemObject").GetParentFolderName(WScript.ScriptFullName)
|
||||
appRoot = CreateObject("Scripting.FileSystemObject").GetParentFolderName(scriptDir)
|
||||
scriptDir = fso.GetParentFolderName(WScript.ScriptFullName)
|
||||
appRoot = fso.GetParentFolderName(scriptDir)
|
||||
WshShell.CurrentDirectory = appRoot
|
||||
' Run bat completely hidden (0 = hidden, False = don't wait)
|
||||
WshShell.Run """" & appRoot & "\MyApp.bat""", 0, False
|
||||
' Use embedded Python if present (installed dist), otherwise system Python
|
||||
embeddedPython = appRoot & "\python\python.exe"
|
||||
If fso.FileExists(embeddedPython) Then
|
||||
WshShell.Run """" & embeddedPython & """ -m your_package.main", 0, False
|
||||
Else
|
||||
WshShell.Run "python -m your_package.main", 0, False
|
||||
End If
|
||||
```
|
||||
|
||||
Place in `scripts/start-hidden.vbs` and bundle it in the build script.
|
||||
All NSIS shortcuts use: `"wscript.exe" '"$INSTDIR\scripts\start-hidden.vbs"'`
|
||||
|
||||
**Important:** The embedded Python fallback is critical — the installed distribution
|
||||
doesn't have Python on PATH, so `python` alone won't work. The dev environment uses
|
||||
system Python, so the fallback handles both cases.
|
||||
|
||||
**CI dependencies:** `sudo apt-get install -y nsis msitools zip`
|
||||
|
||||
Build: `makensis -DVERSION="${VERSION}" installer.nsi`
|
||||
@@ -486,7 +520,64 @@ git push origin v0.2.0-alpha.1
|
||||
- [ ] Configure `pyproject.toml` with `[tool.ruff]` and `[tool.pytest]`
|
||||
- [ ] Set up `.pre-commit-config.yaml` with ruff + black
|
||||
|
||||
## 11. Troubleshooting
|
||||
## 11. Local Build Testing (Windows)
|
||||
|
||||
The CI builds on Linux, but you can build locally on Windows for faster iteration.
|
||||
|
||||
### 11.1. Prerequisites
|
||||
|
||||
Install NSIS (for installer builds):
|
||||
|
||||
```powershell
|
||||
# If winget is not on PATH, use the full path:
|
||||
& "$env:LOCALAPPDATA\Microsoft\WindowsApps\winget.exe" install NSIS.NSIS
|
||||
# Installs to: C:\Program Files (x86)\NSIS\makensis.exe
|
||||
```
|
||||
|
||||
### 11.2. Build Steps
|
||||
|
||||
```bash
|
||||
# 1. Build frontend
|
||||
npm ci && npm run build
|
||||
|
||||
# 2. Build Windows distribution (from Git Bash)
|
||||
bash build-dist-windows.sh v1.0.0
|
||||
|
||||
# 3. Build NSIS installer
|
||||
"/c/Program Files (x86)/NSIS/makensis.exe" -DVERSION="1.0.0" installer.nsi
|
||||
# Output: build/MediaServer-v1.0.0-setup.exe
|
||||
```
|
||||
|
||||
### 11.3. Common Issues
|
||||
|
||||
| Issue | Cause | Fix |
|
||||
|-------|-------|-----|
|
||||
| `zip: command not found` | Git Bash doesn't include `zip` | Harmless — only affects the portable ZIP, not the installer. Install `zip` via MSYS2 if needed |
|
||||
| `Exec expects 1 parameters, got 2` | `MUI_FINISHPAGE_RUN_PARAMETERS` quoting breaks NSIS `Exec` | Use `MUI_FINISHPAGE_RUN_FUNCTION` instead (see section 6) |
|
||||
| `Error opening file for writing: ...python\\_asyncio.pyd` | Server is running and has DLLs locked | Stop the server before installing. Add `.onInit` file-lock check (see section 6) |
|
||||
| App doesn't start after install (Launch checkbox) | VBS uses `python` but embedded Python isn't on PATH | Use embedded Python fallback in VBS (see Hidden Launcher section) |
|
||||
| `winget` not recognized | `winget.exe` exists but isn't on shell PATH | Use full path: `$env:LOCALAPPDATA\Microsoft\WindowsApps\winget.exe` |
|
||||
| NSIS warning: `install function not referenced` | `MUI_FINISHPAGE_RUN` define is missing | `MUI_FINISHPAGE_RUN_FUNCTION` still requires `MUI_FINISHPAGE_RUN` to be defined (controls checkbox visibility). Set it to `""` |
|
||||
| `dist/` has stale files after code changes | `build-dist-windows.sh` copies from source at build time | Re-run the full build script, or manually copy changed files into `dist/` |
|
||||
|
||||
### 11.4. Iterating on Installer Only
|
||||
|
||||
If you only changed `installer.nsi` (not app code), skip the full rebuild:
|
||||
|
||||
```bash
|
||||
# Just rebuild the installer using existing dist/
|
||||
"/c/Program Files (x86)/NSIS/makensis.exe" -DVERSION="1.0.0" installer.nsi
|
||||
```
|
||||
|
||||
If you changed app code or dependencies, you must re-run `build-dist-windows.sh` first —
|
||||
the `dist/` directory is a snapshot and won't pick up source changes automatically.
|
||||
|
||||
## 12. Troubleshooting
|
||||
|
||||
### Running server blocks installation
|
||||
|
||||
See section 11.3. The `.onInit` function in section 6 shows how to detect a locked
|
||||
`python.exe` and prompt the user before proceeding.
|
||||
|
||||
### Release already exists for tag
|
||||
|
||||
|
||||
Reference in New Issue
Block a user