From 209f0a1dcf38401a2f7f7371c90729e5fdc54a41 Mon Sep 17 00:00:00 2001 From: Boof2015 <75185879+Boof2015@users.noreply.github.com> Date: Mon, 17 Aug 2026 21:13:28 -0400 Subject: [PATCH] fix ci fail + clearer windows installer steps --- resources/installer/windows-vst3.nsh | 28 ++++++++++++++++++++-- scripts/test-windows-installer.ps1 | 35 ++++++++++++++++++++++++---- 2 files changed, 57 insertions(+), 6 deletions(-) diff --git a/resources/installer/windows-vst3.nsh b/resources/installer/windows-vst3.nsh index fee59d8..fb5b587 100644 --- a/resources/installer/windows-vst3.nsh +++ b/resources/installer/windows-vst3.nsh @@ -20,6 +20,23 @@ Var PRISM_VST_CHECKBOX Var PRISM_VST_STATE + !macro customHeader + ; electron-builder disables the standard NSIS details view in common.nsh. + ; customHeader is inserted after common.nsh, so this supported hook can + ; override that default without modifying electron-builder's templates. + ShowInstDetails show + + ; This hidden section runs before electron-builder's main install section. + ; Its message therefore remains visible while the bundled application is + ; extracted and atomically copied into the selected installation folder. + Section "-Prism install status" + ${IfNot} ${Silent} + SetDetailsPrint both + DetailPrint "Step 1 of 4: Unpacking Prism application files. This may take a minute..." + ${EndIf} + SectionEnd + !macroend + !macro customInit ; Silent installs skip the options page, so default to installing plugins. StrCpy $PRISM_VST_STATE ${BST_CHECKED} @@ -55,12 +72,16 @@ !macroend !macro customInstall + SetDetailsPrint both + ${IfNot} ${FileExists} "$INSTDIR\resources\tui\prism-tui.exe" DetailPrint "ERROR: bundled prism-tui.exe was not found" MessageBox MB_OK|MB_ICONSTOP "The bundled prism-tui executable was not found.$\r$\n$\r$\nMissing path:$\r$\n$INSTDIR\resources\tui\prism-tui.exe" /SD IDOK Abort ${EndIf} + DetailPrint "Step 2 of 4: Adding prism-tui to the machine PATH..." + ; Pass the path through the installer's process environment. Supplying it ; after PowerShell's -Command argument loses quotes at the native command ; line boundary and truncates the default path to "C:\Program". @@ -85,7 +106,7 @@ DetailPrint "Added $INSTDIR\resources\tui to the machine PATH" ${If} $PRISM_VST_STATE == ${BST_CHECKED} - DetailPrint "Installing Prism VST3 plugins to $COMMONFILES64\VST3" + DetailPrint "Step 3 of 4: Installing Prism VST3 plugins to $COMMONFILES64\VST3..." ${IfNot} ${FileExists} "$INSTDIR\resources\plugins\VST3\*.vst3" ; Plugins are optional. Local app/TUI builds may intentionally omit the @@ -103,10 +124,13 @@ MessageBox MB_OK|MB_ICONSTOP "Prism VST3 plugin installation failed while copying files to:$\r$\n$COMMONFILES64\VST3$\r$\n$\r$\nxcopy exit code: $0" /SD IDOK Abort ${EndIf} + DetailPrint "Installed Prism VST3 plugins." ${EndIf} ${Else} - DetailPrint "Prism VST3 plugins: skipped (opted out)." + DetailPrint "Step 3 of 4: Prism VST3 plugins skipped (opted out)." ${EndIf} + + DetailPrint "Step 4 of 4: Finishing Prism installation..." !macroend !endif diff --git a/scripts/test-windows-installer.ps1 b/scripts/test-windows-installer.ps1 index 49596e6..d099278 100644 --- a/scripts/test-windows-installer.ps1 +++ b/scripts/test-windows-installer.ps1 @@ -116,6 +116,30 @@ function Invoke-CheckedProcess { } } +function Remove-DirectoryWithRetry { + param( + [Parameter(Mandatory)][string]$LiteralPath, + [int]$MaximumAttempts = 10, + [int]$DelayMilliseconds = 500 + ) + + for ($attempt = 1; $attempt -le $MaximumAttempts; $attempt += 1) { + if (-not (Test-Path -LiteralPath $LiteralPath)) { + return + } + + try { + Remove-Item -LiteralPath $LiteralPath -Recurse -Force -ErrorAction Stop + return + } catch { + if ($attempt -eq $MaximumAttempts) { + throw + } + Start-Sleep -Milliseconds $DelayMilliseconds + } + } +} + try { if ([string]::Equals($legacyEntry, $tuiDirectory, [StringComparison]::OrdinalIgnoreCase)) { throw "The smoke-test installation path must contain whitespace: $installRoot" @@ -184,7 +208,10 @@ try { $expectedReinstalledEntries = @($originalEntries) + $legacyEntry + $tuiDirectory Assert-PathEntriesEqual -Expected $expectedReinstalledEntries -Actual $reinstalledEntries -Context 'Reinstalled machine PATH' - Invoke-CheckedProcess -FilePath $uninstallerPath -Arguments '/S' | Out-Null + # _?= prevents NSIS from spawning a temporary uninstaller and exiting early, + # so WaitForExit observes the process that is actually removing the files. + # NSIS requires this to be the final argument and forbids quoting its value. + Invoke-CheckedProcess -FilePath $uninstallerPath -Arguments "/S _?=$installRoot" | Out-Null $uninstalled = $true $uninstalledEntries = @(Get-PathEntries ([Environment]::GetEnvironmentVariable('Path', 'Machine'))) @@ -198,7 +225,7 @@ try { } finally { if (-not $uninstalled -and (Test-Path -LiteralPath $uninstallerPath -PathType Leaf)) { try { - Invoke-CheckedProcess -FilePath $uninstallerPath -Arguments '/S' | Out-Null + Invoke-CheckedProcess -FilePath $uninstallerPath -Arguments "/S _?=$installRoot" | Out-Null } catch { Write-Warning "Smoke-test uninstall cleanup failed: $($_.Exception.Message)" } @@ -210,7 +237,7 @@ try { $fullTempRoot = [IO.Path]::GetFullPath($tempRoot).TrimEnd('\') + '\' $fullInstallRoot = [IO.Path]::GetFullPath($installRoot) if ($fullInstallRoot.StartsWith($fullTempRoot, [StringComparison]::OrdinalIgnoreCase)) { - Remove-Item -LiteralPath $fullInstallRoot -Recurse -Force + Remove-DirectoryWithRetry -LiteralPath $fullInstallRoot } else { Write-Warning "Refusing to remove unexpected smoke-test directory: $fullInstallRoot" } @@ -220,7 +247,7 @@ try { $fullTempRoot = [IO.Path]::GetFullPath($tempRoot).TrimEnd('\') + '\' $fullLegacyEntry = [IO.Path]::GetFullPath($legacyEntry) if ($fullLegacyEntry.StartsWith($fullTempRoot, [StringComparison]::OrdinalIgnoreCase)) { - Remove-Item -LiteralPath $fullLegacyEntry -Recurse -Force + Remove-DirectoryWithRetry -LiteralPath $fullLegacyEntry } else { Write-Warning "Refusing to remove unexpected legacy fixture directory: $fullLegacyEntry" }