Skip to content

Commit c1bb70f

Browse files
authored
ci(windows): fix Lemonade port binding for the two integration jobs (#1867)
## Why this matters The two Windows integration jobs — **Test Agent SDK on Windows** and **Test GAIA CLI on Windows** — went intermittently red on `main` starting 06-24, failing at Lemonade startup (`Lemonade server not ready`) before any test ran. Root cause is **runner state, not a code regression**: the pinned `LemonadeServer.exe` binary is correctly v10.7.0 (CI verifies "no reconcile needed"), but a **stale `config.json`** in the runner's SYSTEM profile pins the server to the old default port **8000**, while the health check polls **13305**. It only looked like "flaky infra a re-run clears" because a previous run's healthy 13305 server was sometimes still alive. No PR caused it — the startup script has been unchanged since #1733 (06-18); the trigger was a v10.8.x install touching the runner's config. The fix makes the server bind 13305 deterministically: launch `LemonadeServer.exe --port 13305` (in v10.x the port is a bare flag — there's no `serve` subcommand, and the old `lemonade-server` shim was removed in v10.5) **and** clear the stale `config.json` so the documented 13305 default regenerates. Also broadens the pre-start process cleanup to the full Lemonade/`llama-server` set so a wedged child can't survive a retry. A second change adds `installer/scripts/**` and these workflows' own files to their `paths` triggers, so changes to the Lemonade startup script actually re-run the jobs they govern (previously they only triggered on `src/**`/`tests/**`, so this very fix couldn't validate itself). ## Test plan These jobs run only on the self-hosted Windows runner, so CI is the verification: - [x] **Test GAIA CLI on Windows** passes — server binds 13305 (validated on an earlier push of this branch). - [ ] **Test Agent SDK on Windows** passes with the same `Server binary: …LemonadeServer.exe` → `Healthy after attempt 1` signature. - [ ] Re-run from a cold runner (no pre-existing 13305 server) self-heals to 13305 instead of getting stuck on 8000.
1 parent 9d82e9e commit c1bb70f

3 files changed

Lines changed: 34 additions & 7 deletions

File tree

.github/workflows/test_agent_sdk.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,17 @@ on:
1414
- "src/**"
1515
- "tests/**"
1616
- "setup.py"
17+
- "installer/scripts/**"
18+
- ".github/workflows/test_agent_sdk.yml"
1719
pull_request:
1820
branches: ["main"]
1921
types: [opened, synchronize, reopened, ready_for_review]
2022
paths:
2123
- "src/**"
2224
- "tests/**"
2325
- "setup.py"
26+
- "installer/scripts/**"
27+
- ".github/workflows/test_agent_sdk.yml"
2428
merge_group:
2529
workflow_dispatch:
2630

.github/workflows/test_gaia_cli_windows.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ on:
1616
- "tests/**"
1717
- "setup.py"
1818
- "pyproject.toml"
19+
- "installer/scripts/**"
20+
- ".github/workflows/test_gaia_cli_windows.yml"
1921
pull_request:
2022
branches: ["main"]
2123
types: [opened, synchronize, reopened, ready_for_review]
@@ -24,6 +26,8 @@ on:
2426
- "tests/**"
2527
- "setup.py"
2628
- "pyproject.toml"
29+
- "installer/scripts/**"
30+
- ".github/workflows/test_gaia_cli_windows.yml"
2731
merge_group:
2832
workflow_dispatch:
2933

installer/scripts/ensure-lemonade-running.ps1

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
55
.DESCRIPTION
66
GitHub Actions terminates any process a job spawns when the job ends, so a
7-
server started inline never survives to the next job. This launches the
8-
version-matched LemonadeServer.exe as a Windows **Scheduled Task** instead --
9-
the Task Scheduler owns it, not the job, so it persists across jobs and
10-
reboots. The task also auto-starts at boot.
7+
server started inline never survives to the next job. This launches
8+
LemonadeServer.exe with `--port $Port` (so it binds $Port regardless of a
9+
stale config.json) as a Windows **Scheduled Task** instead: the Task Scheduler
10+
owns it, not the job, so it persists across jobs and reboots. The task also
11+
auto-starts at boot.
1112
1213
Idempotent + self-healing:
1314
- If a healthy server is already on $Port, returns immediately.
@@ -41,7 +42,13 @@ if (-not $ForceRestart -and (Test-Health)) {
4142
exit 0
4243
}
4344

44-
# Resolve the server binary.
45+
# Resolve the server binary. In v10.x the server is LemonadeServer.exe; the
46+
# legacy `lemonade-server` shim was deprecated in v10.5 and is no longer
47+
# installed, so we launch LemonadeServer.exe directly. There is no `serve`
48+
# subcommand -- the listen port lives in config.json, and a stale config in this
49+
# profile (e.g. a pre-v10.1 default of 8000) is what pins the server to the wrong
50+
# port. We pass `--port` to override it AND clear the stale config so the 13305
51+
# default regenerates. Cross-check installer/scripts/start-lemonade.ps1.
4552
if (-not $ServerExe -or -not (Test-Path $ServerExe)) {
4653
$ServerExe = (Get-ChildItem `
4754
"C:\Users\*\AppData\Local\lemonade_server\bin\LemonadeServer.exe", `
@@ -52,10 +59,21 @@ if (-not $ServerExe -or -not (Test-Path $ServerExe)) {
5259
if (-not $ServerExe) { Write-Host "ERROR: LemonadeServer.exe not found on the runner."; exit 1 }
5360
Write-Host "Server binary: $ServerExe"
5461

62+
# Clear any stale config.json so it can't keep pinning the server to an old port.
63+
# The SYSTEM scheduled task reads the SYSTEM profile cache. --port below also
64+
# overrides, but a clean config is the documented path back to the 13305 default.
65+
# Best-effort: missing files are expected and fine.
66+
foreach ($cfg in @(
67+
"C:\windows\system32\config\systemprofile\.cache\lemonade\config.json",
68+
"C:\windows\system32\config\systemprofile\AppData\Local\lemonade_server\config.json"
69+
)) {
70+
if (Test-Path $cfg) { Write-Host "Removing stale config: $cfg"; Remove-Item $cfg -Force -ErrorAction SilentlyContinue }
71+
}
72+
5573
# (Re)register a Scheduled Task that runs the server as SYSTEM, auto-starting at
5674
# boot and restarting on failure. Force overwrites any prior definition.
5775
try {
58-
$action = New-ScheduledTaskAction -Execute $ServerExe
76+
$action = New-ScheduledTaskAction -Execute $ServerExe -Argument "--port $Port"
5977
$trigger = New-ScheduledTaskTrigger -AtStartup
6078
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
6179
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries `
@@ -74,7 +92,8 @@ $healthy = $false
7492
for ($attempt = 1; $attempt -le 4 -and -not $healthy; $attempt++) {
7593
Write-Host "--- start attempt $attempt ---"
7694
Stop-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
77-
Get-Process LemonadeServer -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
95+
Get-Process LemonadeServer, lemonade-server, lemonade, llama-server, llama-server-dev, lemonade-server-dev `
96+
-ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
7897
Start-Sleep -Seconds 4
7998
Start-ScheduledTask -TaskName $TaskName
8099
for ($i = 0; $i -lt 20; $i++) {

0 commit comments

Comments
 (0)