ROS 2 Windows CI on GitHub Actions: current options and a Pixi-based pattern

I’m trying to understand what we should currently recommend for ROS 2 projects that want to run a real Windows CI job on GitHub Actions, including both build and tests.

There are several existing actions and examples, but their Windows behavior is somewhat different from Linux. I recently compared a few approaches with ROS 2 Lyrical in a small AI-assisted smoke-test repository, and thought it might be useful to summarize what I found and ask whether there is already a preferred approach.

What I found

action-ros-ci

action-ros-ci@v0.4 currently has:

const doTests = !isWindows;

so colcon test is intentionally skipped on Windows. The related background seems to be ros-tooling/action-ros-ci#712.

This makes it useful for some Windows build jobs, but not for CI whose purpose is explicitly to verify tests.

setup-ros

I also tried setup-ros@v0.7 with Lyrical.

In this experiment, it selected the April 30 Lyrical beta binary and ended up combining the GitHub-hosted Python 3.12 environment with an older colcon/Python toolchain.

That caused plugin-loading errors involving removed Python APIs such as pkgutil.ImpImporter and distutils. More importantly, the job still completed successfully with effectively:

Summary: 0 packages finished
...
Summary: 0 tests, 0 errors, 0 failures, 0 skipped

This may be specific to this Lyrical configuration, and I may be missing an intended version pin or setup. However, the false-green result seems worth being aware of.

Pinned ROS 2 binary + Pixi

The approach that worked most consistently in my experiment was:

  1. Download a known ROS 2 Windows binary release.

  2. Use the pixi.toml provided with the ROS 2 source/release environment.

  3. Run pixi install.and preinstall_setup_windows.py.

  4. Enter the Visual Studio developer environment and source ROS 2.

  5. Run colcon build, colcon test, and colcon test-result explicitly.

For example, this workflow uses the 2026-08-07 Lyrical Windows binary and successfully runs launch tests against Fast DDS, Cyclone DDS, and Zenoh.

There are also existing Windows CI examples with a similar shape:

They are not exactly equivalent use cases—the ros-controls workflow, for example, is primarily a build workflow—but they suggest that using the ROS binary environment together with Pixi is already a practical pattern.

Possible recommendation?

For ROS 2 distributions that provide/support the Pixi environment, I wonder whether the current practical recommendation could be something along these lines:

Download a known ROS 2 Windows binary, reproduce its dependency environment with Pixi, and run colcon build/test explicitly.

It has the advantage that the dependency environment stays close to the one used for the ROS 2 binary itself, while the workflow remains explicit about whether tests are actually executed.

One additional safeguard may be worth recommending regardless of the setup: CI should fail if an expected package or test is not discovered. A green Windows job that actually ran zero tests is particularly easy to overlook.

A few questions remain:

  • Is there already a maintained action or reusable workflow that encapsulates this pattern?

  • Is there a recommended way to resolve a stable distro-specific Windows binary rather than hard-coding a dated release URL? For the experiment above I pinned Lyrical 2026-08-07.

  • Is Windows test execution expected to return to action-ros-ci, or is another approach preferred?

  • For distributions that do not provide the Pixi setup, what is the recommended Windows CI environment today?

If there is already a preferred solution, I would be interested in using and documenting that instead. Otherwise, it may be useful to turn the working Pixi-based pattern into a small reusable example so individual projects do not need to rediscover the same Windows setup details.

Related links