param( [string]$HostName = "christunscripted", [string]$RemoteRoot = "/home/jbird/libre-study", [string]$RemoteBibleDataRoot = "/home/jbird/libre-bible-data/packages/json", [int]$Port = 9174, [string]$BootstrapUser = $env:LIBRESTUDY_BOOTSTRAP_USER, [string]$BootstrapPassword = $env:LIBRESTUDY_BOOTSTRAP_PASSWORD ) $ErrorActionPreference = "Stop" function ConvertTo-WslPath([string]$Path) { $resolved = (Resolve-Path $Path).Path.Replace("\", "/") return (wsl wslpath -a "$resolved").Trim() } function ConvertTo-BashSingleQuoted([string]$Value) { return "'" + $Value.Replace("'", "'\''") + "'" } function Assert-CleanPushedRepo([string]$Path, [string]$Name) { git -C $Path fetch origin main if ($LASTEXITCODE -ne 0) { throw "$Name fetch failed." } $status = git -C $Path status --porcelain if ($status) { throw "$Name has uncommitted changes. Commit or revert them before deploying." } $head = (git -C $Path rev-parse HEAD).Trim() $origin = (git -C $Path rev-parse origin/main).Trim() if ($head -ne $origin) { throw "$Name HEAD $head does not match origin/main $origin. Push the repo before deploying." } return $head } $repoRoot = Split-Path -Parent $PSScriptRoot $dataRepo = Resolve-Path (Join-Path $repoRoot "..\libre-bible-data") $commit = Assert-CleanPushedRepo $repoRoot "Libre Study" $dataCommit = Assert-CleanPushedRepo $dataRepo "LibreBible data" $repoRootWsl = ConvertTo-WslPath $repoRoot $dataRepoWsl = ConvertTo-WslPath $dataRepo $deployedAt = (Get-Date).ToUniversalTime().ToString("o") Push-Location $repoRoot try { $env:VITE_REMOTE_WORKSPACE = "true" $env:VITE_API_BASE_URL = "/study/api" $env:VITE_LIBREBIBLE_BASE_URL = "/study/librebible" npm.cmd run build:web:hosted } finally { Remove-Item Env:VITE_REMOTE_WORKSPACE -ErrorAction SilentlyContinue Remove-Item Env:VITE_API_BASE_URL -ErrorAction SilentlyContinue Remove-Item Env:VITE_LIBREBIBLE_BASE_URL -ErrorAction SilentlyContinue Pop-Location } $deployInfo = @{ commit = $commit libreBibleDataCommit = $dataCommit deployedAt = $deployedAt source = "libre-study" sourceRemote = "origin/main" } | ConvertTo-Json -Compress $deployInfoPath = Join-Path $env:TEMP "libre-study-deploy-info.json" Set-Content -Path $deployInfoPath -Value $deployInfo -NoNewline $deployInfoPathWsl = ConvertTo-WslPath $deployInfoPath $bootstrapUserQuoted = ConvertTo-BashSingleQuoted $BootstrapUser $bootstrapPasswordQuoted = ConvertTo-BashSingleQuoted $BootstrapPassword wsl ssh $HostName "mkdir -p '$RemoteRoot/app' '$RemoteRoot/server' '$RemoteRoot/state' '$RemoteBibleDataRoot'" if ($LASTEXITCODE -ne 0) { throw "Remote directory preparation failed." } wsl rsync -az "$deployInfoPathWsl" "${HostName}:$RemoteRoot/deploy-info.json" if ($LASTEXITCODE -ne 0) { throw "Deploy info rsync failed." } wsl rsync -az --delete "$repoRootWsl/dist-hosted/" "${HostName}:$RemoteRoot/app/" if ($LASTEXITCODE -ne 0) { throw "App rsync failed." } wsl rsync -az --delete "$repoRootWsl/server/" "${HostName}:$RemoteRoot/server/" if ($LASTEXITCODE -ne 0) { throw "Server rsync failed." } wsl rsync -az --delete "$dataRepoWsl/packages/json/" "${HostName}:$RemoteBibleDataRoot/" if ($LASTEXITCODE -ne 0) { throw "LibreBible rsync failed." } $pm2Command = @" cd '$RemoteRoot' && export LIBRESTUDY_BOOTSTRAP_USER=$bootstrapUserQuoted && export LIBRESTUDY_BOOTSTRAP_PASSWORD=$bootstrapPasswordQuoted && if pm2 describe libre-study-web >/dev/null 2>&1; then PORT=$Port PUBLIC_DIR='$RemoteRoot/app' LIBREBIBLE_DATA_DIR='$RemoteBibleDataRoot' STATE_DIR='$RemoteRoot/state' DB_PATH='$RemoteRoot/state/libre-study-web.sqlite3' DEPLOY_INFO_PATH='$RemoteRoot/deploy-info.json' pm2 restart libre-study-web --update-env; else PORT=$Port PUBLIC_DIR='$RemoteRoot/app' LIBREBIBLE_DATA_DIR='$RemoteBibleDataRoot' STATE_DIR='$RemoteRoot/state' DB_PATH='$RemoteRoot/state/libre-study-web.sqlite3' DEPLOY_INFO_PATH='$RemoteRoot/deploy-info.json' pm2 start '$RemoteRoot/server/libre-study-server.mjs' --name libre-study-web --update-env; fi && pm2 save "@ wsl ssh $HostName $pm2Command if ($LASTEXITCODE -ne 0) { throw "PM2 start/restart failed." } Remove-Item $deployInfoPath -Force -ErrorAction SilentlyContinue Write-Output "Deployed Libre Study web commit $commit to ${HostName}:$RemoteRoot on port $Port."