avatarD

Summary

The website content outlines three methods for implementing Continuous Integration (CI) for Robot Operating System (ROS) packages using GitHub Actions.

Abstract

Continuous Integration (CI) is an essential component of the DevOps workflow, ensuring that code changes are tested and validated before deployment. The provided content details three distinct approaches to set up a CI pipeline for ROS packages within the GitHub Actions environment. The first method involves manually installing ROS and its dependencies, followed by building the ROS package using catkin build. The second method simplifies the process by leveraging the ros-tooling/setup-ros action to install ROS, while the third method encapsulates the entire build process within a Docker container, ensuring a consistent and isolated environment for CI tasks. Each method aims to ensure that the ROS package can be successfully built, which is the primary goal of the CI pipeline in this context.

Opinions

  • The author emphasizes the importance of a minimal CI pipeline that can at least build the ROS package in question.
  • The use of GitHub Actions for CI is preferred due to its integration with GitHub repositories and its ability to automate the workflow.
  • The author suggests that using a Docker container for CI (Method 3) provides a clean and reproducible environment, which can be particularly beneficial for complex ROS packages with specific dependencies.
  • The ros-tooling/setup-ros action (Method 2) is recommended for its ease of use and the efficiency it brings to the ROS installation process during CI.
  • The manual installation method (Method 1) is presented as a more hands-on approach, which might be necessary for custom or non-standard ROS setups.

Continuous Integration for ROS

Continous Integration is part of the Devops workflow where code is pushed into a pipeline that performs a series of tests before embarking on Continous Deployment. The Continous Integration step typically involves some form of testing minimally involving unit tests.

Photo by Andy Kelly on Unsplash

Let’s make it as minimal as possible, in order for a Continous Integration pipeline to ‘pass’ it has to be able to build the current ROS package in question. In order to do this, first create a .github/workflows/CI.yaml file in the github repository.

Method 1:

This ‘manually’ installs ROS into the workspace

name: ROS CI

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-20.04
    env:
      ROS_CI_DESKTOP: "`lsb_release -cs`"
      ROS_DISTRO: noetic
    steps:
      - uses: actions/checkout@v2
        with:
          submodules: recursive
      - name: Download selected private repository dependencies
        run: |
          mkdir -p ~/catkin_ws/src
          cd ~/catkin_ws/src
          ssh-agent sh -c 'echo "${{ secrets.OTHER_ROS_PACKAGE }}" | ssh-add - && git clone [email protected]:Organisation/other-ros-package.git'
      - name: Install ROS
        run: |
            sudo sh -c "echo \"deb http://packages.ros.org/ros/ubuntu $ROS_CI_DESKTOP main\" > /etc/apt/sources.list.d/ros-latest.list"
            sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
            sudo apt-get update -qq
            sudo apt-get install dpkg
            sudo apt-get install -y python3-catkin-pkg
            sudo apt-get install -y python3-catkin-tools
            sudo apt-get install -y python3-osrf-pycommon
            sudo apt-get install -y python3-rosdep
            sudo apt-get install -y python3-wstool
            sudo apt-get install -y ros-cmake-modules
            sudo apt-get install -y ros-noetic-dwa-local-planner*
            sudo apt-get install -y ros-noetic-turtlesim
            sudo apt-get install -y ros-$ROS_DISTRO-catkin
            source /opt/ros/$ROS_DISTRO/setup.bash
      - name: Install ROS packages with rosdep
        run: |
          source /opt/ros/$ROS_DISTRO/setup.bash
          sudo rosdep init
          rosdep update
          ln -s $GITHUB_WORKSPACE ~/catkin_ws/src/robot
          cd ~/catkin_ws
          rosdep install --from-paths src --ignore-src -ry
      - name: catkin build
        run: |
          source /opt/ros/$ROS_DISTRO/setup.bash
          cd ~/catkin_ws
          catkin build --no-status
          source devel/setup.bash

Method 2:

This installs ROS using the ros-tooling/[email protected] action instead of ‘manually’ installing ROS.

name: ROS CI

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-20.04
    env:
      ROS_CI_DESKTOP: "`lsb_release -cs`"
      ROS_DISTRO: noetic
    steps:
      - uses: actions/checkout@v2
        with:
          submodules: recursive
      - name: Download selected private repository dependencies
        run: |
          mkdir -p ~/catkin_ws/src
          cd ~/catkin_ws/src
          ssh-agent sh -c 'echo "${{ secrets.OTHER_ROS_PACKAGE }}" | ssh-add - && git clone [email protected]:Organisation/other-ros-package.git'- name: Install ROS- name: Install ROS
      - name: Install ROS
      - uses: ros-tooling/[email protected]
          with:
            required-ros-distributions: noetic
      - run: "source /opt/ros/noetic/setup.bash && rosnode --help"
      - name: Install ROS packages with rosdep
        run: |
          source /opt/ros/$ROS_DISTRO/setup.bash
          sudo rosdep init
          rosdep update
          ln -s $GITHUB_WORKSPACE ~/catkin_ws/src/robot
          cd ~/catkin_ws
          rosdep install --from-paths src --ignore-src -ry
      - name: catkin build
        run: |
          source /opt/ros/$ROS_DISTRO/setup.bash
          cd ~/catkin_ws
          catkin build --no-status
          source devel/setup.bash

Method 3:

This method encapsulates everything into a docker file and builds that docker file instead

name: ROS CI

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  build-docker-image:
    name: Install ROS
    runs-on: ubuntu-20.04
    steps:
      - name: Download selected private repository dependencies
        run: |
          mkdir -p ~/catkin_ws/src
          cd ~/catkin_ws/src
          ssh-agent sh -c 'echo "${{ secrets.OTHER_ROS_PACKAGE }}" | ssh-add - && git clone [email protected]:Organisation/other-ros-package.git'
      - uses: actions/checkout@v2
      - name: Build Image
        uses: docker/build-push-action@v2
        with:
          file: ./Dockerfile
          push: false

The dockerfile should look like this:

# Contens of Dockerfile

FROM ros:noetic

# Copy catkin_ws repositories into this Docker Environment
COPY robot /root/catkin_ws/src/robot
COPY other-ros-package /root/catkin_ws/src/other-ros-package

SHELL ["bash", "-c"]

# add install deps
RUN apt-get update && apt-get install git -y 

# https://github.com/docker/build-push-action/issues/504
ARG DEBIAN_FRONTEND=noninteractive

# install dependencies
RUN  cd /root/catkin_ws && \
  apt-get update && \
  apt install python3-catkin-tools -y && \
  rosdep update && \
  rosdep install --from-paths src --ignore-src -yr

# build repo
RUN . /ros_entrypoint.sh && cd /root/catkin_ws && \
  catkin build --cmake-args -DCMAKE_BUILD_TYPE=Release && \
  sed -i '$isource "/root/catkin_ws/devel/setup.bash"' /ros_entrypoint.sh

ENTRYPOINT ["/ros_entrypoint.sh"]
CMD ["bash"]

These are 3 ways to perform (basic) CI on Github actions with catkin build in order to check if the package is able to build. Cheerios~

Ros
Docker
Github
Actions
Ci
Recommended from ReadMedium