Skip to content

Commit b0c6a16

Browse files
committed
gha: adds ROS 2 specific actions for docker and ci
1 parent aadba63 commit b0c6a16

8 files changed

Lines changed: 297 additions & 6 deletions

File tree

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ RUN apt-get -q update && \
2727
RUN src/mujoco_ros_pkgs/.docker/mujoco_installer.sh
2828

2929
# Download upstream repo dependencies
30-
RUN vcs import --shallow --input src/mujoco_ros_pkgs/.github/workflows/upstream.rosinstall src
30+
RUN vcs import --shallow --input src/mujoco_ros_pkgs/.github/workflows/upstream.ros1.rosinstall src
3131

3232
# Create list of ros dependencies
3333
RUN rosdep update $(test "${ROS_DISTRO}" = "noetic" && echo --rosdistro ${ROS_DISTRO})

.docker/Dockerfile.ros2

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
ARG IMAGE_PREFIX=""
2+
ARG ROS_DISTRO=noetic
3+
ARG BASE_DOCKER_NAME=${ROS_DISTRO}
4+
FROM ${IMAGE_PREFIX}ros:${BASE_DOCKER_NAME}-ros-base AS base
5+
6+
ENV TERM=xterm
7+
ENV IN_DOCKER=1
8+
9+
10+
###################################################################################
11+
FROM base AS prepare
12+
# TODO: ROS 2 version for now is pinned at 3.2.0!
13+
ARG MUJOCO_VERSIONS=3.2.0 # ARG must be declared in stage were it is used!
14+
15+
# Setup temporary ROS workspace
16+
WORKDIR /root/ws_mujoco
17+
18+
# Copy MuJoCo ROS sources from docker context
19+
COPY . src/mujoco_ros_pkgs
20+
21+
# Install packages required for prepare stage
22+
RUN apt-get -q update && \
23+
apt-get -q -y dist-upgrade && \
24+
DEBIAN_FRONTEND=noninteractive apt-get -q install --no-install-recommends -y curl git && \
25+
rm -rf /var/lib/apt/lists/*
26+
27+
# Install MuJoCo versions
28+
RUN src/mujoco_ros_pkgs/.docker/mujoco_installer.sh
29+
30+
## Previously needed for timing issues with time resets. TODO: check if something similar is necessary in ROS 2
31+
# Download upstream repo dependencies
32+
# RUN vcs import --shallow --input src/mujoco_ros_pkgs/.github/workflows/upstream.ros2.rosinstall src
33+
34+
# Create list of ros dependencies
35+
RUN rosdep update --rosdistro ${ROS_DISTRO}
36+
RUN rosdep install -y --from-paths src --ignore-src --simulate > /tmp/deps.sh --rosdistro ${ROS_DISTRO}
37+
RUN chmod 755 /tmp/deps.sh
38+
39+
40+
###################################################################################
41+
FROM base AS final
42+
43+
COPY --from=prepare /root/mujoco /root/mujoco
44+
COPY --from=prepare /tmp/deps.sh /tmp/deps.sh
45+
46+
RUN apt-get -q update && \
47+
apt-get -q -y dist-upgrade && \
48+
# Install common dependencies
49+
DEBIAN_FRONTEND=noninteractive apt-get -q install --no-install-recommends -y \
50+
libgles2-mesa-dev libosmesa6-dev libglfw3-dev \
51+
curl git sudo python3-vcstool \
52+
python3-colcon-common-extensions \
53+
clang clang-format clang-tidy clang-tools \
54+
ccache && \
55+
# Install rosdep dependencies
56+
DEBIAN_FRONTEND=noninteractive /tmp/deps.sh && \
57+
# Cleanup apt cache
58+
rm -rf /var/lib/apt/lists/* && \
59+
# Globally disable git security
60+
git config --global --add safe.directory "*"

.dockerignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
*
22

33
!.docker/mujoco_installer.sh
4-
!.github/workflows/upstream.rosinstall
4+
!.github/workflows/upstream.ros1.rosinstall
5+
!.github/workflows/upstream.ros2.rosinstall
56
!.github/workflows/downstream.rosinstall
67
!**/package.xml
78
!**/CATKIN_IGNORE
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ jobs:
4545
# CXXFLAGS: -Wall -Wextra -Wwrite-strings -Wunreachable-code -Wpointer-arith -Wredundant-decls
4646
CXXFLAGS: -Wwrite-strings -Wunreachable-code -Wpointer-arith -Wredundant-decls
4747
CLANG_TIDY_ARGS: --fix --fix-errors --format-style=file
48-
UPSTREAM_WORKSPACE: .github/workflows/upstream.rosinstall
48+
UPSTREAM_WORKSPACE: .github/workflows/upstream.ros1.rosinstall
4949
# Install and start xvfb for GLFW
5050
AFTER_INIT: ${{ matrix.render_backend == 'GLFW' && 'apt-get install -qy xvfb; Xvfb :99 &' || '' }}
5151
# Pull any updates to the upstream workspace
@@ -86,7 +86,7 @@ jobs:
8686
restore-keys: ${{ env.CACHE_PREFIX }}
8787
env:
8888
GHA_CACHE_SAVE: always
89-
CACHE_PREFIX: upstream_ws-${{ matrix.distro }}-${{ hashFiles('.github/workflows/upstream.rosinstall', '.github/workflows/ci.yaml') }}
89+
CACHE_PREFIX: upstream_ws-${{ matrix.distro }}-${{ hashFiles('.github/workflows/upstream.ros1.rosinstall', '.github/workflows/ci.ros1.yaml') }}
9090
# The target directory cache doesn't include the source directory because
9191
# that comes from the checkout. See "prepare target_ws for cache" task below
9292
- name: Cache target workspace
@@ -98,7 +98,7 @@ jobs:
9898
restore-keys: ${{ env.CACHE_PREFIX }}
9999
env:
100100
GHA_CACHE_SAVE: always
101-
CACHE_PREFIX: target_ws${{ matrix.env.CCOV && '-ccov' || '' }}-${{ matrix.distro }}-${{ hashFiles('**/CMakeLists.txt', '**/package.xml', '.github/workflows/ci.yaml') }}
101+
CACHE_PREFIX: target_ws${{ matrix.env.CCOV && '-ccov' || '' }}-${{ matrix.distro }}-${{ hashFiles('**/CMakeLists.txt', '**/package.xml', '.github/workflows/ci.ros1.yaml') }}
102102
- name: Cache ccache
103103
uses: rhaschke/cache@main
104104
with:

.github/workflows/ci.ros2.yaml

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
name: CI
2+
3+
on:
4+
workflow_dispatch:
5+
pull_request:
6+
push:
7+
branches:
8+
- wip-ros-humble
9+
- fix-pr-history
10+
11+
permissions:
12+
contents: read
13+
14+
concurrency:
15+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
16+
cancel-in-progress: true
17+
18+
jobs:
19+
default:
20+
strategy:
21+
fail-fast: false
22+
matrix:
23+
distro: [humble, jazzy]
24+
render_backend: [GLFW, OSMESA, DISABLE] # EGL currently removed due to issues with the local CI runners
25+
mujoco: [3.2.0]
26+
include:
27+
- distro: humble
28+
mujoco: 3.2.0
29+
env:
30+
CCOV: true
31+
- distro: humble
32+
mujoco: 3.2.0
33+
env:
34+
CLANG_TIDY: pedantic
35+
36+
env:
37+
BUILDER: colcon
38+
MUJOCO_DIR: /vol/mujoco/mujoco-${{ matrix.mujoco }} # for self-hosted runners
39+
DOCKER_RUN_OPTS: -e MUJOCO_DIR=/root/mujoco/${{ matrix.mujoco }} -e DISPLAY=:99.0
40+
DOCKER_IMAGE: ubiagni/mujoco_ros:${{ matrix.distro }}-ci
41+
42+
# For now we have flags defined in the CMakeLists, using all flags makes the build break
43+
# I'll fix this once I find some time to do it
44+
# CXXFLAGS: -Wall -Wextra -Wwrite-strings -Wunreachable-code -Wpointer-arith -Wredundant-decls
45+
CXXFLAGS: -Wwrite-strings -Wunreachable-code -Wpointer-arith # rosidl triggers this in non-user code, so let's leave it out for now -Wredundant-decls
46+
CLANG_TIDY_ARGS: --fix --fix-errors --format-style=file
47+
# UPSTREAM_WORKSPACE: .github/workflows/upstream.ros2.rosinstall
48+
# Install and start xvfb for GLFW
49+
AFTER_INIT: ${{ matrix.render_backend == 'GLFW' && 'apt-get install -qy xvfb; Xvfb :99 &' || '' }}
50+
# Pull any updates to the upstream workspace
51+
# AFTER_SETUP_UPSTREAM_WORKSPACE: vcs pull $BASEDIR/upstream_ws/src
52+
AFTER_SETUP_DOWNSTREAM_WORKSPACE: vcs pull $BASEDIR/downstream_ws/src
53+
# Clear ccache stats before and log the stats after the build
54+
AFTER_SETUP_CCACHE: ccache --zero-stats --max-size=10.0G
55+
AFTER_BUILD_TARGET_WORKSPACE: ccache --show-stats
56+
AFTER_BUILD_DOWNSTREAM_WORKSPACE: ccache --show-stats
57+
# Compile CCOV with Debug. Enable -Werror.
58+
TARGET_CMAKE_ARGS: >
59+
-DCMAKE_BUILD_TYPE=${{ matrix.env.CCOV && 'Debug' || 'Release'}}
60+
-DCMAKE_CXX_FLAGS="-Werror $CXXFLAGS${{ matrix.env.CCOV && ' --coverage -O2 -fno-omit-frame-pointer'}}"
61+
-DRENDER_BACKEND=${{ matrix.render_backend }}
62+
# UPSTREAM_CMAKE_ARGS: -DCMAKE_CXX_FLAGS= -DCMAKE_CXX_STANDARD=17
63+
64+
CCACHE_DIR: ${{ github.workspace }}/.ccache
65+
BASEDIR: ${{ github.workspace }}/.work
66+
CLANG_TIDY_BASE_REF: ${{ github.event_name != 'workflow_dispatch' && (github.base_ref || github.ref) || '' }}
67+
BEFORE_CLANG_TIDY_CHECKS: |
68+
# Show list of applied checks
69+
(cd $TARGET_REPO_PATH; clang-tidy --list-checks)
70+
CC: ${{ matrix.env.CLANG_TIDY && 'clang' }}
71+
CXX: ${{ matrix.env.CLANG_TIDY && 'clang++' }}
72+
CLANG_TIDY: ${{ matrix.env.CLANG_TIDY || 'false' }}
73+
CATKIN_LINT: ${{ matrix.env.CATKIN_LINT || 'false' }}
74+
CCOV: ${{ matrix.env.CCOV || 'false' }}
75+
76+
name: "${{ matrix.distro }} mj-${{ matrix.mujoco }} ${{ matrix.render_backend }} ${{ matrix.env.CATKIN_LINT && ' + catkin_lint' || ''}}${{ matrix.env.CCOV && ' + ccov' || ''}}${{ matrix.env.CLANG_TIDY && (github.event_name != 'workflow_dispatch' && ' + clang-tidy (delta)' || ' + clang-tidy (all)') || '' }}"
77+
runs-on: ${{ matrix.render_backend == 'EGL' && matrix.distro || 'ubuntu-latest' }}
78+
steps:
79+
- uses: actions/checkout@v4
80+
# - name: Cache upstream workspace
81+
# uses: rhaschke/cache@main
82+
# with:
83+
# path: ${{ env.BASEDIR }}/upstream_ws
84+
# key: ${{ env.CACHE_PREFIX }}-${{ github.run_id }}
85+
# restore-keys: ${{ env.CACHE_PREFIX }}
86+
# env:
87+
# GHA_CACHE_SAVE: always
88+
# CACHE_PREFIX: upstream_ws-${{ matrix.distro }}-${{ hashFiles('.github/workflows/upstream.rosinstall', '.github/workflows/ci.ros2.yaml') }}
89+
# The target directory cache doesn't include the source directory because
90+
# that comes from the checkout. See "prepare target_ws for cache" task below
91+
- name: Cache target workspace
92+
if: matrix.env.CCOV != true
93+
uses: rhaschke/cache@main
94+
with:
95+
path: ${{ env.BASEDIR }}/target_ws
96+
key: ${{ env.CACHE_PREFIX }}-${{ github.run_id }}
97+
restore-keys: ${{ env.CACHE_PREFIX }}
98+
env:
99+
GHA_CACHE_SAVE: always
100+
CACHE_PREFIX: target_ws${{ matrix.env.CCOV && '-ccov' || '' }}-${{ matrix.distro }}-${{ hashFiles('**/CMakeLists.txt', '**/package.xml', '.github/workflows/ci.ros2.yaml') }}
101+
- name: Cache ccache
102+
uses: rhaschke/cache@main
103+
with:
104+
path: ${{ env.CCACHE_DIR }}
105+
key: ${{ env.CACHE_PREFIX }}-${{ github.sha }}-${{ github.run_id }}
106+
restore-keys: |
107+
${{ env.CACHE_PREFIX }}-${{ github.sha }}
108+
${{ env.CACHE_PREFIX }}
109+
env:
110+
GHA_CACHE_SAVE: always
111+
CACHE_PREFIX: ccache-${{ matrix.distro }}${{ matrix.env.CCOV && '-ccov' || '' }}
112+
113+
- id: ici
114+
name: Run industrial_ci
115+
uses: ros-industrial/industrial_ci@master
116+
117+
- name: Upload test artifacts (on failure)
118+
uses: actions/upload-artifact@v4
119+
if: failure() && (steps.ici.outputs.run_target_test || steps.ici.outputs.target_test_results)
120+
with:
121+
name: test-results-${{ matrix.distro }}-${{ matrix.render_backend }}
122+
path: ${{ env.BASEDIR }}/target_ws/**/test_results/**/*.xml
123+
- name: Generate codecov report
124+
uses: rhaschke/lcov-action@main
125+
if: always() && matrix.env.CCOV && steps.ici.outputs.target_test_results == '0'
126+
with:
127+
docker: ${{ matrix.render_backend != 'EGL' && '$DOCKER_IMAGE' || '' }}
128+
workdir: ${{ env.BASEDIR }}/target_ws
129+
ignore: '"*/target_ws/build/*" "*/target_ws/install/*" "*/test/*"'
130+
output: ${{ env.BASEDIR }}/target_ws/coverage-${{ matrix.distro }}-${{ matrix.render_backend }}.info
131+
- name: Upload codecov report
132+
uses: codecov/codecov-action@v5
133+
if: always() && matrix.env.CCOV && steps.ici.outputs.target_test_results == '0'
134+
with:
135+
files: ${{ env.BASEDIR }}/target_ws/coverage-${{ matrix.distro }}-${{ matrix.render_backend }}.info
136+
- name: Upload clang-tidy changes
137+
uses: rhaschke/upload-git-patch-action@main
138+
if: always() && matrix.env.CLANG_TIDY
139+
with:
140+
name: clang-tidy
141+
path: ${{ env.BASEDIR }}/target_ws/src/$(basename $(pwd))
142+
- name: Prepare target_ws for cache
143+
if: always() && !matrix.env.CCOV
144+
run: |
145+
du -sh ${{ env.BASEDIR }}/target_ws
146+
sudo find ${{ env.BASEDIR }}/target_ws -wholename '*/test_results/*' -delete
147+
sudo rm -rf ${{ env.BASEDIR }}/target_ws/src ${{ env.BASEDIR }}/target_ws/logs
148+
du -sh ${{ env.BASEDIR }}/target_ws
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ jobs:
5757
uses: docker/build-push-action@v5
5858
if: ${{ github.event_name == 'workflow_dispatch' || github.event_name != 'schedule' || steps.apt.outputs.no_cache }}
5959
with:
60-
file: .docker/Dockerfile
60+
file: .docker/Dockerfile.ros1
6161
build-args: |
6262
ROS_DISTRO=${{ matrix.ROS_DISTRO }}
6363
BASE_DOCKER_NAME=${{ matrix.ROS_DISTRO == 'one' && 'jammy' || matrix.ROS_DISTRO }}

.github/workflows/docker.ros2.yaml

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
name: Docker
2+
3+
on:
4+
schedule:
5+
# 6 AM UTC every Sunday
6+
- cron: "0 6 * * 6"
7+
workflow_dispatch:
8+
push:
9+
branches:
10+
- wip-ros-humble
11+
- fix-pr-history
12+
paths:
13+
- '**/package.xml'
14+
- .docker
15+
- .dockignore
16+
- .github/workflows/docker.yml
17+
- .github/workflows/*.rosinstall
18+
pull_request:
19+
branches:
20+
- wip-ros-humble
21+
- fix-pr-history
22+
paths:
23+
- '**/package.xml'
24+
- .docker
25+
- .dockignore
26+
- .github/workflows/docker.yml
27+
- .github/workflows/*.rosinstall
28+
29+
30+
concurrency: # cancel any previous workflow(s) from the same PR or branch/tag
31+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
32+
cancel-in-progress: true
33+
34+
jobs:
35+
ci:
36+
strategy:
37+
fail-fast: false
38+
matrix:
39+
ROS_DISTRO: [humble, jazzy]
40+
runs-on: ubuntu-latest
41+
permissions:
42+
packages: write
43+
contents: read
44+
env:
45+
IMAGE: ubiagni/mujoco_ros:${{ matrix.ROS_DISTRO }}-${{ github.job }}
46+
MUJOCO_VERSIONS: 3.2.0 # TODO: ROS 2 pinned to 3.2.0 for now (until stable)
47+
48+
steps:
49+
- name: Check for apt updates
50+
uses: rhaschke/docker-run-action@main
51+
continue-on-error: true
52+
id: apt
53+
with:
54+
image: ${{ env.IMAGE }}
55+
shell: bash
56+
run: |
57+
apt-get update
58+
have_updates=$(apt-get --simulate upgrade | grep -q "^0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.$" && echo false || echo true)
59+
echo "no_cache=$have_updates" >> "$GITHUB_OUTPUT"
60+
- name: Set up Docker Buildx
61+
uses: docker/setup-buildx-action@v3
62+
if: ${{ github.event_name == 'workflow_dispatch' || github.event_name != 'schedule' || steps.apt.outputs.no_cache }}
63+
- name: Login to Container Registry
64+
uses: docker/login-action@v3
65+
with:
66+
username: ${{ secrets.DOCKERHUB_USERNAME }}
67+
password: ${{ secrets.DOCKERHUB_TOKEN }}
68+
- name: Build and push
69+
uses: docker/build-push-action@v5
70+
if: ${{ github.event_name == 'workflow_dispatch' || github.event_name != 'schedule' || steps.apt.outputs.no_cache }}
71+
with:
72+
file: .docker/Dockerfile.ros2
73+
build-args: |
74+
ROS_DISTRO=${{ matrix.ROS_DISTRO }}
75+
BASE_DOCKER_NAME=${{ matrix.ROS_DISTRO }}
76+
MUJOCO_VERSIONS=${{ env.MUJOCO_VERSIONS }}
77+
IMAGE_PREFIX=${{ '' }}
78+
push: true
79+
no-cache: ${{ steps.apt.outputs.no_cache || github.event_name == 'workflow_dispatch' }}
80+
cache-from: type=registry,ref=${{ env.IMAGE }}
81+
cache-to: type=inline
82+
tags: ${{ env.IMAGE }}
File renamed without changes.

0 commit comments

Comments
 (0)