Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Docker build and add CircleCI + CodeCov support #44

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
246 changes: 246 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
# `checksum.txt` derives the key for the `save_cache` and `restore_cache` steps.
ruffsl marked this conversation as resolved.
Show resolved Hide resolved
# As we can't cache onpon the state of the file system directly,
ruffsl marked this conversation as resolved.
Show resolved Hide resolved
# we instead compute a checksum of the files we wish to cache indirectly.
# CircleCI checksums this file, a simple list of checksum values itself,
# as part of the key to restore or break the respective cache value.

version: 2.1
references:
pre_checkout: &pre_checkout
run:
name: Pre Checkout
command: |
stat -c '%y' /opt/ros/$ROS_DISTRO/setup.sh | \
sha256sum | \
awk '{print "distro "$1}' > /opt/ros/$ROS_DISTRO/checksum.txt
ruffsl marked this conversation as resolved.
Show resolved Hide resolved
cp $MOVEIT2_WS/src/moveit2/moveit2.repos $ROS_WS/
rm -rf $MOVEIT2_WS/*
post_checkout: &post_checkout
run:
name: Post Checkout
command: |
if ! cmp $MOVEIT2_WS/src/moveit2/moveit2.repos $ROS_WS/moveit2.repos >/dev/null 2>&1
then
echo "Cleaning Upstream"
rm -rf $ROS_WS/*
mkdir -p $ROS_WS/src
vcs import $ROS_WS/src < $MOVEIT2_WS/src/moveit2/moveit2.repos
fi
install_upstream: &install_upstream
run:
name: Install Upstream
command: |
cat /opt/ros/$ROS_DISTRO/checksum.txt > $ROS_WS/checksum.txt
find $ROS_WS/src -not -iwholename '*.git/*' -type f -exec sha256sum {} \; | \
sort -k 2 | \
cut -d" " -f1 | \
sha256sum | \
awk '{print "upstream source "$1}' >> $ROS_WS/checksum.txt
apt-get update
dependencies=$(
rosdep install -q -y \
--from-paths \
$ROS_WS/src \
--ignore-src \
--verbose | \
awk '$1 ~ /^resolution\:/' | \
awk -F'[][]' '{print $2}' | \
tr -d \, | xargs -n1 | sort -u | xargs)
dpkg -s $dependencies | \
sha256sum | \
awk '{print "upstream dependencies "$1}' >> $ROS_WS/checksum.txt
restore_upstream_cache: &restore_upstream_cache
restore_cache:
name: Restore Upstream Cache
key: upstream-cache-v1-{{ arch }}-{{ checksum "/opt/ros_ws/checksum.txt" }}
build_upstream: &build_upstream
run:
name: Build Upstream
command: |
cd $ROS_WS
if [ -d install ]
then
echo "Skipping Build Upstream"
else
. /opt/ros/$ROS_DISTRO/setup.sh
colcon build \
--symlink-install \
--cmake-args \
-DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE
fi
save_upstream_cache: &save_upstream_cache
save_cache:
name: Save Upstream Cache
key: upstream-cache-v1-{{ arch }}-{{ checksum "/opt/ros_ws/checksum.txt" }}
paths:
- /opt/ros_ws
install_dependencies: &install_dependencies
run:
name: Install Dependencies
command: |
cat $ROS_WS/checksum.txt > $MOVEIT2_WS/checksum.txt
find $MOVEIT2_WS/src -not -iwholename '*.git/*' -type f -exec sha256sum {} \; | \
sort -k 2 | \
cut -d" " -f1 | \
sha256sum | \
awk '{print "source "$1}' >> $MOVEIT2_WS/checksum.txt
apt-get update
dependencies=$(
rosdep install -q -y \
--from-paths \
$ROS_WS/src \
src \
--ignore-src \
--verbose | \
awk '$1 ~ /^resolution\:/' | \
awk -F'[][]' '{print $2}' | \
tr -d \, | xargs -n1 | sort -u | xargs)
dpkg -s $dependencies | \
sha256sum | \
awk '{print "dependencies "$1}' >> $MOVEIT2_WS/checksum.txt
store_build_checksum: &store_build_checksum
store_artifacts:
path: checksum.txt
restore_build_cache: &restore_build_cache
restore_cache:
name: Restore Build Cache
key: build-cache-v1-{{ arch }}-{{ .Branch }}-{{ checksum "/opt/moveit2_ws/checksum.txt" }}
source_build: &source_build
run:
name: Source Build
command: |
if [ -d install ]
then
echo "Skipping Source Build"
else
. $ROS_WS/install/setup.sh
colcon build \
--symlink-install \
--cmake-args \
-DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE \
-DCOVERAGE_ENABLED=$COVERAGE_ENABLED
fi
save_build_cache: &save_build_cache
save_cache:
name: Save Build Cache
key: build-cache-v1-{{ arch }}-{{ .Branch }}-{{ checksum "/opt/moveit2_ws/checksum.txt" }}
paths:
- /opt/moveit2_ws
copy_build_logs: &copy_build_logs
run:
name: Copy Build Logs
when: always
command: cp -rH log/latest_build log/build
store_build_logs: &store_build_logs
store_artifacts:
path: log/build
test_build: &test_build
run:
name: Test Build
command: |
. install/setup.sh
src/moveit2/tools/run_test_suite.bash
copy_test_logs: &copy_test_logs
run:
name: Copy Test Logs
when: always
command: cp -rH log/latest_test log/test
store_test_logs: &store_test_logs
store_artifacts:
path: log/test
report_code_coverage: &report_code_coverage
run:
name: Report Code Coverage
command: |
if [ "$COVERAGE_ENABLED" = "True" ]
then
. install/setup.sh
src/moveit2/moveit/scripts/code_coverage_report.bash codecovio
else
echo "Skipping Code Coverage Report"
fi

commands:
checkout_source:
description: "Checkout Source"
steps:
- *pre_checkout
- checkout:
path: src/moveit2
- *post_checkout
setup_upstream:
description: "Setup Upstream"
steps:
- *install_upstream
- *restore_upstream_cache
- *build_upstream
- *save_upstream_cache
build_source:
description: "Build Source"
steps:
- *install_dependencies
- *store_build_checksum
- *restore_build_cache
- *source_build
- *save_build_cache
- *copy_build_logs
- *store_build_logs
test_source:
description: "Test Source"
steps:
- *test_build
- *copy_test_logs
- *store_test_logs
report_coverage:
description: "Report Coverage"
steps:
- *report_code_coverage

executors:
docker_exec:
docker:
- image: moveit/moveit2:master
ruffsl marked this conversation as resolved.
Show resolved Hide resolved
working_directory: /opt/moveit2_ws
environment:
MAKEFLAGS: "-j 1 -l 1"

jobs:
debug_build:
executor: docker_exec
environment:
CMAKE_BUILD_TYPE: "Debug"
COVERAGE_ENABLED: "True"
steps:
- checkout_source
- setup_upstream
- build_source
- test_source
# - report_coverage
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# - report_coverage
# TODO: re-enable report coverage when...
# - report_coverage

when? or remove comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is code coverage working now? I was waiting on this until this repo uses something like nav2's cmake changes to enable codecov at build time.

release_build:
executor: docker_exec
environment:
CMAKE_BUILD_TYPE: "Release"
COVERAGE_ENABLED: "False"
steps:
- checkout_source
- setup_upstream
- build_source
- test_source

workflows:
version: 2
build-test:
jobs:
- debug_build
- release_build
# TODO: Add cron jobs for regular tracking upstream
# nightly:
ruffsl marked this conversation as resolved.
Show resolved Hide resolved
# triggers:
# - schedule:
# cron: "0 0 * * *"
# filters:
# branches:
# only:
# - master
# jobs:
# - build
132 changes: 82 additions & 50 deletions .docker/ci/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,50 +1,82 @@
# moveit/moveit:melodic-ci
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep this file intact as it is already setup with dockerhub and travis. Perhaps we could move your changes to .docker/circle-ci/Dockerfile. Once that is done I am comfortable giving this a +1.

On a related note, if you have access to the ros-planning repo, I would recommend pushing your branch to ros-planning/moveit2 so that we can test that everything works with Dockerhub. I did the same thing for my PR #46 and it has been really helpful for iterating quickly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've restored the old Dockerfile in 6d642ca , but reminded I had to have new Dockerfile at the root of the project so that the build context may encompass the entire repo that it copies from. I've added a .dockerignore file to mitigate build cache breaks from git fetches or editing of the Dockerfile itself.

# Sets up a base image to use for running Continuous Integration on Travis

FROM ros:melodic-ros-base
MAINTAINER Dave Coleman dave@picknik.ai

ENV TERM xterm

# Setup catkin workspace
ENV CATKIN_WS=/root/ws_moveit
WORKDIR $CATKIN_WS

# Commands are combined in single RUN statement with "apt/lists" folder removal to reduce image size
# https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#minimize-the-number-of-layers
RUN \
mkdir src && \
cd src && \
#
# Download moveit source, so that we can get necessary dependencies
wstool init --shallow . https://raw.githubusercontent.com/ros-planning/moveit/${ROS_DISTRO}-devel/moveit.rosinstall && \
#
# Update apt package list as previous containers clear the cache
apt-get -qq update && \
apt-get -qq dist-upgrade && \
#
# Install some base dependencies
apt-get -qq install -y \
# Some source builds require a package.xml be downloaded via wget from an external location
wget \
# Required for rosdep command
sudo \
# Preferred build tools
python-catkin-tools \
clang clang-format-3.9 clang-tidy clang-tools \
ccache && \
#
# Download all dependencies of MoveIt!
rosdep update && \
rosdep install -y --from-paths . --ignore-src --rosdistro ${ROS_DISTRO} --as-root=apt:false && \
#
# Remove the source code from this container
# TODO: in the future we may want to keep this here for further optimization of later containers
cd .. && \
rm -rf src/ && \
#
# Clear apt-cache to reduce image size
rm -rf /var/lib/apt/lists/*

# Continous Integration Setting
ENV IN_DOCKER 1
# This dockerfile expects proxies to be set via --build-arg if needed
ruffsl marked this conversation as resolved.
Show resolved Hide resolved
# It also expects to be contained in the /moveit2 root folder for file copy
# Example build command:
# export http_proxy=http://my.proxy.com:80
# export CMAKE_BUILD_TYPE=Debug
# docker build -t nav2:latest --build-arg http_proxy --build-arg CMAKE_BUILD_TYPE ./
Copy link
Contributor

@mlautman mlautman Mar 20, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moveit/moveit2:master

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I omitted the org so user building don't blow away what they may have pulled.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. maybe change nav2->moveit2?

Also I really like that the existing dockerfiles have their label in the documentation (eg https://github.com/ros-planning/moveit2/blob/master/.docker/ci/Dockerfile#L1) do you think you can add a simmilar line up top? It could be something like moveit/moveit2:crystal-circle-ci

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than have some manual mapping from github branches to dockerhub tags, like crystal-circle-ci, I'd recommend we adopt a more programmatic style where release branches and tags on ros-planning/moveit2 github are mapped directly to tag names on ros-planning/moveit2 for CI consumption. There can be procedurally created, while the origin/relation of docker tags to code would be clear and more amenable for CI configs; alluded to in #44 (comment)

FROM osrf/ros2:nightly

# setup keys
ARG http_proxy
RUN if [ "$http_proxy" != "" ]; \
mlautman marked this conversation as resolved.
Show resolved Hide resolved
then \
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 \
--keyserver-options http-proxy=$http_proxy \
--recv-keys 421C365BD9FF1F717815A3895523BAEEB01FA116; \
fi

# install ROS2 dependencies
RUN apt-get update && apt-get install -q -y \
build-essential \
cmake \
git \
python3-colcon-common-extensions \
python3-vcstool \
wget \
&& rm -rf /var/lib/apt/lists/*

# copy ros package repo
ENV MOVEIT2_WS /opt/moveit2_ws
RUN mkdir -p $MOVEIT2_WS/src
ruffsl marked this conversation as resolved.
Show resolved Hide resolved
WORKDIR $MOVEIT2_WS/src
COPY ./ moveit2/

# clone dependency package repos
ENV ROS_WS /opt/ros_ws
RUN mkdir -p $ROS_WS/src
WORKDIR $ROS_WS
RUN vcs import src < $MOVEIT2_WS/src/moveit2/tools/ros2_dependencies.repos

# install dependency package dependencies
RUN . /opt/ros/$ROS_DISTRO/setup.sh && \
apt-get update && \
rosdep install -q -y \
--from-paths \
src \
--ignore-src \
&& rm -rf /var/lib/apt/lists/*

# build dependency package source
ARG CMAKE_BUILD_TYPE=Release

RUN . /opt/ros/$ROS_DISTRO/setup.sh && \
colcon build \
--symlink-install \
--cmake-args \
-DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE

# install moveit2 package dependencies
WORKDIR $MOVEIT2_WS
mlautman marked this conversation as resolved.
Show resolved Hide resolved
RUN . $ROS_WS/install/setup.sh && \
apt-get update && \
rosdep install -q -y \
--from-paths \
$ROS_WS/src \
src \
--ignore-src \
&& rm -rf /var/lib/apt/lists/*

# build moveit2 package source
RUN rm $MOVEIT2_WS/src/moveit2/nav2_system_tests/COLCON_IGNORE
ruffsl marked this conversation as resolved.
Show resolved Hide resolved
ARG COVERAGE_ENABLED=False
RUN . $ROS_WS/install/setup.sh && \
colcon build \
--symlink-install \
--cmake-args \
-DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE \
-DCOVERAGE_ENABLED=$COVERAGE_ENABLED

# source moveit2 workspace from entrypoint
RUN sed --in-place \
's|^source .*|source "$MOVEIT2_WS/install/setup.bash"|' \
/ros_entrypoint.sh
Loading