feat: launch Windows runner in interactive desktop session (WARP-849)#77
feat: launch Windows runner in interactive desktop session (WARP-849)#77PrashantRaj18198 wants to merge 2 commits into
Conversation
Windows jobs were running in Session 0 (the service session) with no window station, blocking UI/GUI workloads (Selenium, WinAppDriver, MAUI/WinUI). The agent now launches the runner into the active interactive desktop (Session 1, winsta0\default) via WTSQueryUserToken + CreateProcessAsUser, mirroring how GitHub-hosted runners work. Prereq (tracked separately): the AMI/cloud-init must ensure a real interactive logon exists in session 1 (Sysinternals Autologon to survive Sysprep, or a post-Sysprep EC2Launch re-stamp of the Winlogon keys). Without that, StartRunner now fails loudly instead of silently running in Session 0. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
So the WARP-849 agent change ships to R2 and is picked up by the testing AMI/cloud-init for end-to-end verification of the interactive session launch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit ada3ebd. Configure here.
| stdoutW.Close() | ||
| stderrW.Close() | ||
| stdinR.Close() | ||
| _ = windows.DestroyEnvironmentBlock(envBlockPtr) |
There was a problem hiding this comment.
Wrong free on merged env block
High Severity
After merging overlay variables, buildEnvironmentBlock returns a pointer into a Go-allocated UTF-16 slice, but startInteractiveProcess still calls DestroyEnvironmentBlock on that pointer. That API is only valid for blocks from CreateEnvironmentBlock. Normal startup always uses a non-empty overlay (e.g. WARPBUILD_GH_JIT_TOKEN), so this path runs on every launch.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit ada3ebd. Configure here.


Summary
What changed
Prereq (not in this PR)
This change is the agent half. It assumes a real interactive logon exists in Session 1. Today that's flaky because Sysprep strips the `DefaultPassword` from the Winlogon registry. Companion AMI/cloud-init work needed:
Without A.1 or A.2, `WTSQueryUserToken` returns no token and `StartRunner` errors out — loud failure instead of silent Session-0 fallback.
Test plan
🤖 Generated with Claude Code
Note
Medium Risk
Moderate risk: replaces Windows runner process-launching with
CreateProcessAsUser/session-token logic and custom stdio piping, which can fail in environments without an active interactive logon and impacts job execution behavior on Windows.Overview
Enables Windows UI/GUI workloads by changing the
github_windows_criprovider to start the runner inside the active interactive session (winsta0\default) instead of the service Session 0 context, using WTS session enumeration, user token duplication, environment block creation/merge, andCreateProcessAsUserwith pipe-forwarded stdout/stderr.Splits the manager into OS-specific files: a
!windowsstub that returns a clear "Windows only" error for cross-builds/tests, and a newwindowsimplementation containing the full start logic and cleanup/cancellation handling.Also updates
release-testingworkflow triggers to include theprashant-warp-849branch so artifacts can be built and uploaded to R2 for validation.Reviewed by Cursor Bugbot for commit ada3ebd. Configure here.