diff --git a/.ci/ArchLinux/Dockerfile b/.ci/ArchLinux/Dockerfile new file mode 100644 index 00000000..b9f96e29 --- /dev/null +++ b/.ci/ArchLinux/Dockerfile @@ -0,0 +1,14 @@ +from archlinux:latest + +RUN pacman --sync --refresh --sysupgrade --needed --noconfirm \ + base-devel \ + ccache \ + cmake \ + git \ + protobuf \ + qt5-base \ + qt5-multimedia \ + qt5-svg \ + qt5-tools \ + qt5-websockets \ + && pacman --sync --clean --clean --noconfirm diff --git a/.ci/DebianBuster/Dockerfile b/.ci/DebianBuster/Dockerfile new file mode 100644 index 00000000..f81a08ac --- /dev/null +++ b/.ci/DebianBuster/Dockerfile @@ -0,0 +1,23 @@ +FROM debian:buster + +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential \ + ccache \ + clang-format \ + cmake \ + file \ + g++ \ + git \ + liblzma-dev \ + libprotobuf-dev \ + libqt5multimedia5-plugins \ + libqt5sql5-mysql \ + libqt5svg5-dev \ + libqt5websockets5-dev \ + protobuf-compiler \ + qt5-default \ + qtbase5-dev \ + qtmultimedia5-dev \ + qttools5-dev-tools \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* diff --git a/.ci/Fedora31/Dockerfile b/.ci/Fedora31/Dockerfile new file mode 100644 index 00000000..a5fa5ebb --- /dev/null +++ b/.ci/Fedora31/Dockerfile @@ -0,0 +1,20 @@ +FROM fedora:31 + +RUN dnf install -y \ + @development-tools \ + ccache \ + cmake \ + desktop-file-utils \ + file \ + gcc-c++ \ + git \ + hicolor-icon-theme \ + libappstream-glib \ + protobuf-devel \ + qt5-{qttools,qtsvg,qtmultimedia,qtwebsockets}-devel \ + rpm-build \ + sqlite-devel \ + wget \ + xz-devel \ + zlib-devel \ + && dnf clean all diff --git a/.ci/UbuntuBionic/Dockerfile b/.ci/UbuntuBionic/Dockerfile index 96e120a8..459ed0d6 100644 --- a/.ci/UbuntuBionic/Dockerfile +++ b/.ci/UbuntuBionic/Dockerfile @@ -2,21 +2,22 @@ FROM ubuntu:bionic RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ + ccache \ clang-format \ + cmake \ file \ g++ \ git \ - ccache \ - cmake \ liblzma-dev \ libprotobuf-dev \ libqt5multimedia5-plugins \ - libqt5svg5-dev \ libqt5sql5-mysql \ + libqt5svg5-dev \ libqt5websockets5-dev \ protobuf-compiler \ qt5-default \ + qtmultimedia5-dev \ qttools5-dev \ qttools5-dev-tools \ - qtmultimedia5-dev \ + && apt-get clean \ && rm -rf /var/lib/apt/lists/* diff --git a/.ci/travis-compile.sh b/.ci/travis-compile.sh index f2b8d5b7..db461f94 100755 --- a/.ci/travis-compile.sh +++ b/.ci/travis-compile.sh @@ -68,6 +68,10 @@ set -e mkdir -p build cd build +if ! [[ $CORE_AMOUNT ]]; then + CORE_AMOUNT="2" # travis machines have 2 cores +fi + # Add cmake flags if [[ $MAKE_SERVER ]]; then flags+=" -DWITH_SERVER=1" @@ -92,7 +96,7 @@ fi # Compile cmake --version cmake .. $flags -make -j2 +make -j"$CORE_AMOUNT" if [[ $MAKE_TEST ]]; then make test @@ -105,9 +109,9 @@ fi if [[ $MAKE_PACKAGE ]]; then make package if [[ $PACKAGE_NAME ]]; then - found=$(find . -maxdepth 1 -type f -name "Cockatrice-*.*" -print -quit) - path=${found%/*} - file=${found##*/} + found="$(find . -maxdepth 1 -type f -name "Cockatrice-*.*" -print -quit)" + path="${found%/*}" + file="${found##*/}" if [[ ! $file ]]; then echo "could not find package" >&2 exit 1 diff --git a/.ci/travis-docker.sh b/.ci/travis-docker.sh new file mode 100644 index 00000000..3ba66b40 --- /dev/null +++ b/.ci/travis-docker.sh @@ -0,0 +1,141 @@ +#!/bin/bash + +# This script is to be sourced in .travis.yaml from the project root directory, do not use it from somewhere else. +# Creates or loads docker images to use in compilation, creates RUN function to start compilation on the docker image. +# --get loads the image from a previously saved image cache, will build if no image is found +# --build builds the image from the Dockerfile in .ci/$NAME +# --save stores the image, if an image was loaded it will not be stored +# requires: docker +# uses env: NAME CACHE BUILD GET SAVE (correspond to args: --set-cache --build --get --save) +# sets env: RUN CCACHE_DIR IMAGE_NAME RUN_ARGS RUN_OPTS BUILD_SCRIPT +# exitcode: 1 for failure, 2 for missing dockerfile, 3 for invalid arguments +export BUILD_SCRIPT=".ci/travis-compile.sh" + +project_name="cockatrice" +save_extension=".tar.gz" +image_cache="image" +ccache_cache=".ccache" + +# Read arguments +while [[ "$@" ]]; do + case "$1" in + '--build') + BUILD=1 + shift + ;; + '--get') + GET=1 + shift + ;; + '--save') + SAVE=1 + shift + ;; + '--set-cache') + CACHE=$2 + if ! [[ -d $CACHE ]]; then + echo "could not find cache path: $CACHE" >&2 + exit 3 + fi + shift 2 + ;; + *) + if [[ $1 == -* ]]; then + echo "unrecognized option: $1" + return 3 + fi + NAME="$1" + shift + ;; + esac +done + +# Setup +if ! [[ $NAME ]]; then + echo "no build name given" >&2 + return 3 +fi + +export IMAGE_NAME="${project_name,,}_${NAME,,}" + +docker_dir=".ci/$NAME" +if ! [[ -r $docker_dir/Dockerfile ]]; then + echo "could not find Dockerfile in $docker_dir" >&2 + return 2 # even if the image is cached, we do not want to run if there is no way to build this image +fi + +if ! [[ -d $CACHE ]]; then + echo "could not find cache dir: $CACHE" >&2 + unset CACHE +else + if [[ $GET || $SAVE ]]; then + img_dir="$CACHE/$image_cache" + img_save="$img_dir/$IMAGE_NAME$save_extension" + if ! [[ -d $img_dir ]]; then + echo "could not find image dir: $img_dir" >&2 + mkdir -p "$img_dir" + fi + fi + export CCACHE_DIR="$CACHE/$ccache_cache" + if ! [[ -d $CCACHE_DIR ]]; then + echo "could not find ccache dir: $CCACHE_DIR" >&2 + mkdir -p "$CCACHE_DIR" + fi +fi + + +# Get the docker image from previously stored save +if [[ $GET ]]; then + if [[ $img_save ]] && docker load --input "$img_save"; then + echo "loaded image" + docker images + unset BUILD # do not overwrite the loaded image with build + unset SAVE # do not overwrite the stored image with the same image + if [[ $(find "$CCACHE_DIR" -type f -print -quit) ]]; then # check contents of ccache + echo "setting ccache to readonly" + export RUN_ARGS="$RUN_ARGS -e CCACHE_READONLY=1 -e CCACHE_NOSTATS=1" # do not overwrite ccache + else + echo "ccache is empty: $(find "$CCACHE_DIR")" >&2 + fi + else + echo "could not load cached image, building instead" >&2 + BUILD=1 + fi +fi + +# Build the docker image from dockerfile +if [[ $BUILD ]]; then + if docker build --tag "$IMAGE_NAME" "$docker_dir"; then + echo "built image" + docker images + else + echo "could not build image $IMAGE_NAME" >&2 + return 1 + fi +fi + +# Save docker image to cache (compressed) +if [[ $SAVE ]]; then + if [[ $img_save ]] && docker save --output "$img_save" "$IMAGE_NAME"; then + echo "saved image to: $img_save" + else + echo "could not save image $IMAGE_NAME" >&2 + fi +fi + +# Set compile function, runs the compile script on the image, passes arguments to the script +function RUN () +{ + echo "running image:" + if docker images | grep "$IMAGE_NAME"; then + args="--mount type=bind,source=$(pwd),target=/src -w=/src" + if [[ $CCACHE_DIR ]]; then + args+=" --mount type=bind,source=$CCACHE_DIR,target=/.ccache -e CCACHE_DIR=/.ccache" + fi + docker run $args $RUN_ARGS "$IMAGE_NAME" bash "$BUILD_SCRIPT" $RUN_OPTS $@ + return $? + else + echo "could not find docker image: $IMAGE_NAME" >&2 + return 3 + fi +} diff --git a/.travis.yml b/.travis.yml index 4465a8ae..e4ce2696 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ os: linux +dist: bionic language: cpp compiler: gcc @@ -21,29 +22,75 @@ jobs: if: tag IS NOT present os: linux services: docker - env: NAME=UbuntuBionic + language: minimal + env: NAME=UbuntuBionic CACHE=$HOME/$NAME cache: directories: - - $HOME/$NAME/ - before_install: docker build -t "cockatrice_${NAME,,}" .ci/$NAME && mkdir -p $HOME/$NAME/.ccache - script: docker run --mount "type=bind,source=$(pwd),target=/src" -w="/src" - --mount "type=bind,source=$HOME/$NAME/.ccache,target=/.ccache" -e "CCACHE_DIR=/.ccache" - "cockatrice_${NAME,,}" - bash .ci/travis-compile.sh --server --test --debug + - $CACHE + before_install: source .ci/travis-docker.sh --build + script: RUN --server --test --debug - name: Ubuntu Bionic (Release) if: (branch = master AND NOT type = pull_request) OR tag IS present os: linux services: docker - env: NAME=UbuntuBionic + language: minimal + env: NAME=UbuntuBionic CACHE=$HOME/$NAME cache: directories: - - $HOME/$NAME/ - before_install: docker build -t "cockatrice_${NAME,,}" .ci/$NAME && mkdir -p $HOME/$NAME/.ccache - script: docker run --mount "type=bind,source=$(pwd),target=/src" -w="/src" - --mount "type=bind,source=$HOME/$NAME/.ccache,target=/.ccache" -e "CCACHE_DIR=/.ccache" - "cockatrice_${NAME,,}" - bash .ci/travis-compile.sh --server --package "$NAME" --release + - $CACHE + before_install: source .ci/travis-docker.sh --build + script: RUN --server --package $NAME --release + + + #Debian Buster (on Docker) + - name: Debian Buster (Compile) + if: tag IS NOT present + os: linux + services: docker + language: minimal + env: NAME=DebianBuster CACHE=$HOME/$NAME + cache: + directories: + - $CACHE + before_install: source .ci/travis-docker.sh --build + script: RUN --server + + - name: Debian Buster (Release) + if: (branch = master AND NOT type = pull_request) OR tag IS present + os: linux + services: docker + language: minimal + env: NAME=DebianBuster CACHE=$HOME/$NAME + cache: + directories: + - $CACHE + before_install: source .ci/travis-docker.sh --build + script: RUN --server --package $NAME --release + + + #Fedora 31 (on docker) + - name: Fedora 31 (Compile) + if: tag IS NOT present + services: docker + language: minimal + env: NAME=Fedora31 CACHE=$HOME/$NAME + cache: + directories: + - $CACHE + before_install: source .ci/travis-docker.sh --build + script: RUN --server + + - name: Fedora 31 (Release) + if: (branch = master AND NOT type = pull_request) OR tag IS present + services: docker + language: minimal + env: NAME=Fedora31 CACHE=$HOME/$NAME + cache: + directories: + - $CACHE + before_install: source .ci/travis-docker.sh --build + script: RUN --server --package $NAME RPM --release #macOS High Sierra @@ -131,6 +178,26 @@ jobs: - brew cleanup + #Arch Linux (on Docker) (allow failures) + - name: Arch Linux (Debug) + if: tag IS NOT present + os: linux + services: docker + language: minimal + env: NAME=ArchLinux CACHE=$HOME/$NAME + cache: + directories: + - $CACHE + before_install: source .ci/travis-docker.sh --build + script: RUN --server --debug + + allow_failures: + # Arch linux is always the latest version and by definition not stable + - name: Arch Linux (Debug) + # Report build completion even if optional builds are not completed + fast_finish: true + + # Builds for pull requests skip the deployment step altogether deploy: # Deploy configuration for "beta" releases