167 lines
5.1 KiB
PowerShell
167 lines
5.1 KiB
PowerShell
param(
|
|
[switch]$SkipFrontendBuild,
|
|
[switch]$SkipSmoke,
|
|
[string]$WebUrl = "http://127.0.0.1:3000",
|
|
[string]$WebReadyUrl = "http://127.0.0.1:3000/editor",
|
|
[string]$ApiHealthUrl = "http://127.0.0.1:8000/health"
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
function Step($Name) {
|
|
Write-Output ""
|
|
Write-Output "==> $Name"
|
|
}
|
|
|
|
function Stop-SferaNextProcesses {
|
|
$processes = Get-CimInstance Win32_Process -Filter "name = 'node.exe'" |
|
|
Where-Object {
|
|
$_.CommandLine -match 'sfera-web' -and (
|
|
$_.CommandLine -match 'next.*start' -or
|
|
$_.CommandLine -match 'next.*build' -or
|
|
$_.CommandLine -match 'npm-cli\.js.*run start'
|
|
)
|
|
}
|
|
if ($processes) {
|
|
Write-Output "Stopping running SFERA Next.js processes."
|
|
$processes | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }
|
|
Start-Sleep -Seconds 2
|
|
}
|
|
}
|
|
|
|
function Stop-SferaApiProcesses {
|
|
$processes = Get-CimInstance Win32_Process |
|
|
Where-Object {
|
|
($_.Name -in @("python.exe", "uvicorn.exe")) -and
|
|
$_.CommandLine -match 'api_server\.main:app' -and
|
|
$_.CommandLine -match 'SFERA'
|
|
}
|
|
if ($processes) {
|
|
Write-Output "Stopping SFERA API smoke processes."
|
|
$processes | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }
|
|
Start-Sleep -Seconds 1
|
|
}
|
|
}
|
|
|
|
function Wait-HttpOk($Url, $TimeoutSeconds = 30) {
|
|
$deadline = (Get-Date).AddSeconds($TimeoutSeconds)
|
|
do {
|
|
try {
|
|
$response = Invoke-WebRequest -UseBasicParsing -Uri $Url -TimeoutSec 15
|
|
if ($response.StatusCode -ge 200 -and $response.StatusCode -lt 500) {
|
|
return
|
|
}
|
|
} catch {
|
|
Start-Sleep -Milliseconds 500
|
|
}
|
|
} while ((Get-Date) -lt $deadline)
|
|
|
|
throw "Timed out waiting for $Url"
|
|
}
|
|
|
|
function Wait-TcpEndpoint($Url, $TimeoutSeconds = 30) {
|
|
$uri = [System.Uri]$Url
|
|
$hostName = $uri.Host
|
|
$port = $uri.Port
|
|
if ($port -le 0) {
|
|
$port = if ($uri.Scheme -eq "https") { 443 } else { 80 }
|
|
}
|
|
$deadline = (Get-Date).AddSeconds($TimeoutSeconds)
|
|
do {
|
|
$client = [System.Net.Sockets.TcpClient]::new()
|
|
try {
|
|
$async = $client.BeginConnect($hostName, $port, $null, $null)
|
|
if ($async.AsyncWaitHandle.WaitOne(2000)) {
|
|
$client.EndConnect($async)
|
|
return
|
|
}
|
|
} catch {
|
|
Start-Sleep -Milliseconds 500
|
|
} finally {
|
|
$client.Close()
|
|
}
|
|
} while ((Get-Date) -lt $deadline)
|
|
|
|
throw "Timed out waiting for TCP $hostName`:$port"
|
|
}
|
|
|
|
$Root = Resolve-Path (Join-Path $PSScriptRoot "..")
|
|
$RustRoot = Join-Path $Root "rust"
|
|
$FrontendRoot = "R:\codex\SFERA\frontend\sfera-web"
|
|
$StartedApiForSmoke = $false
|
|
$StartedWebForSmoke = $false
|
|
|
|
if (-not (Test-Path $FrontendRoot)) {
|
|
$FrontendRoot = Join-Path $Root "frontend\sfera-web"
|
|
}
|
|
|
|
Step "Rust tests and BSL parser build"
|
|
Push-Location $RustRoot
|
|
cargo test
|
|
cargo build -p bsl-parser
|
|
Pop-Location
|
|
|
|
Step "Python and API tests"
|
|
Push-Location $Root
|
|
uv run pytest
|
|
Pop-Location
|
|
|
|
Step "Frontend typecheck"
|
|
Push-Location $FrontendRoot
|
|
npm run typecheck
|
|
|
|
if (-not $SkipFrontendBuild) {
|
|
Step "Frontend production build"
|
|
Stop-SferaNextProcesses
|
|
$env:NEXT_TELEMETRY_DISABLED = "1"
|
|
node_modules\.bin\next.cmd build
|
|
}
|
|
|
|
if (-not $SkipSmoke) {
|
|
Step "Frontend smoke checks"
|
|
try {
|
|
Wait-HttpOk $ApiHealthUrl 5
|
|
} catch {
|
|
Write-Host "Starting API server for smoke checks."
|
|
$apiStdout = Join-Path $Root ".sfera\api-stdout.log"
|
|
$apiStderr = Join-Path $Root ".sfera\api-stderr.log"
|
|
Start-Process -FilePath "uv.exe" `
|
|
-ArgumentList @("run", "uvicorn", "api_server.main:app", "--app-dir", "services/api-server/src", "--host", "0.0.0.0", "--port", "8000") `
|
|
-WorkingDirectory $Root `
|
|
-RedirectStandardOutput $apiStdout `
|
|
-RedirectStandardError $apiStderr
|
|
$StartedApiForSmoke = $true
|
|
Wait-HttpOk $ApiHealthUrl 120
|
|
}
|
|
|
|
$env:SFERA_WEB_URL = $WebUrl
|
|
Stop-SferaNextProcesses
|
|
$runningNext = Get-CimInstance Win32_Process -Filter "name = 'node.exe'" |
|
|
Where-Object { $_.CommandLine -match 'next.*start' -and $_.CommandLine -match 'sfera-web' }
|
|
if (-not $runningNext) {
|
|
$stdout = Join-Path $FrontendRoot ".next\start-stdout.log"
|
|
$stderr = Join-Path $FrontendRoot ".next\start-stderr.log"
|
|
Start-Process -FilePath "npm.cmd" `
|
|
-ArgumentList @("run", "start", "--", "--hostname", "0.0.0.0", "--port", "3000") `
|
|
-WorkingDirectory $FrontendRoot `
|
|
-RedirectStandardOutput $stdout `
|
|
-RedirectStandardError $stderr
|
|
$StartedWebForSmoke = $true
|
|
Wait-TcpEndpoint $WebUrl 45
|
|
}
|
|
npm run smoke:editor
|
|
npm run smoke:editor:runtime
|
|
|
|
if ($StartedWebForSmoke) {
|
|
Stop-SferaNextProcesses
|
|
}
|
|
if ($StartedApiForSmoke) {
|
|
Stop-SferaApiProcesses
|
|
}
|
|
}
|
|
|
|
Pop-Location
|
|
|
|
Write-Output ""
|
|
Write-Output "All requested checks passed."
|