Files
PaperClipAI/.github/workflows/runner-windows.yml
T
Devin Foley cdf843371b fix(runner): build on Windows and add a Windows CI lane (#18250)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Paperclip Runner (`packages/paperclip-runner`) runs agent sessions
through a native Rust daemon, `paperclip-runnerd`
> - The daemon builds only for macOS and Linux. On Windows x64
(`x86_64-pc-windows-msvc`), the build stops with one compile error
> - No CI lane builds the daemon on Windows, so new Unix-only code can
break the Windows build again without notice
> - This pull request fixes the compile error and adds a Windows CI lane
for the Rust workspace. It is the first of a series of small pull
requests that port the Runner to Windows
> - The benefit is a Windows build that stays green. Each later pull
request in the series can then prove its Windows behavior in CI

## Linked Issues or Issue Description

Related: https://github.com/paperclipai/paperclip/issues/18142 and
https://github.com/paperclipai/paperclip/pull/18144 port the server and
the development scripts to native Windows. That work does not touch the
Rust Runner.

**What happened?**
On Windows x64 with the pinned Rust 1.97.1 MSVC toolchain, `cargo build
--manifest-path packages/paperclip-runner/runner/Cargo.toml --locked
--workspace` fails with `error[E0599]: no method named inherited_command
found` in `process_supervisor.rs`. `VerifiedProcessLaunch::spawn_stdio`
calls `inherited_command`, but that method exists only on Linux and
macOS.

**Expected behavior**
The Runner workspace builds on Windows x64. Features that do not have a
Windows implementation yet fail with a clear error at run time. They do
not stop the build.

**Steps to reproduce**
1. Use a Windows x64 host with Visual Studio 2022 Build Tools and
rustup.
2. Check out `master`.
3. Run `cargo build --manifest-path
packages/paperclip-runner/runner/Cargo.toml --locked --workspace`.

**Paperclip version or commit**
`master` at a8e07500db

## What Changed

- `process_supervisor.rs`: compile `VerifiedProcessLaunch::spawn_stdio`
only on Linux and macOS, the same as `inherited_command`. Its only
caller, the stdio MCP proxy, already returns an explicit error on
non-Unix hosts. Linux and macOS behavior does not change.
- New workflow `.github/workflows/runner-windows.yml`: on
`windows-2025`, it installs the pinned toolchain and runs `cargo test
--release --locked --workspace --no-fail-fast` for changes to Runner
Rust inputs. Release mode matches the Linux lane (`test:rust`). In a
debug build on a hosted runner, one recovery test missed its 5-second
deadline. It is a standalone workflow because `pr.yml` runs
`pr-trusted.yml` from `master`, so a lane added there does not run on
the pull request that adds it. The lane has read-only permissions, uses
SHA-pinned actions, and keeps its own Rust cache that only `master`
writes.
- New policy test
`.github/scripts/tests/runner-windows-workflow.test.mjs` for the
workflow triggers, commands, skip list, permissions, and cache.
- 22 tests need verified process launch, which does not exist on Windows
yet. 21 of them are now `#[cfg_attr(windows, ignore = "verified launch
is not supported on Windows yet")]`. The attribute has no effect on
Linux or macOS. The last one is in `acpx_provider_backend.rs`, which is
a Grok profile identity source file. An attribute there would change the
Grok profile identity, so the Windows lane skips that test by exact name
(`--exact --skip`). The policy test fixes the skip list to that one
name. The next pull requests in the series implement verified launch and
remove the attributes and the skip.
- Two test fixtures used Unix-only absolute paths
(`/missing-provider-pack` and `/materialized/skills/...`). These are not
absolute on Windows. On Windows, the fixtures now use a drive-letter
path. The Unix fixtures do not change.

## Verification

- On Windows x64 (Rust 1.97.1 MSVC), the lane's exact release-mode test
command passes: 686 passed, 0 failed, 23 ignored, and 1 test skipped by
name. The test that timed out in a debug build on the hosted runner
takes 3.6 seconds in release mode and 29.5 seconds in debug mode on a
local machine. The ignored tests are the 21 Windows-only ignores and 2
tests that are ignored on every platform. A partial name does not match
with `--exact`, so the skip cannot hide other tests.
- `cargo fmt --manifest-path packages/paperclip-runner/runner/Cargo.toml
--all -- --check` passes.
- `node packages/paperclip-runner/scripts/generate-acpx-profiles.mjs
--check` and `node
packages/paperclip-runner/scripts/grok-profile-identity.mjs --check`
pass. The Grok profile identity does not change.
- `node --test .github/scripts/tests/runner-windows-workflow.test.mjs`
passes.
- The Linux and macOS lanes in this pull request's CI confirm that Unix
behavior does not change.
- The new "Runner Windows" check runs on this pull request.

## Risks

- Low risk. The Rust changes are `cfg` attributes and test fixtures.
Linux and macOS compile the same code as before.
- The new lane adds one Windows job to pull requests that change Runner
Rust inputs. A cold build takes longer than a cached build. After the
first `master` run, pull requests restore the cache.
- The 22 ignored or skipped tests do not run on Windows until verified
launch exists. They still run on Linux and macOS.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- Anthropic Claude Opus 5.5 (`claude-opus-5-5`) in Claude Code, with
tool use (shell, file edits, local builds and tests) and extended
thinking.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-10-30 18:22:47 -07:00

78 lines
3.0 KiB
YAML

name: Runner Windows
# Builds and tests the native Runner on Windows x64. This is a standalone
# workflow because pr.yml runs pr-trusted.yml from master: a lane added there
# would not run on the pull request that adds or changes it.
on:
pull_request:
paths:
- .github/workflows/runner-windows.yml
- packages/paperclip-runner/rust-toolchain.toml
- packages/paperclip-runner/acpx-profiles.json
- packages/paperclip-runner/antigravity-distributions.json
- packages/paperclip-runner/runner/**
- packages/paperclip-runner/protocol/**
- packages/paperclip-runner/test-fixtures/**
- packages/paperclip-runner/test/fixtures/**
- tests/runner-e2e/fixtures/**
push:
branches: [master]
paths:
- .github/workflows/runner-windows.yml
- packages/paperclip-runner/rust-toolchain.toml
- packages/paperclip-runner/acpx-profiles.json
- packages/paperclip-runner/antigravity-distributions.json
- packages/paperclip-runner/runner/**
- packages/paperclip-runner/protocol/**
- packages/paperclip-runner/test-fixtures/**
- packages/paperclip-runner/test/fixtures/**
- tests/runner-e2e/fixtures/**
workflow_dispatch:
permissions: {}
concurrency:
group: runner-windows-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
rust:
name: Runner Rust (Windows x64)
runs-on: windows-2025
timeout-minutes: 60
permissions:
contents: read
defaults:
run:
shell: bash
working-directory: packages/paperclip-runner
env:
CARGO_TERM_COLOR: always
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false
# rust-toolchain.toml pins the channel; install it before rust-cache keys on it.
- name: Install pinned Rust toolchain
run: |
rustup toolchain install
rustup show active-toolchain
# The Linux lanes' caches cannot serve an MSVC build, so this lane keeps its own.
- name: Cache Rust build
uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
with:
workspaces: packages/paperclip-runner/runner -> target
shared-key: runner-windows-v1
# Restore only on pull requests. Never let one evict master's entry.
save-if: ${{ github.event_name == 'push' }}
# Release mode matches the Linux lane (test:rust); some recovery tests
# have deadlines that unoptimized builds miss on hosted runners.
# The skipped test needs verified process launch, which Windows does not
# have yet. Its file is a Grok profile identity source, so a Windows
# ignore attribute there would change that identity.
- name: Test
run: >-
cargo test --release --manifest-path runner/Cargo.toml --locked --workspace --no-fail-fast --
--exact --skip acpx_provider_backend::tests::binds_sidecar_paths_arguments_and_contents_to_the_runner_profile