# CI / CD Pipeline **Status**: forward-looking design (Rust). Final pipeline file lands during build-system bring-up. The shape below describes the intent. ## 1. Goals The pipeline must: - Build the autopilot Rust binary cross-compiled for `aarch64-unknown-linux-gnu`. - Run the full Rust test suite (unit + integration + replay-based) on every commit. - Run a hardware-in-loop conformance gate against an ArduPilot SITL instance (covers `mavlink_layer` + `mission_executor`). - Run a benchmark gate on representative target hardware (covers Tier 1 / Tier 2 / VLM / gimbal latency budgets — see `architecture.md §7.6 Benchmark gate`). - Sign and publish artefacts (binary + container image) on tagged releases. - Never auto-deploy to the airframe. Deployment is a human-driven operation tied to the suite's flight-gate convention (`/run/azaion/in-flight`). ## 2. Pipeline stages Single Woodpecker pipeline, multi-stage. Stages run sequentially; a failed stage stops the run. | Stage | Purpose | Notes | |---|---|---| | **fetch** | Clone, restore Cargo cache | `cargo fetch` with a remote cache key. | | **lint** | `cargo fmt --check`, `cargo clippy --all-targets --all-features -- -D warnings` | Hard fail on any warning. | | **unit-test** | `cargo test --workspace` (host-arch) | Most logic is platform-independent; runs in parallel on host. | | **build-arm64** | Cross-compile for `aarch64-unknown-linux-gnu` | `cross` or `cargo zigbuild` depending on Rust toolchain. Produces the production binary + a debug symbol artefact. | | **integration-test** | Replay-based integration tests under emulation | Fixtures: pre-recorded RTSP clip, MAVLink replay, synthetic telemetry. No hardware required. | | **sitl-conformance** | ArduPilot SITL conformance gate | Spins up ArduPilot SITL + autopilot binary in a container; runs a fixed mission script; asserts MAVLink command surface (per `architecture.md §7.7`) and geofence enforcement. | | **benchmark-gate** *(opt-in, manual / nightly)* | Tier 1 / 2 / VLM / gimbal latency on real Jetson | Runs on a self-hosted Jetson Orin Nano runner. Asserts `architecture.md §6 NFR` budgets. Slow; not on every PR. | | **package** | Build container image (Option B from `containerization.md`) | Multi-arch tag: `azaion/autopilot:-arm64`. | | **sign** | Sign binary + image | Cosign for the image; OS-vendor signing flow for the binary if used in native deployment. | | **publish** | Push image + binary to internal registry | Tagged builds only. | ## 3. Artefacts | Artefact | Where | Retention | |---|---|---| | `autopilot` binary (aarch64) | internal artefact store | last 10 builds per branch; tagged builds kept indefinitely | | Debug symbols (`.dwp`) | internal artefact store, separate path | matched to binary lifetime | | Container image | internal Docker registry | last 10 dev builds; tagged builds kept indefinitely | | Cosign signature | next to image | matched to image lifetime | | Test logs | CI run | per Woodpecker retention | | Benchmark gate report | internal artefact store (Markdown + JSON) | per-tag retention | ## 4. Build matrix Single matrix entry today: | Toolchain | Target | Tier-1 dep | VLM feature | |---|---|---|---| | Rust stable | `aarch64-unknown-linux-gnu` | `../detections` (Cython service consumed via gRPC; not built here) | `cargo --features vlm` (also `cargo` without — both must build) | The `--features vlm` and the no-feature path are both built and tested to enforce the optionality contract from `architecture.md §7.6 Local VLM confirmation`. ## 5. SITL conformance gate (in detail) Stage runs in CI; produces a pass/fail signal that gates merge to `dev`. **Setup:** 1. Start ArduPilot SITL in a container, listening on `udp://0.0.0.0:14550`. 2. Start autopilot binary configured for SITL endpoint. 3. Pre-load a fixture mission via the missions API mock (`mission_client` HTTP target). 4. Pre-load a fixture RTSP source (looped clip). 5. Mock the `../detections` service with deterministic detections. **Assertions:** - All MAVLink message kinds in `architecture.md §7.7` succeed at least once. - Mission upload + start completes within the configured retry budget. - INCLUSION geofence violation triggers RTL. - EXCLUSION geofence violation triggers RTL (regression gate against the earlier silent-ignore behaviour). - Middle-waypoint POST + re-upload succeeds within ≤2 s. - Health endpoint returns `green` once steady state is reached. ## 6. Branch policy | Branch | Triggers | Required gates | |---|---|---| | feature branches (PR) | on push | fetch → lint → unit-test → build-arm64 → integration-test → sitl-conformance | | `dev` | on merge | all PR gates + package | | tagged release (`v*`) | on tag | all `dev` gates + sign + publish + benchmark-gate (manual approval) | `main` and `dev` are protected. Force-push is forbidden. Merges require a green pipeline. ## 7. Out of scope here - Airframe deployment automation (manual; tied to flight-gate). - Ground Station and `../detections` pipelines (each owns its own). - AI training pipeline — `../_docs/12_ai_training.md`. - Model-sync to the airframe (`model-sync.service`, suite-level — `../_docs/00_top_level_architecture.md`).