[CmdletBinding()] param([string]$PostgresBin = 'D:\pgsql17\bin') Set-StrictMode -Version 3.0 $ErrorActionPreference = 'Stop' $started = $false $root = Join-Path ([IO.Path]::GetTempPath()) ('yovision-bell-140-' + [guid]::NewGuid().ToString('N')) $data = Join-Path $root 'postgres' $log = Join-Path $root 'postgres.log' $serverRoot = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path function Get-FreePort { $listener = [Net.Sockets.TcpListener]::new([Net.IPAddress]::Loopback, 0) try { $listener.Start() return ([Net.IPEndPoint]$listener.LocalEndpoint).Port } finally { $listener.Stop() } } function Wait-ForPort([int]$Port) { for ($attempt = 0; $attempt -lt 120; $attempt++) { try { $client = [Net.Sockets.TcpClient]::new() $connected = $client.ConnectAsync('127.0.0.1', $Port).Wait(250) -and $client.Connected $client.Dispose() if ($connected) { return } } catch { } Start-Sleep -Milliseconds 250 } throw 'PostgreSQL did not start' } New-Item -ItemType Directory -Path $root | Out-Null $port = Get-FreePort try { foreach ($name in @('initdb.exe', 'pg_ctl.exe', 'createdb.exe')) { if (-not (Test-Path -LiteralPath (Join-Path $PostgresBin $name))) { throw "Missing $name" } } & (Join-Path $PostgresBin 'initdb.exe') -D $data -U postgres -A trust --encoding=UTF8 --no-locale | Out-Null if ($LASTEXITCODE -ne 0) { throw 'initdb failed' } $arguments = "-D `"$data`" -l `"$log`" -o `"-p $port -h 127.0.0.1`" start" Start-Process (Join-Path $PostgresBin 'pg_ctl.exe') -ArgumentList $arguments -WindowStyle Hidden | Out-Null Wait-ForPort $port $started = $true & (Join-Path $PostgresBin 'createdb.exe') -h 127.0.0.1 -p $port -U postgres bell_140 if ($LASTEXITCODE -ne 0) { throw 'createdb failed' } $env:GOTOOLCHAIN = 'go1.26.5' $env:BELL_DATABASE_URL = "host=127.0.0.1 port=$port user=postgres dbname=bell_140 sslmode=disable" $env:BELL_MINIMAL_MENU_TEST_DATABASE_URL = $env:BELL_DATABASE_URL $env:BELL_JWT_SECRET = [guid]::NewGuid().ToString('N') + [guid]::NewGuid().ToString('N') $env:BELL_BOOTSTRAP_USERNAME = 'bell_140_admin' $env:BELL_BOOTSTRAP_PASSWORD = [guid]::NewGuid().ToString('N') $env:BELL_HOST = '127.0.0.1' $env:BELL_PORT = (Get-FreePort).ToString() Push-Location $serverRoot try { go run . migrate -c config/settings.yml *> (Join-Path $root 'migrate.log') if ($LASTEXITCODE -ne 0) { throw "migration failed; evidence: $root" } go test ./tests/bell_minimal_menu -count=1 -v if ($LASTEXITCODE -ne 0) { throw 'minimal menu test failed' } go run . migrate -c config/settings.yml *> (Join-Path $root 'migrate-repeat.log') if ($LASTEXITCODE -ne 0) { throw "repeat migration failed; evidence: $root" } } finally { Pop-Location } Write-Output 'BELL_140_MINIMAL_MENU fresh=true upgrade=true repeat=true admin_whitelist=true operator_default_menu=false' } finally { if ($started) { & (Join-Path $PostgresBin 'pg_ctl.exe') -D $data -m fast stop *> (Join-Path $root 'stop.log') } foreach ($name in @('BELL_DATABASE_URL', 'BELL_MINIMAL_MENU_TEST_DATABASE_URL', 'BELL_JWT_SECRET', 'BELL_BOOTSTRAP_USERNAME', 'BELL_BOOTSTRAP_PASSWORD', 'BELL_HOST', 'BELL_PORT')) { Remove-Item "Env:$name" -ErrorAction SilentlyContinue } }