Skip to content

Travis CI

dgfrg edited this page Mar 22, 2017 · 4 revisions

One of the possible use-cases of docker is its integration with Travis CI. As the documentation reports, enabling docker has consequences on the selection of the virtualization environment and its features.

Among many pros, this docker way gives the freedom to chose the target linux distribution, removing the constrained choice of the few Ubuntu versions supported out-of-the-box by Travis CI. This could be very useful if you need packages, build tools, or framework not available in the default Ubuntu version. Do you need to test the DUT against other distributions? Just use / create a fedora, red hat, opensuse image, and you're ready to go.

In this short overview, general guidelines on how to properly integrate docker into the .travis.yml configuration file are presented. Since most of our projects use CMake, only out-of-tree examples will be introduced. Before continuing, reading this primer on docker+travis is advised.

Enable docker

services:
  - docker

Docker allows you to ship all the dependencies with the image. sudo could be safely disabled, and a container-based virtualization environment will be used:

sudo: false

Download the image(s)

The images can be downloaded from Docker Hub in the before_install step:

before_install:
  # Pull the docker containers
  - docker pull provider/image1
  - docker pull provider/image2

Containers life cycle

Considering the current development state of these images (highly WIP), two different scenarios can be outlined:

  1. Ephemeral containers: this scenario is valid when an image contains all the dependencies the project (or DUT) needs
  2. Persistent containers: this scenario is valid when the DUT requires dependencies that are not shipped with the docker image

1. Ephemeral containers

As reference, consider the robotology/gazebo-yarp-plugins project. Its .travis.yml executes every required command in a clean container, that is deleted after the process linked to the executed command dies.

The two three build phases (cmake, make, make install) share the folder of the DUT, that is made persistent by mounting it inside the container as a docker volume. The travis' variable TRAVIS_BUILD_DIR contains the absolute path where the project's git tree has been cloned, and it is the persistent folder that will be used. It is worth noting that this approach uses a fresh operating system for every operation, allowing the execution in isolated environments.

The basic steps are the following:

cmake

The configuration of the DUT is performed in the before_script step. A minimal example is the following:

before_script:
  # Run CMake into the persistent $PROJECT_DIR_ABS folder
  - cd $PROJECT_DIR_ABS
  - mkdir build
  - >-
    docker run -it --rm
    -v "$PROJECT_DIR_ABS:/app"
    -w /app
    provider/image
    sh -c 'cd build && cmake ./..'

When the project is configured, the container dies and the build/ folder is maintained into $PROJECT_DIR_ABS/build.

P.S. If a background process is required by the testing routine (e.g. yarpserver or ROS master node), in this step a detached container (docker run -it -d (...)) could be spawned. To facilitate its removal, use the --name option to assign a name.

make

A new container now can build the project. The process is similar to the previous one, but now it will be executed inside the script step;

script:
  # Build the project
  - >-
    docker run -it --rm
    -v "$PROJECT_DIR_ABS:/app"
    -w /app
    provider/image
    sh -c 'cd build && make'

make install

After the project has been build out-of-tree, it is possible to test its installation in another clean container. Usually the install step doesn't fail; its location could be either in the script or after_script step.

docker run -it --rm
    -v "$PROJECT_DIR_ABS:/app"
    -w /app
    provider/image
    sh -c 'cd build && make install'

P.S. If a background container is present, it should be stopped and removed inside the after_script step:

after_script:
  # Stop and remove running containers
  - docker stop containername
  - docker rm containername

2. Persistent containers

Clone this wiki locally