image: alpine:3.9

stages:
 - build
 - test
 - package
 - release
 - notify


#######################################################################################################################
#######################################################################################################################
#######################################################################################################################
# build + test

# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# distro.yml

.template:build:
  dependencies: []
  stage: build
  script:
    - mkdir -p build && cd build
    - ../CMake/generate.py -wm
    - cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .. -GNinja
    - ninja -j $(grep -c processor /proc/cpuinfo)
  artifacts:
    paths:
      - build/
    expire_in: 1 day

.template:test:
  dependencies: []
  stage: test
  script:
    - cd build
    - ctest . --output-on-failure -j $(grep -c processor /proc/cpuinfo)

# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# distro_alpine.yml

.config:alpine: &distro_alpine
  image: alpine:3.9
  only:
    - merge_requests

# -----------------------------------------------------------------------------

build:alpine:
  <<: *distro_alpine
  extends: .template:build
  before_script:
    - apk add --no-cache bash build-base cmake ninja python3 libexecinfo-dev libxml2-dev tclap-dev readline-dev qt5-qtbase-dev graphviz-dev jsoncpp-dev

test:alpine:
  <<: *distro_alpine
  extends: .template:test
  dependencies:
    - build:alpine
  before_script:
    - apk add --no-cache bash bc coreutils python3 cmake libexecinfo libxml2 tclap readline qt5-qtbase qt5-qtbase-x11 graphviz jsoncpp

# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# distro_arch.yml

.config:archlinux: &distro_archlinux
  image: archlinux/base
  only:
    - merge_requests

# -----------------------------------------------------------------------------

build:archlinux:
  <<: *distro_archlinux
  extends: .template:build
  before_script:
    - pacman -Syu --noconfirm base-devel cmake ninja python libxml2 tclap readline qt5-base graphviz jsoncpp
    # - pacman -Syu --noconfirm binutils && strip --remove-section=.note.ABI-tag /usr/lib/libQt5Core.so.5 # qt hack

test:archlinux:
  <<: *distro_archlinux
  extends: .template:test
  dependencies:
    - build:archlinux
  before_script:
    - pacman -Syu --noconfirm base-devel bash bc coreutils cmake ninja python libxml2 tclap readline qt5-base graphviz jsoncpp
    # - pacman -Syu --noconfirm binutils && strip --remove-section=.note.ABI-tag /usr/lib/libQt5Core.so.5 # qt hack

# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# distro_builder.yml

.config:builder: &distro_builder
  image: gitlab.fit.cvut.cz:5000/algorithms-library-toolkit/ci-docker-images/alt-builder:latest
  except:
    - tags

.build:builder:
  <<: *distro_builder
  extends: .template:build

.test:builder:
  <<: *distro_builder
  extends: .template:test

# -----------------------------------------------------------------------------

build:builder:gcc:
  extends: .build:builder

build:builder:clang:
  extends: .build:builder
  variables:
    CXX: clang++-8

test:builder:gcc:
  extends: .test:builder
  dependencies:
    - build:builder:gcc

test:builder:clang:
  extends: .test:builder
  dependencies:
    - build:builder:clang

# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# distro_debian.yml

.config:debian: &distro_debian
  image: amd64/debian:testing-slim
  only:
    - merge_requests

# -----------------------------------------------------------------------------

build:debian:
  <<: *distro_debian
  extends: .template:build
  before_script:
    - apt-get update
    - apt-get install -y build-essential cmake ninja-build python3 libxml2-dev libtclap-dev libreadline-dev qtbase5-dev graphviz-dev libjsoncpp-dev

test:debian:
  <<: *distro_debian
  extends: .template:test
  dependencies:
    - build:debian
  before_script:
    - apt-get update
    - apt-get install -y build-essential bash cmake libxml2 libreadline7 libqt5widgets5 libqt5xml5 graphviz libjsoncpp1

# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# distro_opensuse.yml

.config:opensuse:leap: &distro_opensuse-leap
  image: opensuse/leap:latest
  only:
    - merge_requests

# -----------------------------------------------------------------------------

build:opensuse:leap:
  <<: *distro_opensuse-leap
  extends: .template:build
  before_script:
    - zypper -n install python3 cmake gcc-c++ bash ninja libxml2-devel tclap readline-devel libQt5Widgets-devel libQt5Xml-devel graphviz-devel jsoncpp-devel

test:opensuse:leap:
  <<: *distro_opensuse-leap
  extends: .template:test
  dependencies:
    - build:opensuse:leap
  before_script:
    - zypper -n install bash cmake libxml2 readline libQt5Widgets5 libQt5Xml5 graphviz libjsoncpp19

# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# distro_ubuntu-lts.yml

.config:ubuntu:lts: &distro_ubuntu-lts
  image: ubuntu:latest
  only:
    - merge_requests

# -----------------------------------------------------------------------------

build:ubuntu:lts:
  <<: *distro_ubuntu-lts
  extends: .template:build
  before_script:
    - apt-get update
    - apt-get install -y build-essential cmake ninja-build python3 libxml2-dev libtclap-dev libreadline-dev qtbase5-dev graphviz-dev libjsoncpp-dev

test:ubuntu:lts:
  <<: *distro_ubuntu-lts
  extends: .template:test
  dependencies:
    - build:ubuntu:lts
  before_script:
    - apt-get update
    - apt-get install -y build-essential bash cmake libxml2 libreadline7 libqt5widgets5 libqt5xml5 graphviz libjsoncpp1

# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# distro_ubuntu-rolling.yml

.config:ubuntu:rolling: &distro_ubuntu-rolling
  image: ubuntu:rolling
  only:
    - merge_requests

# -----------------------------------------------------------------------------

build:ubuntu:rolling:
  <<: *distro_ubuntu-rolling
  extends: .template:build
  before_script:
    - apt-get update
    - apt-get install -y build-essential cmake ninja-build python3 libxml2-dev libtclap-dev libreadline-dev qtbase5-dev graphviz-dev libjsoncpp-dev

test:ubuntu:rolling:
  <<: *distro_ubuntu-rolling
  extends: .template:test
  before_script:
    - apt-get update
    - apt-get install -y build-essential bash cmake libxml2 libreadline8 libqt5widgets5 libqt5xml5 graphviz libjsoncpp1
  dependencies:
    - build:ubuntu:rolling


# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# doc.yml

doc:doc:
  stage: build
  before_script:
    - apk add --no-cache doxygen graphviz
  script:
    - doxygen
  artifacts:
    name: docs
    paths:
      - doc/
    expire_in: 1 day

# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# static-analysis.yml

.template:static-analysis:
  stage: build
  image: gitlab.fit.cvut.cz:5000/algorithms-library-toolkit/ci-docker-images/alt-builder:latest
  before_script:
    - mkdir -p build && pushd build
    - ../CMake/generate.py -wm
    - cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .. -GNinja
    - popd
  allow_failure: true # TODO: Remove
  dependencies: []
  only:
    - merge_requests
    - branches
  except:
    - tags

# -----------------------------------------------------------------------------

static-analysis:cppcheck:
  extends: .template:static-analysis
  script:
    - cppcheck -q --enable=all --project=build/compile_commands.json --suppress="*:*/contrib/*" --error-exitcode=1


static-analysis:clang-tidy:
  extends: .template:static-analysis
  script:
    - jq ".[].file" build/compile_commands.json | tr -d "\"" | grep -v "test-src" | xargs -n1 -P$(grep -c processor /proc/cpuinfo) clang-tidy-8 -p build/


#######################################################################################################################
#######################################################################################################################
#######################################################################################################################
# package + release

# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# release.yml

.template:only:nightly: &release_nightly
  only:
    refs:
      - master

.template:only:tag: &release_tag
  only:
    - tags
    - /^v.*$/

.template:package:
  stage: package
  dependencies: []

.template:release:
  stage: release
  dependencies: []


.releaser:
  extends: .template:release
  before_script:
    - apk add --no-cache curl tar
    - DISTRO=$(echo "$CI_JOB_NAME" | cut -d":" -f2)
    - MODE=$(echo "$CI_JOB_NAME" | cut -d":" -f3)
    - URL="$REPOMGR/upload/$DISTRO/$MODE"
    - if [[ $DISTRO != "sources" ]]; then URL="$URL/x86_64"; fi
  script:
    - tar cvf archive.tar $RELEASER_WILDCARD_UPLOAD
    - curl --fail --w "%{http_code}\n\n" -s --show-error -X POST -F "data=@archive.tar" $URL

# -----------------------------------------------------------------------------

# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# release_archlinux.yml

.package:archlinux:
  extends: .template:package
  image: gitlab.fit.cvut.cz:5000/algorithms-library-toolkit/ci-docker-images/archlinux-makepkg
  script:
    - pacman -Suy --noconfirm --needed base-devel gnupg
    - echo "$GPG_PRIVATE_KEY" | sudo -u builder -- gpg --no-tty --batch --import -
    - KEYGRIP=$(sudo -u builder -- gpg --with-keygrip -k $GPG_KEYID | grep Keygrip | cut -d= -f2 | tr -d ' ')
    - sudo -u builder -- /usr/lib/gnupg/gpg-preset-passphrase --preset --passphrase "$GPG_PASSPHRASE" "$KEYGRIP"
    - sudo -u builder -- makepkg --syncdeps --noconfirm --sign --key $GPG_KEYID
  artifacts:
    paths:
      - "*.pkg.tar.xz*"
    expire_in: 1 day
  variables:
    PACKAGER: "Tomáš Pecka <peckato1@fit.cvut.cz>"

# -----------------------------------------------------------------------------

package:archlinux:nightly:
  <<: *release_nightly
  extends: .package:archlinux
  before_script:
    - cp extra/distro/arch/nightly/PKGBUILD .
    - chown builder:builder PKGBUILD

package:archlinux:release:
  <<: *release_tag
  extends: .package:archlinux
  before_script:
    - cp extra/distro/arch/release/PKGBUILD .
    - chown builder:builder PKGBUILD

# -----------------------------------------------------------------------------
.release:archlinux:
  extends: .releaser
  variables:
    RELEASER_WILDCARD_UPLOAD: "*.pkg.tar.xz*"

release:archlinux:nightly:
  <<: *release_nightly
  extends: .release:archlinux
  environment:
    name: arch-nightly
    url: https://repository.alt.pecka.me/archlinux/nightly/x86_64/
  dependencies:
    - package:archlinux:nightly

release:archlinux:release:
  <<: *release_tag
  extends: .release:archlinux
  environment:
    name: arch-release
    url: https://repository.alt.pecka.me/archlinux/release/x86_64/
  dependencies:
    - package:archlinux:release


# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# release_docker.yml

.package:docker: &docker
  extends: .template:package
  cache: {}  # disable
  services:
    - docker:dind
  variables:
    DOCKER_DRIVER: overlay2
    DOCKER_HOST: docker
    # ---------
    IMAGE_CLI: $CI_REGISTRY_IMAGE/cli
    IMAGE_GUI: $CI_REGISTRY_IMAGE/gui
    IMAGE_ALL: $CI_REGISTRY_IMAGE
    TAG_NIGHTLY: nightly
    TAG_RELEASE: $CI_COMMIT_REF_NAME
    TAG_LATEST:  latest
  before_script:
    - apk add --no-cache docker
    - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
    - docker info
  dependencies: []
  artifacts:
    paths:
      - images.tar
    expire_in: 1 day

# -----------------------------------------------------------------------------

package:docker:nightly:
  <<: *release_nightly
  <<: *docker
  extends: .package:docker
  script:
    - docker build --target=deploy-cli -f extra/docker/Dockerfile.master -t "$IMAGE_CLI:$TAG_NIGHTLY" .
    - docker build --target=deploy-all -f extra/docker/Dockerfile.master -t "$IMAGE_ALL:$TAG_NIGHTLY" .
    - docker tag "$IMAGE_ALL:$TAG_NIGHTLY" "$IMAGE_GUI:$TAG_NIGHTLY" # gui-version is now only a symlink to all-version
    - docker run "$IMAGE_CLI:$TAG_NIGHTLY" /usr/bin/aql2 --help
    - docker run "$IMAGE_GUI:$TAG_NIGHTLY" /usr/bin/aql2 --help
    - docker run "$IMAGE_ALL:$TAG_NIGHTLY" /usr/bin/aql2 --help
    - docker save -o images.tar "$IMAGE_CLI:$TAG_NIGHTLY" "$IMAGE_GUI:$TAG_NIGHTLY" "$IMAGE_ALL:$TAG_NIGHTLY"

package:docker:release:
  <<: *release_tag
  <<: *docker
  extends: .package:docker
  script:
    - docker build --target=deploy-cli -f extra/docker/Dockerfile.master -t "$IMAGE_CLI:$TAG_NIGHTLY" .
    - docker build --target=deploy-all -f extra/docker/Dockerfile.master -t "$IMAGE_ALL:$TAG_NIGHTLY" .
    - docker tag "$IMAGE_ALL:$TAG_RELEASE" "$IMAGE_GUI:$TAG_RELEASE" # gui-version is now only a symlink to all-version
    - docker tag "$IMAGE_ALL:$TAG_LATEST"  "$IMAGE_GUI:$TAG_LATEST"  # gui-version is now only a symlink to all-version
    - docker run "$IMAGE_ALL:$TAG_RELEASE" /usr/bin/aql2 --help
    - docker run "$IMAGE_CLI:$TAG_RELEASE" /usr/bin/aql2 --help
    - docker run "$IMAGE_GUI:$TAG_RELEASE" /usr/bin/aql2 --help
    - docker save -o images.tar "$IMAGE_CLI:$TAG_RELEASE" "$IMAGE_GUI:$TAG_RELEASE" "$IMAGE_ALL:$TAG_RELEASE"

# -----------------------------------------------------------------------------

release:docker:nightly:
  <<: *release_nightly
  <<: *docker
  extends: .template:release
  environment:
    name: docker-nightly
    url: https://gitlab.fit.cvut.cz/algorithms-library-toolkit/automata-library/container_registry
  script:
    - docker load -i images.tar
    - docker push "$IMAGE_CLI:$TAG_NIGHTLY"
    - docker push "$IMAGE_GUI:$TAG_NIGHTLY"
    - docker push "$IMAGE_ALL:$TAG_NIGHTLY"
  dependencies:
    - package:docker:nightly

release:docker:release:
  <<: *release_tag
  <<: *docker
  extends: .template:release
  environment:
    name: docker-release
    url: https://gitlab.fit.cvut.cz/algorithms-library-toolkit/automata-library/container_registry
  script:
    - docker load -i images.tar
    - docker push "$IMAGE_CLI:$TAG_RELEASE"
    - docker push "$IMAGE_GUI:$TAG_RELEASE"
    - docker push "$IMAGE_ALL:$TAG_RELEASE"
  dependencies:
    - package:docker:release


# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# release_sources.yml

.package:sources:
  extends: .template:package
  before_script:
    - apk add --no-cache git gnupg
    - mkdir -p ~/.gnupg && echo -ne 'allow-preset-passphrase\nmax-cache-ttl 60480000\ndefault-cache-ttl 60480000\n' > ~/.gnupg/gpg-agent.conf
    - echo "$GPG_PRIVATE_KEY" | gpg --no-tty --batch --import -
    - KEYGRIP=$(gpg --with-keygrip -k $GPG_KEYID | grep Keygrip | cut -d= -f2 | tr -d ' ')
    - /usr/libexec/gpg-preset-passphrase --preset --passphrase "$GPG_PASSPHRASE" "$KEYGRIP"

  artifacts:
    paths:
      - "*.tar.gz*"
    expire_in: 1 day

package:sources:nightly:
  <<: *release_nightly
  extends: .package:sources
  script:
     - FILENAME=algorithms-library-$(git describe --long --tags --match="v*" |  sed 's/^v//;s/\([^-]*-g\)/r\1/;s/-/./g').tar.gz
     - git archive --format=tar.gz --prefix="algorithms-library/" HEAD -o $FILENAME
     - gpg --armor --detach-sig -o $FILENAME.sig $FILENAME

package:sources:release:
  <<: *release_tag
  extends: .package:sources
  script:
     - FILENAME=algorithms-library-$(git describe  --tags --match="v*" --abbrev=0 | sed 's/^v//g').tar.gz
     - git archive --format=tar.gz --prefix="algorithms-library/" HEAD -o $FILENAME
     - gpg --armor --detach-sig -o $FILENAME.sig $FILENAME

# -----------------------------------------------------------------------------

.release:sources:
  extends: .releaser
  variables:
    RELEASER_WILDCARD_UPLOAD: "*.tar.gz*"

release:sources:nightly:
  <<: *release_nightly
  extends: .release:sources
  environment:
    name: sources-nightly
    url: https://repository.alt.pecka.me/sources/nightly/
  dependencies:
    - package:sources:nightly

release:sources:release:
  <<: *release_tag
  extends: .release:sources
  environment:
    name: sources-release
    url: https://repository.alt.pecka.me/sources/release/
  dependencies:
    - package:sources:release


#######################################################################################################################
#######################################################################################################################
#######################################################################################################################
# notify

.template:notify:
  stage: notify
  before_script:
    - apk add --no-cache curl
  dependencies: []

# -----------------------------------------------------------------------------

notify:pyalib:
  extends: .template:notify
  script:
    - curl -X POST -F token="$PY_ALIB_TOKEN" -F ref=master https://gitlab.fit.cvut.cz/api/v4/projects/11497/trigger/pipeline
  only:
    refs:
      - master