A working example: PX4 SITL running in CI on a free GitHub-hosted runner. No simulation service, no self-hosted runner, nothing to build.
The workflow pulls a pinned PX4 + Gazebo image, waits for a MAVLink heartbeat, flies an arm-takeoff-land smoke test, and uploads the flight log as a workflow artifact. The badge above is this repository running it.
The guide explains every part of this, and the limits: https://hangars.dev/guides/px4-sitl-github-actions
| Path | What it does |
|---|---|
.github/workflows/sitl.yml |
The whole job. |
tests/wait_for_heartbeat.py |
Blocks until PX4 announces itself on UDP 14540. |
tests/smoke_test.py |
Arms, climbs to 5 m, holds, lands. Exits non-zero on failure. |
Fork this repository, or copy the three files into one you already have. The workflow needs nothing configured: no secrets, no runner setup.
Replace tests/smoke_test.py with your own mission once it passes.
Measured on ubuntu-latest (2 cores, 7 GiB RAM) on 22 September 2026:
- A run takes about three minutes. Most of that is pulling the 3.3 GB image.
- Simulated time runs at about 0.89 of real time, so budget CI timeouts in wall-clock terms with headroom.
- One vehicle per job. PX4 supports multi-vehicle SITL, but this image does not configure the per-instance IDs and ports it needs by default.
The guide has the full numbers and how they were measured.
MIT. See LICENSE.