param( [switch]$NoOpen ) $ErrorActionPreference = 'Stop' $workspaceRoot = Split-Path -Parent $PSScriptRoot $releaseDirectory = Join-Path $workspaceRoot 'release' $electronBuilderCommand = Join-Path $workspaceRoot 'node_modules\.bin\electron-builder.CMD' Set-Location -LiteralPath $workspaceRoot function Invoke-CheckedCommand { param( [Parameter(Mandatory = $true)] [string]$Command, [string[]]$Arguments = @() ) & $Command @Arguments if ($LASTEXITCODE -ne 0) { throw "Command failed with exit code ${LASTEXITCODE}: $Command $($Arguments -join ' ')" } } try { Write-Host '[1/4] Checking Node.js and pnpm...' -ForegroundColor Cyan if (-not (Get-Command node -ErrorAction SilentlyContinue)) { throw 'Node.js was not found. Install Node.js 20 first.' } if (-not (Get-Command pnpm -ErrorAction SilentlyContinue)) { throw 'pnpm was not found. Run: corepack enable' } $nodeVersion = (& node --version).Trim() $pnpmVersion = (& pnpm --version).Trim() Write-Host "Node.js $nodeVersion, pnpm $pnpmVersion" -ForegroundColor DarkGray Write-Host '[2/4] Checking project dependencies...' -ForegroundColor Cyan if (-not (Test-Path -LiteralPath $electronBuilderCommand)) { Write-Host 'Dependencies are missing. Running pnpm install...' Invoke-CheckedCommand -Command 'pnpm' -Arguments @('install') } else { Write-Host 'Dependencies found. Skipping installation.' -ForegroundColor DarkGray } Write-Host '[3/4] Building the Electron installer...' -ForegroundColor Cyan $env:ELECTRON_MIRROR = 'https://npmmirror.com/mirrors/electron/' Invoke-CheckedCommand -Command 'pnpm' -Arguments @('electron:build') Write-Host '[4/4] Checking build output...' -ForegroundColor Cyan $installer = Get-ChildItem -LiteralPath $releaseDirectory -Filter '*.exe' -File | Sort-Object LastWriteTime -Descending | Select-Object -First 1 if (-not $installer) { throw "The build completed, but no installer was found in $releaseDirectory." } $sizeMb = [Math]::Round($installer.Length / 1MB, 2) Write-Host '' Write-Host 'Build completed successfully.' -ForegroundColor Green Write-Host "Installer: $($installer.FullName)" Write-Host "Size: $sizeMb MB" if (-not $NoOpen) { Start-Process -FilePath 'explorer.exe' -ArgumentList "/select,`"$($installer.FullName)`"" } } catch { Write-Host '' Write-Host "Automatic packaging failed: $($_.Exception.Message)" -ForegroundColor Red exit 1 }