Skip to content

Commit

Permalink
gh: add GHA CI & Docker (#30)
Browse files Browse the repository at this point in the history
* Several cleanups & fixes to make build succeed (catkin lint, clang-tidy)
* Add ROS one build
* Add gh commitlint scope
* Make @rhaschke codeowner of gh workflows
* Use NodeHandle in plugin instead of smart ptr
* Use mjModel & mjData raw pointers instead of smart ptrs for better performance
---------

Co-authored-by: David Leins <[email protected]>
  • Loading branch information
rhaschke and DavidPL1 authored Oct 23, 2023
1 parent 8f96022 commit a10b4c7
Show file tree
Hide file tree
Showing 55 changed files with 911 additions and 540 deletions.
1 change: 1 addition & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Checks: 'performance-*,
modernize-redundant-void-arg,
modernize-use-nullptr,
modernize-use-default,
modernize-use-emplace,
modernize-use-override,
modernize-use-using,
modernize-loop-convert,
Expand Down
24 changes: 24 additions & 0 deletions .codecov.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
coverage:
precision: 2
round: up
range: "45...70"
status:
project:
default:
target: auto
threshold: 5%
patch: off

# While UI is not being tested, ignore UI/rendering related files
# lodepng is external and was tested beforehand (might include original unittests here at some point)
ignore:
- mujoco_ros/include/mujoco_ros/offscreen_camera.h
- mujoco_ros/include/mujoco_ros/platform_ui_adapter.h
- mujoco_ros/include/mujoco_ros/viewer.h
- mujoco_ros/src/glfw_adapter.cc
- mujoco_ros/src/glfw_dispatch.cc
- mujoco_ros/src/lodepng.cpp
- mujoco_ros/src/offscreen_camera.cpp
- mujoco_ros/src/offscreen_rendering.cpp
- mujoco_ros/src/platform_ui_adapter.cc
- mujoco_ros/src/viewer.cpp
57 changes: 57 additions & 0 deletions .docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
ARG IMAGE_PREFIX=""
ARG IMAGE_SUFFIX=""
ARG ROS_DISTRO=noetic
FROM ${IMAGE_PREFIX}ros:${ROS_DISTRO}-ros-base${IMAGE_SUFFIX} AS base

ENV TERM xterm
ENV IN_DOCKER 1


###################################################################################
FROM base AS prepare
ARG MUJOCO_VERSIONS=2.3.6 # ARG must be declared in stage were it is used!

# Setup temporary ROS workspace
WORKDIR /root/ws_mujoco

# Copy MuJoCo ROS sources from docker context
COPY . src/mujoco_ros_pkgs

# Install packages required for prepare stage
RUN apt-get -q update && \
apt-get -q -y dist-upgrade && \
DEBIAN_FRONTEND=noninteractive apt-get -q install --no-install-recommends -y curl git python3-vcstool && \
rm -rf /var/lib/apt/lists/*

# Install MuJoCo versions
RUN src/mujoco_ros_pkgs/.docker/mujoco_installer.sh

# Download upstream repo dependencies
RUN vcs import --shallow --input src/mujoco_ros_pkgs/.github/workflows/upstream.rosinstall src

# Create list of ros dependencies
RUN rosdep update
RUN rosdep install -y --from-paths src --ignore-src --simulate > /tmp/deps.sh
RUN chmod 755 /tmp/deps.sh


###################################################################################
FROM base AS final

COPY --from=prepare /root/mujoco /root/mujoco
COPY --from=prepare /tmp/deps.sh /tmp/deps.sh

RUN apt-get -q update && \
apt-get -q -y dist-upgrade && \
# Install common dependencies
DEBIAN_FRONTEND=noninteractive apt-get -q install --no-install-recommends -y \
curl git sudo python3-vcstool \
$(test "${ROS_DISTRO}" = "noetic" && echo "python3-catkin-tools" || echo "python3-colcon-common-extensions") \
clang clang-format clang-tidy clang-tools \
ccache && \
# Install rosdep dependencies
DEBIAN_FRONTEND=noninteractive /tmp/deps.sh && \
# Cleanup apt cache
rm -rf /var/lib/apt/lists/* && \
# Globally disable git security
git config --global --add safe.directory "*"
14 changes: 14 additions & 0 deletions .docker/mujoco_installer.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash

rm -rf "${HOME}/mujoco"

for mj_version in $MUJOCO_VERSIONS
do
echo "Installing MuJoCo Version ${mj_version} ..."

if curl -sSLfO https://github.com/google-deepmind/mujoco/releases/download/${mj_version}/mujoco-${mj_version}-linux-x86_64.tar.gz; then
mkdir -p "${HOME}/mujoco/${mj_version}"
tar -xzf mujoco-${mj_version}-linux-x86_64.tar.gz -C "${HOME}/mujoco/${mj_version}" --strip-components 1
rm "mujoco-${mj_version}-linux-x86_64.tar.gz"
fi
done
7 changes: 7 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
*

!.docker/mujoco_installer.sh
!.github/workflows/upstream.rosinstall
!.github/workflows/downstream.rosinstall
!**/package.xml
!**/CATKIN_IGNORE
4 changes: 3 additions & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
* @DavidPL1
* @DavidPL1

.github/workflows @rhaschke @DavidPL1
7 changes: 7 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
### Description

Please explain the changes you made, including a reference to the related issue if applicable

### Checklist
- [ ] **Required by CI**: Code is auto formatted using clang-format.
- [ ] Add a brief explanation of your changes to the [changelog](mujoco_ros/CHANGELOG.md).
142 changes: 142 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
name: CI

on:
workflow_dispatch:
pull_request:
push:
branches:
- noetic-devel

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
default:
strategy:
fail-fast: false
matrix:
distro: [noetic, one]
mujoco: [2.3.6]
include:
- distro: noetic
mujoco: 2.3.6
env:
CATKIN_LINT: true
CCOV: true
- distro: one
mujoco: 2.3.6
env:
CLANG_TIDY: pedantic

env:
BUILDER: colcon
DOCKER_RUN_OPTS: -e MUJOCO_DIR=/root/mujoco/${{ matrix.mujoco }}
DOCKER_IMAGE: ubiagni/mujoco_ros:${{ matrix.distro }}-ci

# For now we have flags defined in the CMakeLists, using all flags makes the build break
# I'll fix this once I find some time to do it
# CXXFLAGS: -Wall -Wextra -Wwrite-strings -Wunreachable-code -Wpointer-arith -Wredundant-decls
CXXFLAGS: -Wwrite-strings -Wunreachable-code -Wpointer-arith -Wredundant-decls
CLANG_TIDY_ARGS: --fix --fix-errors --format-style=file
UPSTREAM_WORKSPACE: .github/workflows/upstream.rosinstall
# Pull any updates to the upstream workspace
AFTER_SETUP_UPSTREAM_WORKSPACE: vcs pull $BASEDIR/upstream_ws/src
AFTER_SETUP_DOWNSTREAM_WORKSPACE: vcs pull $BASEDIR/downstream_ws/src
# Clear ccache stats before and log the stats after the build
AFTER_SETUP_CCACHE: ccache --zero-stats --max-size=10.0G
AFTER_BUILD_TARGET_WORKSPACE: ccache --show-stats
AFTER_BUILD_DOWNSTREAM_WORKSPACE: ccache --show-stats
# Compile CCOV with Debug. Enable -Werror.
TARGET_CMAKE_ARGS: >
-DCMAKE_BUILD_TYPE=${{ matrix.env.CCOV && 'Debug' || 'Release'}}
-DCMAKE_CXX_FLAGS="-Werror $CXXFLAGS${{ matrix.env.CCOV && ' --coverage -O2 -fno-omit-frame-pointer'}}"
UPSTREAM_CMAKE_ARGS: -DCMAKE_CXX_FLAGS= -DCMAKE_CXX_STANDARD=17

CCACHE_DIR: ${{ github.workspace }}/.ccache
BASEDIR: ${{ github.workspace }}/.work
CLANG_TIDY_BASE_REF: ${{ github.event_name != 'workflow_dispatch' && (github.base_ref || github.ref) || '' }}
BEFORE_CLANG_TIDY_CHECKS: |
# Show list of applied checks
(cd $TARGET_REPO_PATH; clang-tidy --list-checks)
CC: ${{ matrix.env.CLANG_TIDY && 'clang' }}
CXX: ${{ matrix.env.CLANG_TIDY && 'clang++' }}
CLANG_TIDY: ${{ matrix.env.CLANG_TIDY || 'false' }}
CATKIN_LINT: ${{ matrix.env.CATKIN_LINT || 'false' }}
CCOV: ${{ matrix.env.CCOV || 'false' }}

name: "${{ matrix.distro }} mj-${{ matrix.mujoco }}${{ 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)') || '' }}"
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- name: Cache upstream workspace
uses: rhaschke/cache@main
with:
path: ${{ env.BASEDIR }}/upstream_ws
key: ${{ env.CACHE_PREFIX }}-${{ github.run_id }}
restore-keys: ${{ env.CACHE_PREFIX }}
env:
GHA_CACHE_SAVE: always
CACHE_PREFIX: upstream_ws-${{ matrix.distro }}-${{ hashFiles('.github/workflows/upstream.rosinstall', '.github/workflows/ci.yaml') }}
# The target directory cache doesn't include the source directory because
# that comes from the checkout. See "prepare target_ws for cache" task below
- name: Cache target workspace
if: matrix.env.CCOV != true
uses: rhaschke/cache@main
with:
path: ${{ env.BASEDIR }}/target_ws
key: ${{ env.CACHE_PREFIX }}-${{ github.run_id }}
restore-keys: ${{ env.CACHE_PREFIX }}
env:
GHA_CACHE_SAVE: always
CACHE_PREFIX: target_ws${{ matrix.env.CCOV && '-ccov' || '' }}-${{ matrix.distro }}-${{ hashFiles('**/CMakeLists.txt', '**/package.xml', '.github/workflows/ci.yaml') }}
- name: Cache ccache
uses: rhaschke/cache@main
with:
path: ${{ env.CCACHE_DIR }}
key: ${{ env.CACHE_PREFIX }}-${{ github.sha }}-${{ github.run_id }}
restore-keys: |
${{ env.CACHE_PREFIX }}-${{ github.sha }}
${{ env.CACHE_PREFIX }}
env:
GHA_CACHE_SAVE: always
CACHE_PREFIX: ccache-${{ matrix.distro }}${{ matrix.env.CCOV && '-ccov' || '' }}

- id: ici
name: Run industrial_ci
uses: rhaschke/industrial_ci@ros-one

- name: Upload test artifacts (on failure)
uses: actions/upload-artifact@v3
if: failure() && (steps.ici.outputs.run_target_test || steps.ici.outputs.target_test_results)
with:
name: test-results-${{ matrix.distro }}
path: ${{ env.BASEDIR }}/target_ws/**/test_results/**/*.xml
- name: Generate codecov report
uses: rhaschke/lcov-action@main
if: always() && matrix.env.CCOV && steps.ici.outputs.target_test_results == '0'
with:
docker: $DOCKER_IMAGE
workdir: ${{ env.BASEDIR }}/target_ws
ignore: '"*/target_ws/build/*" "*/target_ws/install/*" "*/test/*"'
- name: Upload codecov report
uses: codecov/codecov-action@v3
if: always() && matrix.env.CCOV && steps.ici.outputs.target_test_results == '0'
with:
files: ${{ env.BASEDIR }}/target_ws/coverage.info
- name: Upload clang-tidy changes
uses: rhaschke/upload-git-patch-action@main
if: always() && matrix.env.CLANG_TIDY
with:
name: clang-tidy
path: ${{ env.BASEDIR }}/target_ws/src/$(basename $(pwd))
- name: Prepare target_ws for cache
if: always() && !matrix.env.CCOV
run: |
du -sh ${{ env.BASEDIR }}/target_ws
sudo find ${{ env.BASEDIR }}/target_ws -wholename '*/test_results/*' -delete
sudo rm -rf ${{ env.BASEDIR }}/target_ws/src ${{ env.BASEDIR }}/target_ws/logs
du -sh ${{ env.BASEDIR }}/target_ws
68 changes: 68 additions & 0 deletions .github/workflows/docker.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: Docker

on:
schedule:
# 6 AM UTC every Sunday
- cron: "0 6 * * 6"
workflow_dispatch:
push:
paths:
- '**/package.xml'
- .docker
- .dockignore
- .github/workflows/docker.yml
- .github/workflows/*.rosinstall

concurrency: # cancel any previous workflow(s) from the same PR or branch/tag
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
ci:
strategy:
fail-fast: false
matrix:
ROS_DISTRO: [noetic, one]
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
env:
IMAGE: ubiagni/mujoco_ros:${{ matrix.ROS_DISTRO }}-${{ github.job }}
MUJOCO_VERSIONS: 2.3.6 2.3.7

steps:
- name: Check for apt updates
uses: rhaschke/docker-run-action@v4
continue-on-error: true
id: apt
with:
image: ${{ env.IMAGE }}
shell: bash
run: |
apt-get update
have_updates=$(apt-get --simulate upgrade | grep -q "^0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.$" && echo false || echo true)
echo "no_cache=$have_updates" >> "$GITHUB_OUTPUT"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
if: ${{ github.event_name == 'workflow_dispatch' || github.event_name != 'schedule' || steps.apt.outputs.no_cache }}
- name: Login to Container Registry
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
if: ${{ github.event_name == 'workflow_dispatch' || github.event_name != 'schedule' || steps.apt.outputs.no_cache }}
with:
file: .docker/Dockerfile
build-args: |
ROS_DISTRO=${{ matrix.ROS_DISTRO }}
MUJOCO_VERSIONS=${{ env.MUJOCO_VERSIONS }}
IMAGE_PREFIX=${{ matrix.ROS_DISTRO == 'one' && 'ubiagni/' || '' }}
IMAGE_SUFFIX=${{ matrix.ROS_DISTRO == 'one' && '-jammy' || '' }}
push: true
no-cache: ${{ steps.apt.outputs.no_cache || github.event_name == 'workflow_dispatch' }}
cache-from: type=registry,ref=${{ env.IMAGE }}
cache-to: type=inline
tags: ${{ env.IMAGE }}
27 changes: 27 additions & 0 deletions .github/workflows/format.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Format

on:
workflow_dispatch:
pull_request:
push:

permissions:
contents: read

jobs:
pre-commit:
name: pre-commit
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- name: Install clang-format
run: sudo apt-get update && sudo apt-get install clang-format -y
- name: Install catkin_lint
uses: rhaschke/[email protected]
- uses: pre-commit/[email protected]
id: precommit
- name: Upload pre-commit changes
if: failure() && steps.precommit.outcome == 'failure'
uses: rhaschke/upload-git-patch-action@main
with:
name: pre-commit
4 changes: 4 additions & 0 deletions .github/workflows/upstream.rosinstall
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
- git:
local-name: actionlib
uri: https://github.com/rhaschke/actionlib.git
version: noetic-devel
1 change: 1 addition & 0 deletions .housekeeping/git-commit-template.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
# test = Including new or correcting previous tests
# build = Changes that affect the build system or external dependencies
# revert = Reverts a previous commit
# gh = github related changes (actions, workflows, ...)
#
# <scope> can specify which part of the codebase is affected by the commit.
#
Expand Down
Loading

0 comments on commit a10b4c7

Please sign in to comment.