Skip to content

Commit 6334600

Browse files
committed
refactor: manage CI using nix
1 parent 1062add commit 6334600

5 files changed

Lines changed: 429 additions & 337 deletions

File tree

.github/workflows/ci.yml

Lines changed: 21 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ on:
77
branches: [ main ]
88

99
jobs:
10-
no-ros:
11-
name: ROS-independent Test
10+
nix-matrix:
11+
name: Generate Nix CI Matrix
1212
runs-on: ubuntu-latest
13-
13+
outputs:
14+
matrix: ${{ steps.set-matrix.outputs.matrix }}
1415
steps:
1516
- name: Checkout repository
1617
uses: actions/checkout@v4
@@ -23,63 +24,22 @@ jobs:
2324
experimental-features = nix-command flakes
2425
accept-flake-config = true
2526
26-
- name: Setup sccache
27-
if: env.ACT != 'true'
28-
uses: mozilla-actions/sccache-action@v0.0.9
29-
30-
- name: Check Nix formatting
31-
run: |
32-
nix fmt -- --check flake.nix
33-
34-
- name: Check Markdown formatting
35-
run: |
36-
nix develop '.#noRos-ci' -c markdownlint '**/*.md'
37-
38-
- name: Check Rust formatting
39-
run: |
40-
nix develop '.#noRos-ci' -c cargo fmt --all -- --check
41-
42-
- name: Clippy (default workspace)
43-
run: |
44-
nix develop '.#noRos-ci' -c cargo clippy --lib --bins --tests -- -D warnings
45-
46-
- name: Check default workspace
47-
run: |
48-
nix develop '.#noRos-ci' -c cargo check
49-
50-
- name: Build default workspace
51-
run: |
52-
nix develop '.#noRos-ci' -c cargo build
53-
54-
- name: Build examples without ROS dependencies
55-
run: |
56-
nix develop '.#noRos-ci' -c cargo build --examples
57-
58-
- name: Run tests
59-
run: |
60-
nix develop '.#noRos-ci' -c cargo test
61-
62-
- name: Check ros-z-msgs with bundled messages (no ROS required)
63-
run: |
64-
nix develop '.#noRos-ci' -c cargo check -p ros-z-msgs
65-
nix develop '.#noRos-ci' -c cargo check -p ros-z-msgs --features bundled_msgs
66-
nix develop '.#noRos-ci' -c cargo check -p ros-z-msgs --features common_interfaces
27+
- name: Setup Magic Nix Cache
28+
uses: DeterminateSystems/magic-nix-cache-action@v8
6729

68-
- name: Build ros-z-msgs with individual bundled packages
30+
- name: Generate CI matrix from flake
31+
id: set-matrix
6932
run: |
70-
nix develop '.#noRos-ci' -c cargo build -p ros-z-msgs --no-default-features --features std_msgs
71-
nix develop '.#noRos-ci' -c cargo build -p ros-z-msgs --no-default-features --features geometry_msgs
72-
nix develop '.#noRos-ci' -c cargo build -p ros-z-msgs --no-default-features --features sensor_msgs
73-
nix develop '.#noRos-ci' -c cargo build -p ros-z-msgs --no-default-features --features nav_msgs
33+
set -euo pipefail
34+
matrix="$(nix eval --json '.#githubActions.matrix')"
35+
echo "matrix=$matrix" >> "$GITHUB_OUTPUT"
7436
75-
with-ros:
76-
name: ROS-dependent Test (${{ matrix.distro }})
37+
nix-build:
38+
name: ${{ matrix.attr }}
39+
needs: nix-matrix
7740
runs-on: ubuntu-latest
7841
strategy:
79-
matrix:
80-
distro: [jazzy]
81-
# distro: [jazzy, rolling] # Uncomment to test rolling when stable
82-
42+
matrix: ${{fromJSON(needs.nix-matrix.outputs.matrix)}}
8343
steps:
8444
- name: Checkout repository
8545
uses: actions/checkout@v4
@@ -99,48 +59,11 @@ jobs:
9959
with:
10060
name: ros
10161
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
102-
skipPush: true
103-
104-
- name: Setup sccache
105-
if: env.ACT != 'true'
106-
uses: mozilla-actions/sccache-action@v0.0.9
107-
108-
- name: Check rcl-z
109-
run: |
110-
nix develop '.#${{ matrix.distro }}-ci' -c cargo check -p rcl-z
111-
112-
- name: Check ros-z-msgs (default bundled features)
113-
run: |
114-
nix develop '.#${{ matrix.distro }}-ci' -c cargo check -p ros-z-msgs
115-
116-
- name: Check ros-z-msgs with external messages
117-
run: |
118-
nix develop '.#${{ matrix.distro }}-ci' -c cargo check -p ros-z-msgs --features external_msgs
119-
nix develop '.#${{ matrix.distro }}-ci' -c cargo check -p ros-z-msgs --features example_interfaces
62+
# Push build outputs to cachix for reuse
63+
skipPush: false
12064

121-
- name: Check ros-z-msgs with all messages (bundled + external)
122-
run: |
123-
nix develop '.#${{ matrix.distro }}-ci' -c cargo check -p ros-z-msgs --features all_msgs
124-
125-
- name: Check with protobuf feature
126-
run: |
127-
nix develop '.#${{ matrix.distro }}-ci' -c cargo check -p ros-z -p ros-z-msgs --features ros-z/protobuf,ros-z-msgs/protobuf
128-
129-
- name: Check ros-z (with rcl-z feature)
130-
run: |
131-
nix develop '.#${{ matrix.distro }}-ci' -c cargo check -p ros-z --features rcl-z
132-
133-
- name: Build ROS message examples
134-
run: |
135-
nix develop '.#${{ matrix.distro }}-ci' -c cargo build -p ros-z-msgs
136-
nix develop '.#${{ matrix.distro }}-ci' -c cargo build --examples
137-
nix develop '.#${{ matrix.distro }}-ci' -c cargo build --example z_srvcli --features external_msgs
138-
139-
- name: Build protobuf demo
140-
run: |
141-
nix develop '.#${{ matrix.distro }}-ci' -c cargo build -p protobuf_demo
65+
- name: Setup Magic Nix Cache
66+
uses: DeterminateSystems/magic-nix-cache-action@v8
14267

143-
# FIXME: This requires the installation of rmw_zenoh_cpp triggering a build from source...
144-
# - name: Run unit tests
145-
# run: |
146-
# nix develop .#ci -c cargo test --all-features
68+
- name: Run check
69+
run: nix build -L '.#${{ matrix.attr }}'

ci.nix

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# CI checks module
2+
# This module defines all CI checks for ros-z project
3+
{
4+
pkgs,
5+
self,
6+
commonBuildInputs,
7+
mkRosEnv,
8+
exportEnvVars,
9+
}:
10+
let
11+
# Vendor Cargo dependencies for sandboxed builds
12+
cargoVendorDir = pkgs.rustPlatform.importCargoLock {
13+
lockFile = ./Cargo.lock;
14+
outputHashes = {
15+
"cdr-encoding-0.10.2" = "sha256-bpo8Fu3Qp5TapzFFAvyRJdSiO50G3YBBTSJNV/cNa4Y=";
16+
"roslibrust-0.16.0" = "sha256-qi4h1ksC/iLwK1uiUs6LU9CX3RDYVOd6E4SRdUAbqZo=";
17+
};
18+
};
19+
20+
# Fetch roslibrust git repo for assets directory (with submodules for ros2_common_interfaces)
21+
roslibrustSrc = pkgs.fetchgit {
22+
url = "https://github.com/YuanYuYuan/roslibrust";
23+
rev = "f08547babb04c3b19a77af9a55a10b8148908e55"; # dev/ros-z branch
24+
hash = "sha256-qi4h1ksC/iLwK1uiUs6LU9CX3RDYVOd6E4SRdUAbqZo=";
25+
fetchSubmodules = true;
26+
};
27+
in
28+
let
29+
# Create a cargo check that runs in sandbox with vendored dependencies
30+
mkCargoCheck =
31+
{
32+
name,
33+
packages,
34+
rosEnv ? null,
35+
script,
36+
extraAttrs ? { },
37+
}:
38+
pkgs.stdenv.mkDerivation (
39+
{
40+
name = "check-${name}";
41+
src = self;
42+
nativeBuildInputs = packages ++ [ pkgs.nixfmt-rfc-style ]; # For format checks
43+
buildInputs = pkgs.lib.optional (rosEnv != null) rosEnv;
44+
45+
# Disable ROS setup hooks that interfere with Cargo builds
46+
dontUseCmakeConfigure = true;
47+
dontUseColconBuildSetup = true;
48+
49+
buildPhase = ''
50+
# Export environment variables
51+
${exportEnvVars}
52+
53+
# Disable sccache in sandbox (no HOME directory)
54+
unset RUSTC_WRAPPER
55+
56+
# Setup ROS environment if provided
57+
${pkgs.lib.optionalString (rosEnv != null) ''
58+
export AMENT_PREFIX_PATH="${rosEnv}"
59+
export CMAKE_PREFIX_PATH="${rosEnv}"
60+
''}
61+
62+
# Setup vendored cargo dependencies
63+
export CARGO_HOME=$(pwd)/.cargo
64+
mkdir -p .cargo
65+
cat > .cargo/config.toml <<EOF
66+
[source.crates-io]
67+
replace-with = "vendored-sources"
68+
69+
[source."https://github.com/YuanYuYuan/cdr-encoding"]
70+
git = "https://github.com/YuanYuYuan/cdr-encoding"
71+
branch = "feat/byte-buf"
72+
replace-with = "vendored-sources"
73+
74+
[source."https://github.com/YuanYuYuan/roslibrust"]
75+
git = "https://github.com/YuanYuYuan/roslibrust"
76+
branch = "dev/ros-z"
77+
replace-with = "vendored-sources"
78+
79+
[source.vendored-sources]
80+
directory = "${cargoVendorDir}"
81+
EOF
82+
83+
# Point build.rs to roslibrust assets from fetched git repo
84+
export ROSLIBRUST_ASSETS_DIR="${roslibrustSrc}/assets"
85+
86+
# Run checks
87+
set -euo pipefail
88+
${script}
89+
'';
90+
91+
installPhase = ''
92+
touch $out
93+
'';
94+
95+
# Disable hardening for ROS compatibility
96+
hardeningDisable = [ "all" ];
97+
}
98+
// extraAttrs
99+
);
100+
in
101+
let
102+
# Formatting check - runs first and other checks depend on this
103+
formatting = mkCargoCheck {
104+
name = "formatting";
105+
packages = commonBuildInputs;
106+
script = ''
107+
echo "=== Nix Formatting ==="
108+
nixfmt --check flake.nix
109+
110+
echo "=== Markdown Linting ==="
111+
markdownlint '**/*.md'
112+
113+
echo "=== Rust Formatting ==="
114+
cargo fmt --all -- --check
115+
'';
116+
};
117+
118+
# ROS-independent checks (linting, build, test)
119+
no-ros = mkCargoCheck {
120+
name = "no-ros";
121+
packages = commonBuildInputs;
122+
script = ''
123+
# This check depends on formatting passing first
124+
# Reference the formatting check to create a build-time dependency
125+
echo "Prerequisites: ${formatting}"
126+
127+
echo "=== Build & Test ==="
128+
cargo build --workspace --lib --bins --exclude rcl-z --exclude protobuf_demo
129+
cargo test --workspace --lib --bins --exclude rcl-z --exclude protobuf_demo
130+
131+
echo "=== Lint ==="
132+
cargo clippy --workspace --lib --bins --exclude rcl-z -- -D warnings
133+
134+
echo "=== Message Package Checks ==="
135+
cargo check -p ros-z-msgs
136+
cargo check -p ros-z-msgs --features bundled_msgs
137+
cargo check -p ros-z-msgs --features common_interfaces
138+
139+
echo "=== Individual Message Packages ==="
140+
cargo build -p ros-z-msgs --no-default-features --features std_msgs
141+
cargo build -p ros-z-msgs --no-default-features --features geometry_msgs
142+
cargo build -p ros-z-msgs --no-default-features --features sensor_msgs
143+
cargo build -p ros-z-msgs --no-default-features --features nav_msgs
144+
'';
145+
};
146+
147+
# ROS-dependent checks for Jazzy distribution
148+
with-ros-jazzy = mkCargoCheck {
149+
name = "with-ros-jazzy";
150+
packages = commonBuildInputs;
151+
rosEnv = (mkRosEnv "jazzy").build;
152+
script = ''
153+
# This check depends on formatting passing first
154+
# Reference the formatting check to create a build-time dependency
155+
echo "Prerequisites: ${formatting}"
156+
157+
echo "=== RCL Bindings ==="
158+
cargo check -p rcl-z
159+
160+
echo "=== Message Packages ==="
161+
cargo check -p ros-z-msgs
162+
cargo check -p ros-z-msgs --features external_msgs
163+
cargo check -p ros-z-msgs --features example_interfaces
164+
cargo check -p ros-z-msgs --features all_msgs
165+
166+
echo "=== Feature Checks ==="
167+
cargo check -p ros-z -p ros-z-msgs --features ros-z/protobuf,ros-z-msgs/protobuf
168+
cargo check -p ros-z --features rcl-z
169+
170+
echo "=== Build Examples ==="
171+
cargo build -p ros-z-msgs
172+
cargo build --examples
173+
cargo build --example z_srvcli --features external_msgs
174+
cargo build -p protobuf_demo
175+
'';
176+
};
177+
in
178+
{
179+
# Export all checks
180+
inherit formatting no-ros with-ros-jazzy;
181+
}

flake.lock

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)