<# .SYNOPSIS Build script for DashCaddy Windows Desktop App .DESCRIPTION This script: 1. Builds the WinUI 3 desktop app (Release) 2. Packages as MSIX 3. Creates NSIS installer 4. Outputs: DashCaddy-Setup-1.15.0.exe .REQUIREMENTS - Visual Studio 2022 with Windows App SDK workload - NSIS 3.08+ - .NET 8 SDK #> param( [string]$Version = "1.15.0", [string]$Configuration = "Release", [string]$Platform = "x64" ) $ErrorActionPreference = 'Stop' $RootDir = Split-Path $PSScriptRoot -Parent $DesktopDir = Join-Path $RootDir 'desktop' $InstallerDir = Join-Path $RootDir 'installer\windows' $OutputDir = Join-Path $RootDir 'artifacts' $BuildDir = Join-Path $OutputDir 'build' Write-Host "=== DashCaddy Windows Build v$Version ===" -ForegroundColor Cyan Write-Host "Configuration: $Configuration" Write-Host "Platform: $Platform" # ─── Clean ─── if (Test-Path $OutputDir) { Write-Host "Cleaning previous build..." Remove-Item -Recurse -Force $OutputDir } New-Item -ItemType Directory -Path $BuildDir -Force | Out-Null # ─── Build .NET App ─── Write-Host "`n[1/5] Building WinUI 3 Desktop App..." -ForegroundColor Green $csproj = Join-Path $DesktopDir 'DashCaddy.Desktop.csproj' $publishDir = Join-Path $BuildDir 'app' dotnet publish $csproj ` -c $Configuration ` -r win10-$Platform ` --self-contained true ` -p:PublishSingleFile=true ` -p:PublishTrimmed=true ` -p:TrimMode=partial ` -p:EnableMsixTooling=true ` -p:AppxPackageDir=$OutputDir ` -o $publishDir if (-not (Test-Path (Join-Path $publishDir 'DashCaddy.exe'))) { throw "Build failed - DashCaddy.exe not found" } Write-Host "App built to: $publishDir" # ─── Copy Assets ─── Write-Host "`n[2/5] Copying assets..." -ForegroundColor Green $assetsSrc = Join-Path $InstallerDir 'assets' $assetsDst = Join-Path $BuildDir 'assets' if (Test-Path $assetsSrc) { Copy-Item -Recurse $assetsSrc $assetsDst } else { # Create minimal assets New-Item -ItemType Directory -Path $assetsDst -Force | Out-Null # Create a simple icon placeholder Write-Host "Warning: No assets found, creating placeholders" } # ─── Copy Bootstrap ─── Write-Host "`n[3/5] Copying bootstrap script..." -ForegroundColor Green Copy-Item (Join-Path $InstallerDir 'bootstrap.ps1') (Join-Path $BuildDir 'bootstrap.ps1') # ─── Create docker-compose.yml for installer ─── Write-Host "`n[4/5] Creating installer docker-compose.yml..." -ForegroundColor Green $composeContent = @" version: '3.8' services: dashcaddy-api: image: dashcaddy/dashcaddy-api:latest container_name: dashcaddy-api restart: unless-stopped ports: - "127.0.0.1:3001:3001" volumes: - \${DATA_DIR}:/opt/dashcaddy/data - \${APPDATA_DIR}/config.yaml:/opt/dashcaddy/config.yaml:ro - //./pipe/docker_engine:/var/run/docker.sock:ro environment: - NODE_ENV=production - DATA_DIR=/opt/dashcaddy/data - CONFIG_FILE=/opt/dashcaddy/config.yaml healthcheck: test: ["CMD", "node", "-e", "require('http').get('http://localhost:3001/health', (r) => { process.exit(r.statusCode === 200 ? 0 : 1); }).on('error', () => process.exit(1))"] interval: 30s timeout: 10s retries: 3 start_period: 15s networks: - dashcaddy-net caddy: image: caddy:2.10-alpine container_name: dashcaddy-caddy restart: unless-stopped ports: - "80:80" - "443:443" volumes: - \${DATA_DIR}/caddy/Caddyfile:/etc/caddy/Caddyfile:ro - \${DATA_DIR}/caddy/data:/data - \${DATA_DIR}/caddy/config:/config networks: - dashcaddy-net depends_on: - dashcaddy-api coredns: image: coredns/coredns:latest container_name: dashcaddy-coredns restart: unless-stopped ports: - "53:53/udp" - "53:53/tcp" volumes: - \${DATA_DIR}/coredns/Corefile:/etc/coredns/Corefile:ro networks: - dashcaddy-net networks: dashcaddy-net: driver: bridge "@ $composeContent | Set-Content -Path (Join-Path $BuildDir 'docker-compose.yml') -Encoding UTF8 # ─── Build NSIS Installer ─── Write-Host "`n[5/5] Building NSIS Installer..." -ForegroundColor Green $nsisPath = "C:\Program Files (x86)\NSIS\makensis.exe" if (-not (Test-Path $nsisPath)) { $nsisPath = "C:\Program Files\NSIS\makensis.exe" } if (-not (Test-Path $nsisPath)) { throw "NSIS not found. Install NSIS 3.08+ from https://nsis.sourceforge.io/" } $nsiFile = Join-Path $InstallerDir 'dashcaddy.nsi' $installerOutput = Join-Path $OutputDir "DashCaddy-Setup-$Version.exe" & $nsisPath ` "/DVERSION=$Version" ` "/DOUTPUT=$installerOutput" ` "/DINSTALLER_DIR=$BuildDir" ` $nsiFile if (Test-Path $installerOutput) { $size = [math]::Round((Get-Item $installerOutput).Length / 1MB, 1) Write-Host "`n✅ Build Complete!" -ForegroundColor Green Write-Host "Installer: $installerOutput ($size MB)" Write-Host "" Write-Host "Next steps:" Write-Host " 1. Test installer on clean Windows VM" Write-Host " 2. Code sign: signtool sign /fd sha256 /tr http://timestamp.digicert.com $installerOutput" Write-Host " 3. Upload to dashcaddy.net/downloads" } else { throw "NSIS build failed - installer not created" }