From 294c50a2eb8fc333aa08e9d3e97acb3bf022dbaa Mon Sep 17 00:00:00 2001 From: "dolgolyov.alexei" Date: Tue, 24 Mar 2026 12:46:38 +0300 Subject: [PATCH] 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 --- gitea-python-ci-cd.md | 111 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 101 insertions(+), 10 deletions(-) diff --git a/gitea-python-ci-cd.md b/gitea-python-ci-cd.md index 5539da9..b7863d5 100644 --- a/gitea-python-ci-cd.md +++ b/gitea-python-ci-cd.md @@ -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