Context

Discord discussion on how to use GitLab CI to verify a ROS2 package repo (Python + C++) builds correctly on both x86 and ARM Docker containers.

Key Insights

  • GitLab.com has native arm64 shared runners — use tags: [saas-linux-small-arm64] and tags: [saas-linux-small-amd64]. No QEMU or dind needed for build verification.
  • ros:humble-ros-base is a multi-arch manifest — same image tag works for amd64 and arm64; Docker automatically pulls the correct variant based on runner architecture. Confirmed via Docker Hub: https://hub.docker.com/_/ros/
  • dind is only required when you need to operate the Docker daemon itself (e.g., docker build, docker push, docker-compose, docker buildx). For colcon build inside a ROS image, just use image: directly.
  • ROS2 Python packages use package.xml + rosdep, not requirements.txt — declare deps as <depend>python3-numpy</depend>, then rosdep install --from-paths src --ignore-src -r -y. Only fall back to pip for packages absent from the rosdep DB.
  • Checking rosdep availability: run rosdep resolve <pkg> locally, or search github.com/ros/rosdistro/blob/master/rosdep/python.yaml directly.
  • package.xml version constraints (version_gte, version_lt, etc.) exist syntactically but apt does not enforce them — use requirements.txt + pip if strict version pinning is needed.
  • Probing self-hosted GitLab runner architecture: run a job with uname -m to detect arch without admin access. x86_64 = amd64, aarch64 = arm64.

Minimal CI Template

build-amd64:
  image: ros:humble-ros-base
  tags: [saas-linux-small-amd64]
  script:
    - rosdep init && rosdep update
    - rosdep install --from-paths src --ignore-src -r -y
    - colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release
 
build-arm64:
  image: ros:humble-ros-base
  tags: [saas-linux-small-arm64]
  script:
    - rosdep init && rosdep update
    - rosdep install --from-paths src --ignore-src -r -y
    - colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release

Connections