# Publish MyOffice API + SPA for Proxmox (artifacts only, no source). # Usage (from repo root): # .\proxmox\publish.ps1 # .\proxmox\publish.ps1 -OutDir D:\builds\myoffice # .\proxmox\publish.ps1 -Tar # also write myoffice-publish.tar.gz next to OutDir # # Before build: # 1) copy appsettings.shared.json → Development + Production overlays (only if missing) # 2) restore NuGet + npm # # Output: / with MyOffice.Web.dll + wwwroot/ (SPA, same-origin URLs) [CmdletBinding()] param( [string]$OutDir = '', [switch]$Tar ) $ErrorActionPreference = 'Stop' $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path $repoRoot = Resolve-Path (Join-Path $scriptDir '..') Set-Location $repoRoot if (-not $OutDir) { $OutDir = Join-Path $repoRoot '_Published' } $OutDir = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($OutDir) $sharedDir = Join-Path $repoRoot 'MyOffice.Shared' $sharedBase = Join-Path $sharedDir 'appsettings.shared.json' if (-not (Test-Path $sharedBase)) { throw "Missing $sharedBase" } Write-Host "-----------------------------------------------" Write-Host "Copy appsettings.shared.json -> Development + Production (if missing)" Write-Host "-----------------------------------------------" foreach ($name in @('appsettings.shared.Development.json', 'appsettings.shared.Production.json')) { $dest = Join-Path $sharedDir $name if (Test-Path $dest) { Write-Host "Skip (exists): $name" } else { Copy-Item $sharedBase $dest Write-Host "Created: $name" } } Write-Host "-----------------------------------------------" Write-Host "Restore NuGet packages" Write-Host "-----------------------------------------------" dotnet restore 'MyOffice.Web\MyOffice.Web.csproj' --nologo if ($LASTEXITCODE -ne 0) { throw "dotnet restore failed with exit code $LASTEXITCODE" } $spaDir = Join-Path $repoRoot 'MyOffice.SPA' $envSample = Join-Path $spaDir 'src\environments\environment.sample.ts' $envLocal = Join-Path $spaDir 'src\environments\environment.ts' if (-not (Test-Path $envLocal) -and (Test-Path $envSample)) { Copy-Item $envSample $envLocal } Write-Host "-----------------------------------------------" Write-Host "Restore npm packages (MyOffice.SPA)" Write-Host "-----------------------------------------------" Push-Location $spaDir try { if (Test-Path (Join-Path $spaDir 'package-lock.json')) { npm ci } else { npm install } if ($LASTEXITCODE -ne 0) { throw "npm restore failed with exit code $LASTEXITCODE" } } finally { Pop-Location } Write-Host "-----------------------------------------------" Write-Host "dotnet publish -> $OutDir" Write-Host "-----------------------------------------------" if (Test-Path $OutDir) { Remove-Item -Recurse -Force $OutDir } New-Item -ItemType Directory -Path $OutDir | Out-Null dotnet publish 'MyOffice.Web\MyOffice.Web.csproj' -c Release -o $OutDir --no-restore --nologo if ($LASTEXITCODE -ne 0) { throw "dotnet publish failed with exit code $LASTEXITCODE" } # CT owns Production overlays — do not ship local env-specific appsettings. # Keep appsettings.json + appsettings.shared.json (required at runtime). Get-ChildItem -Path $OutDir -Filter 'appsettings*.json' -File -ErrorAction SilentlyContinue | Where-Object { $_.Name -notin @('appsettings.json', 'appsettings.shared.json') } | Remove-Item -Force Write-Host "-----------------------------------------------" Write-Host "ng build (proxmox) -> $OutDir\wwwroot" Write-Host "-----------------------------------------------" Push-Location $spaDir try { $spaOut = Join-Path $env:TEMP ("myoffice-spa-" + [guid]::NewGuid().ToString('N')) npx ng build --configuration proxmox --output-path $spaOut if ($LASTEXITCODE -ne 0) { throw "ng build failed with exit code $LASTEXITCODE" } $wwwroot = Join-Path $OutDir 'wwwroot' if (Test-Path $wwwroot) { Remove-Item -Recurse -Force $wwwroot } New-Item -ItemType Directory -Path $wwwroot | Out-Null $browser = Join-Path $spaOut 'browser' if (Test-Path $browser) { Copy-Item -Path (Join-Path $browser '*') -Destination $wwwroot -Recurse -Force } else { Copy-Item -Path (Join-Path $spaOut '*') -Destination $wwwroot -Recurse -Force } Remove-Item -Recurse -Force $spaOut -ErrorAction SilentlyContinue } finally { Pop-Location } if ($Tar) { $tarPath = Join-Path (Split-Path -Parent $OutDir) 'myoffice-publish.tar.gz' if (Test-Path $tarPath) { Remove-Item -Force $tarPath } Write-Host "-----------------------------------------------" Write-Host "tar -> $tarPath" Write-Host "-----------------------------------------------" # Windows 10+ tar; paths relative to OutDir parent Push-Location (Split-Path -Parent $OutDir) try { $leaf = Split-Path -Leaf $OutDir tar -czf $tarPath $leaf if ($LASTEXITCODE -ne 0) { throw "tar failed with exit code $LASTEXITCODE" } } finally { Pop-Location } Write-Host "Archive: $tarPath" } Write-Host "" Write-Host "Published to $OutDir" Write-Host "Next (Gitea): .\proxmox\publish.ps1 -Tar ; .\proxmox\release.ps1 -GiteaUrl ... -Owner ... -Tag v1.2.3" Write-Host "Linux/CI: ./proxmox/publish.sh --tar ; ./proxmox/release.sh ..." Write-Host "Lab SSH: .\proxmox\deploy.ps1 -TargetHost " Write-Host ""