ros-industrial/industrial_ci: ROS/ROS2 CI Pipeline Library

Research Question

What does ros-industrial/industrial_ci do, what are its key features, and how do you integrate it into a ROS2 CI pipeline?

Knowledge Map

  • ROS2 build system (colcon) — industrial_ci delegates all building and testing to colcon for ROS2; understanding colcon workspaces and overlay/underlay structure explains why UPSTREAM_WORKSPACE exists
  • Docker — all CI runs inside Docker containers; knowing how ROS Docker images are layered explains the DOCKER_IMAGE override and why environment isolation matters
  • GitHub Actions matrix strategy — the idiomatic way to use industrial_ci is a matrix over ROS_DISTRO; without matrix knowledge you’ll miss the multi-distro testing pattern
  • rosdep — dependency resolution is rosdep-driven inside the container; ROSDEP_SKIP_KEYS is only meaningful if you understand what rosdep resolves
  • catkin vs colcon — industrial_ci auto-selects the builder by ROS generation; knowing the distinction clarifies why the same YAML works for ROS1 and ROS2

Sources Gathered

New sources clipped and analyzed during this research:

Existing vault notes referenced:

Key Findings

  1. One-line adoption: industrial_ci is consumed as a GitHub Actions action (uses: ros-industrial/industrial_ci@master) or cloned repo. No per-project CI scripting required.

  2. Docker-native isolation: every job runs in an official ROS Docker image. The build environment is reproducible across developer machines, CI, and releases. Custom images are supported via DOCKER_IMAGE.

  3. Multi-distro matrix is the standard pattern: the intended usage is a strategy.matrix over ROS_DISTRO values (e.g., humble + jazzy), giving parallel jobs for each distribution per push.

  4. Cross-repo dependency testing via workspaces: UPSTREAM_WORKSPACE lets you declare unreleased dependencies (via .repos file or GitHub URL) that get cloned and built before the target package. DOWNSTREAM_WORKSPACE runs packages that depend on yours, catching regressions upstream changes cause downstream.

  5. Code quality is first-class: clang-format, clang-tidy, pylint, and black checks are toggled with env vars and fail the CI job — no separate linting workflow needed.

  6. Alternative: ros-tooling/action-ros-ci (from Open Robotics) is a leaner alternative focused purely on ROS2 and GitHub Actions, without the multi-platform history. industrial_ci has broader platform coverage and deeper configuration.

Open Questions

  • How does industrial_ci handle ROS2 packages with Python-only nodes (no colcon C++ compilation)? Does PYLINT_CHECK integrate cleanly with ament_flake8?
  • Is the ABICHECK_URL feature actively used by the community, or is it mostly for official ROS-Industrial releases?
  • How does industrial_ci interact with rosdep when UPSTREAM_WORKSPACE contains packages not in the rosdep index?

Report

What industrial_ci Is

ros-industrial/industrial_ci is a shared CI library for the ROS ecosystem, maintained by the ROS-Industrial consortium. The problem it solves: every ROS package needs essentially the same CI pipeline — clone dependencies, build with colcon/catkin, run tests, optionally lint. Without a shared library, every package author writes their own GitHub Actions YAML, diverging over time and lacking features.

industrial_ci centralizes this into a single reusable action. A package author adds one uses: line and sets ROS_DISTRO; everything else is handled.

How It Works

All CI logic runs inside Docker. When triggered, the action:

  1. Pulls the appropriate ROS Docker image (or a custom one via DOCKER_IMAGE)
  2. Installs ADDITIONAL_DEBS if specified
  3. Clones and builds UPSTREAM_WORKSPACE packages (unreleased deps)
  4. Builds the target workspace with colcon (ROS2) or catkin_tools (ROS1)
  5. Runs all registered tests (colcon test)
  6. Optionally builds and tests DOWNSTREAM_WORKSPACE packages
  7. Optionally runs clang-format/tidy, pylint, black checks
  8. Optionally runs the official ROS prerelease test suite

Minimal ROS2 Setup

# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        env:
          - ROS_DISTRO: humble
          - ROS_DISTRO: jazzy
    steps:
      - uses: actions/checkout@v4
      - uses: ros-industrial/industrial_ci@master
        env: ${{ matrix.env }}

This gives parallel jobs for Humble and Jazzy on every push and PR. No other configuration needed for a standard package.

Important Configuration Patterns

Testing with unreleased dependencies:

env:
  ROS_DISTRO: humble
  UPSTREAM_WORKSPACE: https://raw.githubusercontent.com/your-org/deps/main/deps.repos

Adding static analysis:

env:
  ROS_DISTRO: humble
  CLANG_FORMAT_CHECK: true
  CLANG_TIDY: true
  PYLINT_CHECK: true

Custom Docker image (e.g., with CUDA):

env:
  DOCKER_IMAGE: nvidia/cuda:12.3-ros-humble
  # ROS_DISTRO can be omitted if the image sets it

Speed up rebuilds with ccache:

env:
  ROS_DISTRO: humble
  CCACHE_DIR: /github/home/.ccache

When to Use industrial_ci vs action-ros-ci

Criterionindustrial_ciros-tooling/action-ros-ci
Platform supportGitHub, GitLab, Bitbucket, TravisGitHub Actions only
ROS1 supportYesNo
Configuration depthHigh (30+ env vars)Lower
CommunityROS-Industrial consortiumOpen Robotics tooling WG
Learning curveModerateLow

For ROS2-only, GitHub Actions-only projects, action-ros-ci is simpler. For multi-platform CI, ROS1+ROS2 packages, or packages needing ABI checks and downstream testing, industrial_ci is the better choice.


中文版

研究問題

ros-industrial/industrial_ci 是什麼、有哪些關鍵功能,以及如何整合到 ROS2 CI 流水線中?

知識地圖

  • colcon 建置系統 — industrial_ci 的 ROS2 建置與測試完全委派給 colcon
  • Docker — 所有 CI 在 Docker 容器內執行,環境與本機完全隔離
  • GitHub Actions matrix strategy — 標準用法是以 ROS_DISTRO 為維度建立 matrix,同時測試多個發行版
  • rosdep — 容器內的依賴解析由 rosdep 驅動
  • catkin vs colcon — industrial_ci 依 ROS 世代自動選擇建置工具

關鍵發現

  1. 一行整合:只需 uses: ros-industrial/industrial_ci@master,無需撰寫 CI 腳本。
  2. Docker 原生隔離:建置環境與官方 ROS Docker 映像完全一致,可重現。
  3. 多發行版 matrix 是標準做法:每次 push 同時測試 Humble + Jazzy。
  4. 跨 repo 依賴測試UPSTREAM_WORKSPACE 允許宣告未發布的依賴,DOWNSTREAM_WORKSPACE 測試下游套件是否受影響。
  5. 程式碼品質內建:clang-format、clang-tidy、pylint、black 直接作為 CI 失敗條件。

未解問題

  • PYLINT_CHECK 與 ROS2 的 ament_flake8 如何協作?
  • ABICHECK_URL 在社群中的實際使用率如何?

報告

industrial_ci 是 ROS-Industrial 聯盟維護的共用 CI 函式庫,解決每個 ROS 套件需要重寫相似 CI 流水線的問題。採用方式極簡:加一行 uses:,設定 ROS_DISTRO,其餘由 industrial_ci 處理。

執行流程:拉取 ROS Docker 映像 → 安裝額外 apt 套件 → 建置上游依賴 → 建置目標套件 → 執行測試 → 可選靜態分析與 prerelease 測試。

ros-tooling/action-ros-ci 相比,industrial_ci 支援更多 CI 平台、同時支援 ROS1/ROS2、設定選項更豐富,適合需要跨平台或深度配置的專案。純 ROS2 + GitHub Actions 的小型專案可考慮 action-ros-ci 作為更輕量的替代方案。