Skip to content

Commit d80ef5d

Browse files
feat: improve engine health check and configuration management in CI workflows
1 parent d8327d2 commit d80ef5d

1 file changed

Lines changed: 101 additions & 9 deletions

File tree

.github/workflows/release.yml

Lines changed: 101 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ permissions:
1212
env:
1313
# Derived from tag at runtime (e.g. v1.0.3 -> 1.0.3)
1414
RELEASE_VERSION: ""
15+
# Starting port written into engine-config.json in CI (engine may increment).
1516
ENGINE_PORT: "8740"
1617

1718
jobs:
@@ -93,19 +94,41 @@ jobs:
9394
- name: Validate engine runs (health check)
9495
shell: pwsh
9596
run: |
96-
$p = Start-Process -FilePath ".\\dist\\SentraCoreEngine.exe" -PassThru -WindowStyle Hidden
97+
$cfgPath = Resolve-Path ".\\dist\\engine-config.json"
98+
# Kill anything listening on the start port (best-effort).
99+
$startPort = [int]${env:ENGINE_PORT}
100+
$pids = (Get-NetTCPConnection -State Listen -LocalPort $startPort -ErrorAction SilentlyContinue | Select-Object -ExpandProperty OwningProcess -Unique)
101+
foreach ($pid in $pids) { try { Stop-Process -Id $pid -Force } catch {} }
102+
# Write engine-config.json next to engine (single source of truth).
103+
$cfg = @{
104+
host = "127.0.0.1"
105+
port = $startPort
106+
bind_host = "127.0.0.1"
107+
status = "stopped"
108+
last_error = ""
109+
pid = 0
110+
} | ConvertTo-Json
111+
$tmp = "$cfgPath.tmp"
112+
$cfg | Out-File -FilePath $tmp -Encoding utf8
113+
Move-Item -Force $tmp $cfgPath
114+
$p = Start-Process -FilePath ".\\dist\\SentraCoreEngine.exe" -PassThru -WindowStyle Hidden -Environment @{ "SENTRACORE_ENGINE_CONFIG" = "$cfgPath" }
97115
try {
98116
$ok = $false
99117
for ($i=0; $i -lt 40; $i++) {
100118
try {
101-
$r = Invoke-WebRequest -UseBasicParsing -TimeoutSec 2 "http://127.0.0.1:${env:ENGINE_PORT}/api/v1/health"
119+
$cfgDisk = $null
120+
try { $cfgDisk = Get-Content "$cfgPath" -Raw | ConvertFrom-Json } catch {}
121+
$host = if ($cfgDisk -and $cfgDisk.host) { $cfgDisk.host } else { "127.0.0.1" }
122+
$port = if ($cfgDisk -and $cfgDisk.port) { [int]$cfgDisk.port } else { $startPort }
123+
$r = Invoke-WebRequest -UseBasicParsing -TimeoutSec 2 "http://$host`:$port/api/v1/health"
102124
if ($r.StatusCode -eq 200) { $ok = $true; break }
103125
} catch {}
104126
Start-Sleep -Milliseconds 500
105127
}
106128
if (-not $ok) { throw "Engine health check failed" }
107129
} finally {
108130
try { Stop-Process -Id $p.Id -Force } catch {}
131+
try { Stop-Process -Name "SentraCoreEngine" -Force } catch {}
109132
}
110133
111134
- name: Setup Flutter
@@ -210,17 +233,43 @@ jobs:
210233
- name: Validate engine runs (health check)
211234
run: |
212235
chmod +x dist/SentraCoreEngine
213-
./dist/SentraCoreEngine &
236+
START_PORT="${ENGINE_PORT:-8740}"
237+
# Kill anything on start port (best-effort).
238+
lsof -ti "tcp:${START_PORT}" | xargs kill -9 2>/dev/null || true
239+
# Write engine-config.json next to engine.
240+
cat > dist/engine-config.json <<EOF
241+
{
242+
"host": "127.0.0.1",
243+
"port": ${START_PORT},
244+
"bind_host": "127.0.0.1",
245+
"status": "stopped",
246+
"last_error": "",
247+
"pid": 0
248+
}
249+
EOF
250+
SENTRACORE_ENGINE_CONFIG="$(pwd)/dist/engine-config.json" ./dist/SentraCoreEngine &
214251
PID=$!
215252
OK=0
216253
for i in {1..40}; do
217-
if curl -fsS --max-time 2 "http://127.0.0.1:${ENGINE_PORT}/api/v1/health" >/dev/null; then
254+
PORT="$(python - <<'PY'
255+
import json, pathlib
256+
p = pathlib.Path("dist/engine-config.json")
257+
try:
258+
j = json.loads(p.read_text())
259+
print(int(j.get("port", 0)) or 0)
260+
except Exception:
261+
print(0)
262+
PY
263+
)"
264+
if [ -z "$PORT" ] || [ "$PORT" = "0" ]; then PORT="$START_PORT"; fi
265+
if curl -fsS --max-time 2 "http://127.0.0.1:${PORT}/api/v1/health" >/dev/null; then
218266
OK=1
219267
break
220268
fi
221269
sleep 0.5
222270
done
223271
kill $PID || true
272+
pkill -f SentraCoreEngine || true
224273
if [ "$OK" -ne 1 ]; then
225274
echo "Engine health check failed"
226275
exit 1
@@ -330,17 +379,41 @@ jobs:
330379
- name: Validate engine runs (health check)
331380
run: |
332381
chmod +x dist/SentraCoreEngine
333-
./dist/SentraCoreEngine &
382+
START_PORT="${ENGINE_PORT:-8740}"
383+
fuser -k "${START_PORT}/tcp" 2>/dev/null || true
384+
cat > dist/engine-config.json <<EOF
385+
{
386+
"host": "127.0.0.1",
387+
"port": ${START_PORT},
388+
"bind_host": "0.0.0.0",
389+
"status": "stopped",
390+
"last_error": "",
391+
"pid": 0
392+
}
393+
EOF
394+
SENTRACORE_ENGINE_CONFIG="$(pwd)/dist/engine-config.json" ./dist/SentraCoreEngine &
334395
PID=$!
335396
OK=0
336397
for i in {1..40}; do
337-
if curl -fsS --max-time 2 "http://127.0.0.1:${ENGINE_PORT}/api/v1/health" >/dev/null; then
398+
PORT="$(python - <<'PY'
399+
import json, pathlib
400+
p = pathlib.Path("dist/engine-config.json")
401+
try:
402+
j = json.loads(p.read_text())
403+
print(int(j.get("port", 0)) or 0)
404+
except Exception:
405+
print(0)
406+
PY
407+
)"
408+
if [ -z "$PORT" ] || [ "$PORT" = "0" ]; then PORT="$START_PORT"; fi
409+
if curl -fsS --max-time 2 "http://127.0.0.1:${PORT}/api/v1/health" >/dev/null; then
338410
OK=1
339411
break
340412
fi
341413
sleep 0.5
342414
done
343415
kill $PID || true
416+
pkill -f SentraCoreEngine || true
344417
if [ "$OK" -ne 1 ]; then
345418
echo "Engine health check failed"
346419
exit 1
@@ -373,19 +446,38 @@ jobs:
373446
set -e
374447
HERE="$(dirname "$(readlink -f "$0")")"
375448
cd "$HERE/usr/bin"
449+
# Create engine-config.json (single source of truth) next to binaries.
450+
if [ ! -f "./engine-config.json" ]; then
451+
cat > "./engine-config.json" <<'JSON'
452+
{
453+
"host": "127.0.0.1",
454+
"port": 8740,
455+
"bind_host": "0.0.0.0",
456+
"status": "stopped",
457+
"last_error": "",
458+
"pid": 0
459+
}
460+
JSON
461+
fi
376462
# Start engine in background (best-effort) and stop it when UI exits.
377-
./SentraCoreEngine >/dev/null 2>&1 &
463+
SENTRACORE_ENGINE_CONFIG="$HERE/usr/bin/engine-config.json" ./SentraCoreEngine >/dev/null 2>&1 &
378464
ENGINE_PID=$!
379-
trap "kill $ENGINE_PID >/dev/null 2>&1 || true" EXIT
465+
trap "kill $ENGINE_PID >/dev/null 2>&1 || true; pkill -f SentraCoreEngine >/dev/null 2>&1 || true" EXIT
380466
# Wait until engine responds (avoid UI starting before backend).
381467
OK=0
382468
for i in $(seq 1 40); do
383-
if curl -fsS --max-time 2 "http://127.0.0.1:${ENGINE_PORT}/api/v1/health" >/dev/null; then
469+
PORT="$(sed -n 's/.*\"port\"[[:space:]]*:[[:space:]]*\\([0-9][0-9]*\\).*/\\1/p' ./engine-config.json | head -n 1)"
470+
if [ -z "$PORT" ]; then PORT="8740"; fi
471+
if curl -fsS --max-time 2 "http://127.0.0.1:${PORT}/api/v1/health" >/dev/null; then
384472
OK=1
385473
break
386474
fi
387475
sleep 0.5
388476
done
477+
if [ "$OK" -ne 1 ]; then
478+
echo "Engine health check failed"
479+
exit 1
480+
fi
389481
exec ./sentracore_dashboard "$@"
390482
EOF
391483
chmod +x SentraCore.AppDir/AppRun

0 commit comments

Comments
 (0)