From c03e94f8b0aa2e61eae8df8f475aa6fa7574c218 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 23 Nov 2017 10:56:24 +0100 Subject: [PATCH] ci: use Docker for Travis Continuous Integration --- .dockerignore | 2 + .travis.yml | 60 +++++++++++--------- scripts/docker/arch_latest.docker | 15 +++++ scripts/docker/docker_tool.py | 85 +++++++++++++++++++++++++++++ scripts/docker/docker_travis.sh | 14 +++++ scripts/docker/fedora_latest.docker | 20 +++++++ scripts/docker/ubuntu_latest.docker | 22 ++++++++ 7 files changed, 191 insertions(+), 27 deletions(-) create mode 100644 .dockerignore create mode 100644 scripts/docker/arch_latest.docker create mode 100755 scripts/docker/docker_tool.py create mode 100755 scripts/docker/docker_travis.sh create mode 100644 scripts/docker/fedora_latest.docker create mode 100644 scripts/docker/ubuntu_latest.docker diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..10ea3993 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +build +.git diff --git a/.travis.yml b/.travis.yml index 91270180..27e7e9f5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,32 +1,38 @@ -sudo: required -dist: trusty -language: generic -env: - - CXX=g++-5 CC=gcc-5 -addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-5 - - libbullet-dev - - libsdl2-dev - - libglm-dev - - libopenal-dev - - libavcodec-dev - - libavformat-dev - - libboost-filesystem-dev - - libboost-program-options-dev - # Dependencies for BUILD_TESTS - - libboost-test-dev - # Dependencies for BUILD_VIEWER - - qt5-default - - libqt5opengl5-dev +language: cpp + git: depth: 3 -script: - - ctest -S cmake/ctest/travis_script.ctest -VV -DSRC_DIR=. -DBIN_DIR=build - - if [ -f FATAL_ERROR ]; then printf "Fatal failure detected.\nExiting with non-zero result code.\n"; exit 1; fi + +matrix: + include: + - os: linux + env: NAME="Ubuntu Linux (Latest)" + services: docker + script: + - scripts/docker/docker_travis.sh "ubuntu_latest.docker" + - os: linux + env: NAME="Fedora Linux (Latest)" + services: docker + script: + - scripts/docker/docker_travis.sh "fedora_latest.docker" + - os: linux + env: NAME="Arch Linux (Latest)" + services: docker + script: + - scripts/docker/docker_travis.sh "arch_latest.docker" + - os: osx + env: NAME="Apple MacOS" + osx_image: xcode9.2 + install: + - brew update + - brew upgrade + - brew install boost cmake bullet ffmpeg glm openal-soft qt5 sdl2 + - export PATH="/usr/local/opt/openal-soft/bin:/usr/local/opt/qt/bin:$PATH" + - export PKG_CONFIG_PATH=/usr/local/opt/openal-soft/lib/pkgconfig + script: + - mkdir -p "$TRAVIS_BUILD_DIR/build" + - ctest -S "$TRAVIS_BUILD_DIR/cmake/ctest/travis_script.ctest" -VV -DSRC_DIR="$TRAVIS_BUILD_DIR" -DBIN_DIR="$TRAVIS_BUILD_DIR/build" + notifications: email: false # irc: diff --git a/scripts/docker/arch_latest.docker b/scripts/docker/arch_latest.docker new file mode 100644 index 00000000..89e82079 --- /dev/null +++ b/scripts/docker/arch_latest.docker @@ -0,0 +1,15 @@ +FROM base/archlinux + +RUN pacman -Syy --noconfirm \ + core/gcc \ + make \ + extra/boost \ + extra/cmake \ + extra/ffmpeg \ + extra/bullet \ + community/glm \ + extra/openal \ + extra/sdl2 \ + extra/qt5-base + +CMD ["/bin/bash"] diff --git a/scripts/docker/docker_tool.py b/scripts/docker/docker_tool.py new file mode 100755 index 00000000..fc695994 --- /dev/null +++ b/scripts/docker/docker_tool.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 + +import argparse +import os +from pathlib import Path +import pwd +import subprocess + +docker_dir = Path(__file__).absolute().parent +docker_files = list(docker_dir.glob('*.docker')) +openrw_dir = docker_dir.parents[1] +openrw_build_dir = openrw_dir / 'build' +assert((openrw_dir/'CMakeLists.txt').exists()) + + +def sub_run(args): + print('Executing', args) + subprocess.check_call(args) + + +def build(ns: argparse.Namespace): + docker_file = docker_dir / ns.distribution + assert(docker_file.exists()) + sub_run(['docker', 'build', '-t', ns.tag, '-f', str(docker_file), str(openrw_dir)]) + + +def create(ns: argparse.Namespace): + # name: str, tag: str, build_subdir: str, uid: typing.Union[None, int], username: str): + build_dir = openrw_build_dir / ns.build_subdir + if not build_dir.exists(): + build_dir.mkdir() + env_args = [a for e in ns.env for a in ('-e', e)] + run_args = ['docker', 'run', + '-v', '{}:/src:ro,z'.format(str(openrw_dir)), + '-v', '{}:/build:rw,z'.format(str(build_dir)) ] + \ + env_args + ['--name', ns.name, '-d', ns.tag, 'sleep', 'infinity'] + sub_run(run_args) + if ns.uid is None: + ns.uid = os.getuid() + gid = pwd.getpwuid(ns.uid).pw_gid + sub_run(['docker', 'exec', ns.name, 'groupadd', '--gid', str(gid), ns.username]) + sub_run(['docker', 'exec', ns.name, 'useradd', '--create-home', + '--uid', str(ns.uid), '-g', ns.username, ns.username]) + + +def exec(ns: argparse.Namespace): + if ns.ARGUMENTS: + run_args = ['docker', 'exec', '-u', ns.username, ns.name ] + ns.ARGUMENTS + else: + run_args = ['docker', 'exec', '-ti', '-u', ns.username, ns.name, '/bin/bash'] + sub_run(run_args) + + +def main(): + parser = argparse.ArgumentParser() + subparser = parser.add_subparsers() + + build_parser = subparser.add_parser('build') + build_parser.add_argument('-d', '--distribution', required=True, choices=tuple(df.name for df in docker_files), + help='which Docker image to build') + build_parser.add_argument('-t', '--tag', required=True, help='Docker image name') + build_parser.set_defaults(func=build) + + create_parser = subparser.add_parser('create') + create_parser.add_argument('-e', '--env', default=[], nargs=argparse.ONE_OR_MORE, help='Add environment variables') + create_parser.add_argument('-n', '--name', required=True, help='Name of the container') + create_parser.add_argument('-b', '--build_subdir', default='.', help='/build subdir') + create_parser.add_argument('-t', '--tag', required=True, help='Docker image name') + create_parser.add_argument('-u', '--uid', type=int, default=None, help='uid of the user to add to the Docker image') + create_parser.add_argument('-U', '--username', type=str, required=True, help='name of the user to add to the Docker image') + create_parser.set_defaults(func=create) + + exec_parser = subparser.add_parser('exec') + exec_parser.add_argument('ARGUMENTS', nargs=argparse.ZERO_OR_MORE) + exec_parser.add_argument('-n', '--name', required=True, help='Name of the container') + exec_parser.add_argument('-U', '--username', type=str, required=True, help='username to execute commands as') + exec_parser.set_defaults(func=exec) + + ns = parser.parse_args() + if not hasattr(ns, 'func'): + parser.error('Need an action to perform') + ns.func(ns) + +if __name__ == '__main__': + main() diff --git a/scripts/docker/docker_travis.sh b/scripts/docker/docker_travis.sh new file mode 100755 index 00000000..170deecf --- /dev/null +++ b/scripts/docker/docker_travis.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +curdir=$(dirname "$(readlink -f "$0")") + +docker=$1 + +# Build docker image +"$curdir/docker_tool.py" build -d "$docker" -t openrw_build_image + +# Start docker container + add travis user +"$curdir/docker_tool.py" create -t openrw_build_image -n openrw_builder -U travis -e XDG_RUNTIME_DIR=/tmp CI=$CI TRAVIS=$TRAVIS TRAVIS_COMMIT=$TRAVIS_COMMIT TRAVIS_EVENT_TYPE=$TRAVIS_EVENT_TYPE TRAVIS_REPO_SLUG=$TRAVIS_REPO_SLUG TRAVIS_BRANCH=$TRAVIS_BRANCH + +# execute test +"$curdir/docker_tool.py" exec -n openrw_builder -U travis -- /bin/bash -c "ctest -S /src/cmake/ctest/travis_script.ctest -VV -DSRC_DIR=/src -DBIN_DIR=/build" diff --git a/scripts/docker/fedora_latest.docker b/scripts/docker/fedora_latest.docker new file mode 100644 index 00000000..36096f07 --- /dev/null +++ b/scripts/docker/fedora_latest.docker @@ -0,0 +1,20 @@ +FROM fedora:latest + +# ffmpeg-devel needs rpmfusion +RUN dnf install -y https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm \ + https://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm + +RUN dnf update -y \ + && dnf install -y \ + boost-devel \ + gcc gcc-c++ \ + boost-devel \ + cmake \ + bullet-devel \ + ffmpeg-devel \ + glm-devel \ + openal-soft-devel \ + SDL2-devel \ + qt5-devel + +CMD ["/bin/bash"] diff --git a/scripts/docker/ubuntu_latest.docker b/scripts/docker/ubuntu_latest.docker new file mode 100644 index 00000000..811b61be --- /dev/null +++ b/scripts/docker/ubuntu_latest.docker @@ -0,0 +1,22 @@ +FROM ubuntu:rolling + +RUN apt-get update \ + && apt-get install --no-install-recommends --no-upgrade -y \ + build-essential \ + cmake \ + gcc-7 \ + g++-7 \ + libavcodec-dev \ + libavformat-dev \ + libboost-filesystem-dev \ + libboost-program-options-dev \ + libbullet-dev \ + libglm-dev \ + libopenal-dev \ + libsdl2-dev \ + libboost-test-dev \ + libqt5opengl5-dev \ + iwyu \ + qt5-default + +CMD ["/bin/bash"]