Add 'local' deploy mode to Deploy-Brass.ps1 #1

Merged
Matt merged 1 commits from feature/local-deploy-mode into main 2026-05-22 15:14:44 +00:00
2 changed files with 51 additions and 17 deletions
Showing only changes of commit f280e107f3 - Show all commits
+32 -5
View File
@@ -52,7 +52,10 @@ if (-not (Test-Path $cfgPath)) {
. $cfgPath . $cfgPath
# Sanity-check required vars actually got set (template ships with CHANGE_ME). # Sanity-check required vars actually got set (template ships with CHANGE_ME).
foreach ($v in 'DeployShare','ServerSshHost','ServerSshKey','ServerBinaryRemote') { # $ServerSshKey is only required for SSH-mode deploys; skip it when ServerSshHost = 'local'.
$requiredVars = @('DeployShare','ServerSshHost','ServerBinaryRemote')
if ($ServerSshHost -ne 'local') { $requiredVars += 'ServerSshKey' }
foreach ($v in $requiredVars) {
$val = Get-Variable -Name $v -ValueOnly -ErrorAction Stop $val = Get-Variable -Name $v -ValueOnly -ErrorAction Stop
if ($val -match 'CHANGE_ME' -or [string]::IsNullOrWhiteSpace($val)) { if ($val -match 'CHANGE_ME' -or [string]::IsNullOrWhiteSpace($val)) {
throw "deploy.config.ps1 has placeholder/empty `$$v. Fill it in." throw "deploy.config.ps1 has placeholder/empty `$$v. Fill it in."
@@ -120,14 +123,26 @@ if (($shouldRunPack -or $shouldRunLauncher) -and -not $DryRun -and -not $Force)
# actually broken -- the atomic swap is safe with the daemon running). But # actually broken -- the atomic swap is safe with the daemon running). But
# knowing the state up front lets us tailor the final "next steps" message # knowing the state up front lets us tailor the final "next steps" message
# so a deploy success doesn't silently leave you on the old code. # so a deploy success doesn't silently leave you on the old code.
# Set $ServerSshHost = 'local' in deploy.config.ps1 to skip SSH entirely
# and copy/inspect the server binary on the local filesystem. Use when the
# deploy machine IS the server (e.g. running Deploy-Brass.ps1 on glados).
$isLocalDeploy = ($ServerSshHost -eq 'local')
$daemonWasRunning = $false $daemonWasRunning = $false
if ($shouldRunServer) { if ($shouldRunServer) {
if ($isLocalDeploy) {
Write-Host "Pre-flight: checking daemon state locally..." -ForegroundColor DarkGray
$pgrepOut = & pgrep -f '/brass-sigil-server($| )' 2>$null
} else {
Write-Host "Pre-flight: checking daemon state on $ServerSshHost..." -ForegroundColor DarkGray Write-Host "Pre-flight: checking daemon state on $ServerSshHost..." -ForegroundColor DarkGray
# Single-quoted PS string so PowerShell doesn't try to interpret the # Single-quoted PS string so PowerShell doesn't try to interpret the
# bash-side metacharacters. The remote shell sees the literal pgrep # bash-side metacharacters. Match the binary path followed by either
# command; the trailing $ anchors so we don't match run.sh wrappers. # end-of-line OR a space, so we catch `brass-sigil-server run` (the
$remoteCmd = 'pgrep -f /brass-sigil-server$ 2>/dev/null' # actual invocation) without matching the `/brass-sigil-server/...`
# directory path that appears in the run.sh wrapper's argv.
$remoteCmd = 'pgrep -f /brass-sigil-server($| ) 2>/dev/null'
$pgrepOut = & ssh -i $ServerSshKey -o ConnectTimeout=5 -o BatchMode=yes $ServerSshHost $remoteCmd 2>$null $pgrepOut = & ssh -i $ServerSshKey -o ConnectTimeout=5 -o BatchMode=yes $ServerSshHost $remoteCmd 2>$null
}
$daemonWasRunning = -not [string]::IsNullOrWhiteSpace($pgrepOut) $daemonWasRunning = -not [string]::IsNullOrWhiteSpace($pgrepOut)
if ($daemonWasRunning) { if ($daemonWasRunning) {
Write-Host " Daemon is RUNNING. Atomic swap is safe -- but you'll need to" -ForegroundColor Yellow Write-Host " Daemon is RUNNING. Atomic swap is safe -- but you'll need to" -ForegroundColor Yellow
@@ -224,8 +239,19 @@ if ($shouldRunPack) {
} }
} }
# ─── Stage 6: scp + atomic swap server binary ───────────────────────────── # ─── Stage 6: copy + atomic swap server binary ─────────────────────────────
if ($shouldRunServer) { if ($shouldRunServer) {
if ($isLocalDeploy) {
Step "Copy server binary -> $ServerBinaryRemote (local atomic swap)" {
$localNew = "$ServerBinaryRemote.new"
Copy-Item $serverExe $localNew -Force
& chmod +x $localNew
if ($LASTEXITCODE -ne 0) { throw "chmod failed with exit $LASTEXITCODE" }
Move-Item $localNew $ServerBinaryRemote -Force
$md5 = (& md5sum $ServerBinaryRemote) -split '\s+' | Select-Object -First 1
Write-Host " md5: $md5" -ForegroundColor DarkGray
}
} else {
Step "scp server binary -> $ServerSshHost`:$ServerBinaryRemote (atomic swap)" { Step "scp server binary -> $ServerSshHost`:$ServerBinaryRemote (atomic swap)" {
$remoteNew = "$ServerBinaryRemote.new" $remoteNew = "$ServerBinaryRemote.new"
& scp -i $ServerSshKey -o ConnectTimeout=15 $serverExe "$ServerSshHost`:$remoteNew" & scp -i $ServerSshKey -o ConnectTimeout=15 $serverExe "$ServerSshHost`:$remoteNew"
@@ -234,6 +260,7 @@ if ($shouldRunServer) {
& ssh -i $ServerSshKey -o ConnectTimeout=10 $ServerSshHost $cmd & ssh -i $ServerSshKey -o ConnectTimeout=10 $ServerSshHost $cmd
if ($LASTEXITCODE -ne 0) { throw "ssh swap failed with exit $LASTEXITCODE" } if ($LASTEXITCODE -ne 0) { throw "ssh swap failed with exit $LASTEXITCODE" }
} }
}
Write-Host "" Write-Host ""
if ($daemonWasRunning) { if ($daemonWasRunning) {
Write-Host "Server binary swapped on disk, but the daemon was running before this" -ForegroundColor Yellow Write-Host "Server binary swapped on disk, but the daemon was running before this" -ForegroundColor Yellow
+9 -2
View File
@@ -19,13 +19,20 @@ $ManifestPublicUrl = 'https://CHANGE_ME/pack/manifest.json'
# ─── Server (brass-sigil-server daemon host) ─────────────────────────────── # ─── Server (brass-sigil-server daemon host) ───────────────────────────────
# user@host for the Linux box running the daemon. # user@host for the Linux box running the daemon.
#
# Set to the literal string 'local' if Deploy-Brass.ps1 is being run on the
# server itself (e.g. on glados over the Telegram bridge). In local mode the
# script skips scp/ssh and copies the binary directly to $ServerBinaryRemote
# with an in-place atomic rename; $ServerSshKey is ignored.
$ServerSshHost = 'user@CHANGE_ME' $ServerSshHost = 'user@CHANGE_ME'
# Path to the local SSH private key authorised on the server. # Path to the local SSH private key authorised on the server.
# Ignored when $ServerSshHost = 'local'.
$ServerSshKey = "$env:USERPROFILE\.ssh\id_ed25519" $ServerSshKey = "$env:USERPROFILE\.ssh\id_ed25519"
# Absolute path on the Linux box where the brass-sigil-server binary lives. # Absolute path where the brass-sigil-server binary lives -- on the remote
# `Deploy-Brass.ps1` uploads to "<this>.new" then `mv` over for atomic swap. # host in SSH mode, on the local filesystem in 'local' mode.
# `Deploy-Brass.ps1` writes to "<this>.new" then renames over for atomic swap.
$ServerBinaryRemote = '/home/user/brass-sigil-server/brass-sigil-server' $ServerBinaryRemote = '/home/user/brass-sigil-server/brass-sigil-server'
# ─── Build outputs (don't normally need to change) ───────────────────────── # ─── Build outputs (don't normally need to change) ─────────────────────────