Skip to content

Commit f69c7d6

Browse files
ouyyyyangclaude
andcommitted
add windows smoke test workflow
Runs start.bat end-to-end on windows-latest to catch Windows-only regressions (login, agent startup, PowerShell launcher) that Mac dev can't reproduce locally. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a32fc5e commit f69c7d6

1 file changed

Lines changed: 162 additions & 0 deletions

File tree

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
name: Windows smoke test
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
workflow_dispatch:
9+
10+
jobs:
11+
smoke:
12+
name: start.bat end-to-end on Windows
13+
runs-on: windows-latest
14+
timeout-minutes: 15
15+
16+
steps:
17+
- name: Checkout
18+
uses: actions/checkout@v4
19+
20+
- name: Setup Node.js
21+
uses: actions/setup-node@v4
22+
with:
23+
node-version: "22"
24+
25+
- name: Install dependencies
26+
shell: pwsh
27+
run: npm ci
28+
29+
- name: Start agent via start.bat
30+
shell: pwsh
31+
run: |
32+
$ErrorActionPreference = "Stop"
33+
Write-Host "Launching start.bat in background..."
34+
$proc = Start-Process `
35+
-FilePath "cmd.exe" `
36+
-ArgumentList "/c", "start.bat" `
37+
-WorkingDirectory "$env:GITHUB_WORKSPACE" `
38+
-WindowStyle Hidden `
39+
-PassThru
40+
Write-Host "start.bat launcher PID: $($proc.Id)"
41+
42+
- name: Wait for agent to be ready
43+
shell: pwsh
44+
run: |
45+
$ErrorActionPreference = "Stop"
46+
$portFile = "runtime/agent/agent.port"
47+
$port = $null
48+
49+
for ($i = 0; $i -lt 90; $i++) {
50+
if (Test-Path $portFile) {
51+
$port = (Get-Content $portFile -Raw).Trim()
52+
if ($port) { break }
53+
}
54+
Start-Sleep -Seconds 2
55+
}
56+
57+
if (-not $port) {
58+
Write-Error "agent.port file never appeared — start.bat failed to start the agent"
59+
exit 1
60+
}
61+
62+
Write-Host "Agent port: $port"
63+
"AGENT_PORT=$port" | Out-File -FilePath $env:GITHUB_ENV -Append
64+
65+
$url = "http://127.0.0.1:$port/api/config"
66+
for ($i = 0; $i -lt 60; $i++) {
67+
try {
68+
$resp = Invoke-WebRequest -UseBasicParsing -Uri $url -TimeoutSec 3
69+
if ($resp.StatusCode -eq 200) {
70+
Write-Host "GET /api/config -> 200 OK"
71+
Write-Host $resp.Content
72+
exit 0
73+
}
74+
} catch {
75+
Start-Sleep -Seconds 2
76+
}
77+
}
78+
Write-Error "Agent never responded on /api/config within 2 minutes"
79+
exit 1
80+
81+
- name: Smoke test /desktop route
82+
shell: pwsh
83+
run: |
84+
$ErrorActionPreference = "Stop"
85+
$url = "http://127.0.0.1:$env:AGENT_PORT/desktop"
86+
$resp = Invoke-WebRequest -UseBasicParsing -Uri $url -TimeoutSec 10
87+
if ($resp.StatusCode -ne 200) {
88+
Write-Error "/desktop returned $($resp.StatusCode)"
89+
exit 1
90+
}
91+
Write-Host "/desktop -> 200 OK ($($resp.Content.Length) bytes)"
92+
93+
- name: Smoke test login (POST /api/pair)
94+
shell: pwsh
95+
run: |
96+
$ErrorActionPreference = "Stop"
97+
98+
$tokenFile = "runtime/agent/app_data/pairing-token.txt"
99+
if (-not (Test-Path $tokenFile)) {
100+
Write-Error "pairing-token.txt missing — agent never initialized session store"
101+
exit 1
102+
}
103+
$token = (Get-Content $tokenFile -Raw).Trim()
104+
Write-Host "Pairing token: $token"
105+
106+
$url = "http://127.0.0.1:$env:AGENT_PORT/api/pair"
107+
108+
# 1. Wrong token -> 401
109+
try {
110+
$bad = Invoke-WebRequest -UseBasicParsing -Uri $url -Method POST `
111+
-ContentType "application/json" `
112+
-Body '{"token":"wrong-token"}' -TimeoutSec 5
113+
Write-Error "Wrong token should have failed, got $($bad.StatusCode)"
114+
exit 1
115+
} catch {
116+
if ($_.Exception.Response.StatusCode.value__ -ne 401) {
117+
Write-Error "Wrong token expected 401, got $($_.Exception.Response.StatusCode.value__)"
118+
exit 1
119+
}
120+
Write-Host "Wrong token -> 401 (as expected)"
121+
}
122+
123+
# 2. Correct token -> 200 { ok: true }
124+
$body = @{ token = $token } | ConvertTo-Json -Compress
125+
$ok = Invoke-WebRequest -UseBasicParsing -Uri $url -Method POST `
126+
-ContentType "application/json" `
127+
-Body $body -TimeoutSec 5
128+
if ($ok.StatusCode -ne 200) {
129+
Write-Error "/api/pair returned $($ok.StatusCode)"
130+
exit 1
131+
}
132+
Write-Host "/api/pair -> 200 OK: $($ok.Content)"
133+
134+
- name: Run unit tests
135+
shell: pwsh
136+
run: npm test
137+
138+
- name: Stop agent
139+
if: always()
140+
shell: pwsh
141+
run: |
142+
$pidFile = "runtime/agent/agent.pid"
143+
if (Test-Path $pidFile) {
144+
$agentPid = (Get-Content $pidFile -Raw).Trim()
145+
try {
146+
Stop-Process -Id $agentPid -Force -ErrorAction Stop
147+
Write-Host "Stopped agent PID $agentPid"
148+
} catch {
149+
Write-Host "Agent PID $agentPid already gone"
150+
}
151+
}
152+
153+
- name: Upload agent log
154+
if: always()
155+
uses: actions/upload-artifact@v4
156+
with:
157+
name: agent-log
158+
path: |
159+
runtime/agent/agent.log
160+
runtime/agent/agent.port
161+
runtime/agent/agent.pid
162+
if-no-files-found: warn

0 commit comments

Comments
 (0)