mirror of
https://github.com/hansjone/netx.git
synced 2026-10-09 02:00:46 +08:00
Ship installable releases via zip/Inno Setup with optional bundled Postgres, API-hosted SPA, manual update path, and CI workflow for future tag builds. Co-authored-by: Cursor <cursoragent@cursor.com>
104 lines
4 KiB
PowerShell
104 lines
4 KiB
PowerShell
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$PackagePath,
|
|
[string]$ProgramRoot = "",
|
|
[string]$DataRoot = "",
|
|
[switch]$SkipBackup = $false,
|
|
[switch]$NoStart = $false
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
. "$PSScriptRoot\_common.ps1"
|
|
|
|
$prog = Get-NetxProgramRoot -Override $ProgramRoot
|
|
$data = Get-NetxDataRoot -ProgramRoot $prog -Override $DataRoot
|
|
|
|
if (-not (Test-Path $PackagePath)) {
|
|
throw "package_not_found: $PackagePath"
|
|
}
|
|
|
|
$work = Join-Path $env:TEMP ("netx-update-" + [guid]::NewGuid().ToString("n"))
|
|
New-Item -ItemType Directory -Path $work -Force | Out-Null
|
|
|
|
try {
|
|
Write-Host "==> Extracting update package"
|
|
if ($PackagePath.ToLowerInvariant().EndsWith(".zip")) {
|
|
Expand-Archive -Path $PackagePath -DestinationPath $work -Force
|
|
} else {
|
|
throw "unsupported_package: use a .zip built by build_release.ps1"
|
|
}
|
|
|
|
$src = $work
|
|
# If zip has a single top-level folder, use it.
|
|
$kids = @(Get-ChildItem -Path $work -Directory)
|
|
if ($kids.Count -eq 1 -and (Test-Path (Join-Path $kids[0].FullName "version.json"))) {
|
|
$src = $kids[0].FullName
|
|
} elseif (-not (Test-Path (Join-Path $work "version.json"))) {
|
|
$nested = Get-ChildItem -Path $work -Recurse -Filter "version.json" | Select-Object -First 1
|
|
if ($nested) { $src = Split-Path -Parent $nested.FullName }
|
|
}
|
|
|
|
$newVerFile = Join-Path $src "version.json"
|
|
if (-not (Test-Path $newVerFile)) {
|
|
throw "version.json missing in package"
|
|
}
|
|
$newVer = (Get-Content -Raw $newVerFile | ConvertFrom-Json).version
|
|
$oldVer = Get-NetxVersion -ProgramRoot $prog
|
|
Write-Host "==> Updating $oldVer -> $newVer"
|
|
|
|
if (-not $SkipBackup) {
|
|
$stamp = Get-Date -Format "yyyyMMdd_HHmmss"
|
|
$bak = Join-Path $data "backups\pre-update-$stamp"
|
|
New-Item -ItemType Directory -Path $bak -Force | Out-Null
|
|
$envFile = Join-Path $data ".env"
|
|
if (Test-Path $envFile) {
|
|
Copy-Item $envFile (Join-Path $bak ".env")
|
|
}
|
|
Write-Host "==> Backup marker: $bak (data/pgdata left in place; optional pg_dump not run)"
|
|
}
|
|
|
|
Write-Host "==> Stopping services"
|
|
& powershell -ExecutionPolicy Bypass -File (Join-Path $PSScriptRoot "stop_netx_app.ps1") `
|
|
-ProgramRoot $prog -DataRoot $data
|
|
|
|
# Replace program layers only — never wipe data root.
|
|
$replaceDirs = @("netx_api", "alembic", "web", "packaging", "scripts", "postgres", "packages")
|
|
foreach ($name in $replaceDirs) {
|
|
$from = Join-Path $src $name
|
|
$to = Join-Path $prog $name
|
|
if (-not (Test-Path $from)) { continue }
|
|
Write-Host "==> Replacing $name"
|
|
if (Test-Path $to) {
|
|
Remove-Item -Recurse -Force $to
|
|
}
|
|
Copy-Item -Path $from -Destination $to -Recurse -Force
|
|
}
|
|
foreach ($f in @("requirements.txt", "pyproject.toml", "alembic.ini", "version.json", "README.md", "LICENSE")) {
|
|
$from = Join-Path $src $f
|
|
if (Test-Path $from) {
|
|
Copy-Item -Path $from -Destination (Join-Path $prog $f) -Force
|
|
}
|
|
}
|
|
# Optional runtime / .venv shipped in package
|
|
if (Test-Path (Join-Path $src "runtime")) {
|
|
$rt = Join-Path $prog "runtime"
|
|
if (Test-Path $rt) { Remove-Item -Recurse -Force $rt }
|
|
Copy-Item -Path (Join-Path $src "runtime") -Destination $rt -Recurse -Force
|
|
}
|
|
if (Test-Path (Join-Path $src ".venv")) {
|
|
Write-Host "==> Replacing .venv from package"
|
|
$venvTo = Join-Path $prog ".venv"
|
|
if (Test-Path $venvTo) { Remove-Item -Recurse -Force $venvTo }
|
|
Copy-Item -Path (Join-Path $src ".venv") -Destination $venvTo -Recurse -Force
|
|
}
|
|
|
|
Write-Host "==> Update files applied" -ForegroundColor Green
|
|
if (-not $NoStart) {
|
|
& powershell -ExecutionPolicy Bypass -File (Join-Path $PSScriptRoot "start_netx_app.ps1") `
|
|
-ProgramRoot $prog -DataRoot $data -SkipBrowser
|
|
}
|
|
} finally {
|
|
if (Test-Path $work) {
|
|
Remove-Item -Recurse -Force $work -ErrorAction SilentlyContinue
|
|
}
|
|
}
|