###########################################################
#####                                                 #####
#####       DO  NOT  EDIT  THIS  FILE  BY  HAND       #####
#####                                                 #####
###########################################################
#####                                                 #####
##### This file is autogenerated from misc/gitlab/.   #####
##### Edit those files and run `make gitlab` instead. #####
#####                                                 #####
###########################################################

variables:
  DEBIAN_FRONTEND: noninteractive
  LC_ALL: C.UTF-8
  GIT_STRATEGY: fetch
  DOCKER_CMD: docker --config="$HOME/.docker/$CI_JOB_ID/"
  IMG_BASE: registry.nic.cz/labs/bird
  TOOLS_DIR: /home/gitlab-runner/bird-tools
  STAYRTR_BINARY: /usr/local/bin/stayrtr

stages:
  - consistency
  - image
  - build
  - pkg
  - install
  - test

## Common rules
# Ignore WIP commits
.never-wip: &never-wip
  if: $CI_COMMIT_MESSAGE =~ /^(fixup! )*WIP/
  when: never
# Run for stable branches
.if-stable: &if-stable
  if: ($CI_COMMIT_BRANCH =~ /^(stable-.*|thread-next|master)$/ || $CI_PIPELINE_SOURCE == "merge_request_event")
  when: always
# Do run for tags
.if-tag: &if-tag
  if: $CI_COMMIT_TAG
  when: always
# Never run for tags
.never-tag: &never-tag
  if: $CI_COMMIT_TAG
  when: never

## Consistency checks for stable branches
commit-messages:
  stage: consistency
  image: registry.nic.cz/labs/bird:docbuilder
  script:
  - tools/git-check-commits
  rules:
  - *if-stable
  - when: never

## Tag check
tag-collect:
  stage: consistency
  image: registry.nic.cz/labs/bird:docbuilder
  script:
  - python3 -m venv venv
  - . venv/bin/activate
  - pip3 install requests
  - tools/git-check-tag-local $CI_COMMIT_TAG
  - tools/git-check-tag-ci $CI_COMMIT_SHA
  artifacts:
    paths:
      - obj/doc/bird-singlepage.html
      - bird-*.tar.gz
      - pkg/pkgs/*
      - pkg/srcpkgs/*
  rules:
  - *if-tag
  - when: never

## Default test job rules
.test-job: &test-job
  rules:
  - *never-wip
  - *never-tag
  - when: always

############################
## Docker builder rebuild ##
############################
# We are running all the build / packaging tests in Dockers (unless otherwise)
# and these are rules to build these docker images. These are expensive to run
# and should run only if needed.
#
# Modify the appropriate dockerfile to rebuild these images

.docker: &docker-build
  stage: image
  script:
  - $DOCKER_CMD login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.nic.cz
  # Make sure we refresh the base image if it updates (eg. security updates, etc)
  # If we do just the build, cache is always reused and the freshness of the
  # base image is never checked. However, pull always asks and updates the
  # image only if it changed ‒ therefore, the cache is used unless there's a
  # change.
  - $DOCKER_CMD pull `sed -ne 's/^FROM //p' "misc/docker/$IMG_NAME/Dockerfile"`
  - $DOCKER_CMD build -t "bird:$IMG_NAME" "misc/docker/$IMG_NAME"
  - $DOCKER_CMD tag "bird:$IMG_NAME" "$IMG_BASE:$IMG_NAME"
  - $DOCKER_CMD push "$IMG_BASE:$IMG_NAME"
  after_script:
  - rm -f "$HOME/.docker/$CI_JOB_ID/" # cleanup the credentials
  tags:
  # That's Docker in Docker
  - dind
  rules:
    # Never rebuild for WIP commits
  - *never-wip

    # Never rebuild for tags
  - if: '$CI_COMMIT_TAG'
    when: never

    # Never rebuild for new branches
  - if: $CI_COMMIT_BEFORE_SHA == "0000000000000000000000000000000000000000"
    when: never

    # Do any change in Dockerfile (e.g. change a comment) to rebuild the image
    # FIXME: This probably belongs to bird-tools instead, we may end up with
    # screwed up docker repository in case of colliding image updates
  - changes:
    - misc/docker/$IMG_NAME/Dockerfile
    when: always

  - when: never

{% for docker in [ { "name": "docbuilder" } ] + distros %}
docker-{{ docker["name"] }}:
  variables:
    IMG_NAME: "{{ docker["name"] }}"
  <<: *docker-build
{% endfor %}

#####################################################
## Linux distro build tests inside Docker builders ##
#####################################################

## Build stage
#
# Now we compile and run unit tests ... in every single distribution.
# Every task needs its docker, see above.

.build: &build-base
  <<: *test-job
  stage: build
  script:
    - if [ "$CI_PIPELINE_SOURCE" == "merge_request_event" ]; then export BRANCH=mergerequest-$CI_MERGE_REQUEST_IID; else export BRANCH=$CI_COMMIT_BRANCH; fi
    - tools/version && ( echo -n "BIRD version "; tools/version ) > version-expected
    - |
      STABLE_VERSION="`cat VERSION`"
      if [ "$CI_COMMIT_MESSAGE" == "NEWS and version update
      " ]; then
        if [ "${STABLE_VERSION}" == "`tools/version`" ]; then
          echo "Stable version precheck OK"
        else
          echo "Stable version discrepancy: $STABLE_VERSION vs. $(tools/version)"
          exit 1
        fi
      else
        if grep -qF "BIRD version ${STABLE_VERSION}+branch" version-expected; then
          true
        else
          echo -n "Commit $CI_COMMIT_SHA message $CI_COMMIT_MESSAGE expects version "
          cat version-expected
          exit 1
        fi
      fi
    - autoreconf
    - ./configure CPPFLAGS="$CPPFLAGS" LDFLAGS="$LDFLAGS" $CONFIGURE_OPTIONS
    # Detect which make is available
    - MAKE=make
    - which gmake 2>/dev/null >/dev/null && MAKE=gmake
    - $MAKE
    - $MAKE check
    # Build docs when tools are available
    - if which linuxdoc pdflatex sgmlsasp >/dev/null ; then $MAKE docs ; fi
    # Check that the reported version is the right one
    - ./bird --version |& tee obj/version-built
    - diff obj/version-built version-expected

.build-docker-linux-amd64: &build-docker-linux-amd64
  <<: *build-base
  tags:
    - docker
    - linux
    - amd64

{% for dist in distros %}
build-{{dist["name"]}}:
  <<: *build-docker-linux-amd64
  needs:
    - job: docker-{{ dist["name"] }}
      optional: true
  image: registry.nic.cz/labs/bird:{{ dist["name"] }}
{%- if 'variables' in dist %}
  variables:
{{ dist["variables"] | to_yaml | indent(4, true) }}
{%- endif %}
{% endfor %}

#######################################################
## A special task for preparing the release archives ##
#######################################################
build-release:
  <<: *test-job
  image: registry.nic.cz/labs/bird:docbuilder
  needs: 
    - job: docker-docbuilder
      optional: true
  stage: build
  tags:
    - docker
    - linux
  script:
    - if [ "$CI_PIPELINE_SOURCE" == "merge_request_event" ]; then export BRANCH=mergerequest-$CI_MERGE_REQUEST_IID; else export BRANCH=$CI_COMMIT_BRANCH; fi
    - autoreconf
    - ./configure --with-protocols= --disable-client
    - make obj/doc/bird-singlepage.html
    - tools/make-archive
  artifacts:
    paths:
      - obj/doc/bird-singlepage.html
      - bird-*.tar.gz
    expire_in: 1 day

# Packaging rules
# As we support some ancient versions of different distributions,
# we need to keep several different machineries. It's not so bad
# but it's bad nevertheless.
#
# We do NOT build separate documentation packages in these rules.

.pkg-deb: &pkg-deb
  <<: *test-job
  stage: pkg
  script:
    - if [ "$CI_PIPELINE_SOURCE" == "merge_request_event" ]; then export BRANCH=mergerequest-$CI_MERGE_REQUEST_IID; else export BRANCH=$CI_COMMIT_BRANCH; fi
    - tools/make-deb
  artifacts:
    paths:
      - pkg/pkgs/*
      - pkg/srcpkgs/*

.pkg-rpm: &pkg-rpm
  <<: *test-job
  stage: pkg
  script:
    - if [ "$CI_PIPELINE_SOURCE" == "merge_request_event" ]; then export BRANCH=mergerequest-$CI_MERGE_REQUEST_IID; else export BRANCH=$CI_COMMIT_BRANCH; fi
    - STABLE_BUILDDIR=true tools/make-rpm
  artifacts:
    paths:
      - pkg/pkgs/*
      - pkg/srcpkgs/*


{% for dist in distros %}
pkg-{{ dist["name"] }}:
  <<: *pkg-{{ dist["type"] }}
  needs:
    - job: build-{{ dist["name"] }}
      artifacts: false
    - job: build-release
  image: registry.nic.cz/labs/bird:{{ dist["name"] }}
{%- if 'variables' in dist %}
  variables:
{{ dist["variables"] | to_yaml | indent(4, true) }}
{%- endif %}
{% endfor %}

## Package installability checks

.install-deb: &install-deb
  <<: *test-job
  stage: install
  script:
    # check that bird is _not_ installed now and no user or group bird exists
    - |
      if bird --version >/dev/null 2>&1; then
        echo "Error: BIRD unexpectedly installed"
        exit 1
      fi
      if id -g bird >/dev/null 2>&1; then
        echo "Error: User group 'bird' unexpectedly exist before installation"
        exit 1
      fi
      if id -u bird >/dev/null 2>&1; then
        echo "Error: User 'bird' unexpectedly exist before installation"
        exit 1
      fi
    # install packages
    - find pkg/pkgs/ -type f -name '*.deb' '(' -ls -exec dpkg -i '{}' ';' ')'
    # test that installation is successful
    - ./tools/test-install "$CI_COMMIT_MESSAGE"

.install-rpm: &install-rpm
  <<: *test-job
  stage: install
  script:
    # check that bird is _not_ installed now and no user or group bird exists
    - |
      if bird --version >/dev/null 2>&1; then
        echo "Error: BIRD unexpectedly installed"
        exit 1
      fi
      if id -g bird >/dev/null 2>&1; then
        echo "Error: User group 'bird' exist before installation"
        exit 1
      fi
      if id -u bird >/dev/null 2>&1; then
        echo "Error: User 'bird' exist before installation"
        exit 1
      fi
    # install packages
    - find pkg/pkgs/ -type f -name '*.rpm' '(' -ls -exec $RPM_INSTALL_CMD '{}' ';' ')'
    # test that installation is successful
    - ./tools/test-install "$CI_COMMIT_MESSAGE"

{% for dist in distros %}
install-{{ dist["name"] }}:
  <<: *install-{{ dist["type"] }}
  needs:
    - job: pkg-{{ dist["name"] }}
  image: registry.nic.cz/labs/bird:{{ dist["name"] }}
  variables:
{%- if dist["name"][:12] == "opensuse-16." %}
    RPM_INSTALL_CMD: zypper --non-interactive --no-gpg-checks in
{%- elif dist["type"] == "rpm" %}
    RPM_INSTALL_CMD: rpm -i
{%- endif %}
{% endfor %}

###################################
## Non-linux build tests in QEMU ##
###################################
.build-birdlab-base: &build-birdlab-base
  <<: *build-base
  stage: build
#  script:
#    - export BRANCH=$CI_COMMIT_BRANCH
#    - autoreconf
#    - ./configure $CONFIGURE_OPTIONS
#    - gmake
#    - gmake check

{% for test in birdlab %}
build-birdlab-{{ test['name'] }}:
  <<: *build-birdlab-base
{%- if 'variables' in test %}
  variables:
{{ test['variables'] | to_yaml | indent(4, true) }}{%- endif %}
  tags:
    - birdlab-{{ test['dist'] if 'dist' in test else test['name'] }}
    - amd64
{% endfor %}

#########################
## Partial build tests ##
#########################

.build-only: &build-only
  <<: *build-docker-linux-amd64
  image: registry.nic.cz/labs/bird:{{ partial_build_image["name"] }}
  needs:
    - job: docker-{{ partial_build_image["name"] }}
      optional: true

{% for test in partial_build %}
partial-build-linux-{{ test["protocols"] }}:
  <<: *build-only
  variables:
    CONFIGURE_OPTIONS: --with-protocols={{ test["protocols"] }}
{% endfor %}

################################
## Netlab functionality tests ##
################################

build-netlab:
  <<: *test-job
  stage: build
  variables:
    BDIR: build-netlab
  tags:
    - netlab
    - amd64
  script:
    - if [ "$CI_PIPELINE_SOURCE" == "merge_request_event" ]; then export BRANCH=mergerequest-$CI_MERGE_REQUEST_IID; else export BRANCH=$CI_COMMIT_BRANCH; fi
    - autoreconf
    - mkdir $BDIR
    - cd $BDIR
    - ../configure
    - make
  artifacts:
    paths:
      - $BDIR/bird
      - $BDIR/birdc
    expire_in: 2 hours

.netlab-test: &test-base
  <<: *test-job
  stage: test
  needs: [build-netlab]
  tags:
    - netlab
    - amd64
  script:
    - sudo rm -rf netlab-failure
    - DIR=$(pwd)
    - cd $TOOLS_DIR
    - sudo git clean -fx
    - git pull --ff-only
    - "mv $DIR/build-netlab/* netlab/common/"
    - ln -s $STAYRTR_BINARY netlab/common/stayrtr
    - cd netlab
    - sudo ./stop
    - ulimit -f 1048576 # Protect the filesystem from overflowing by log bloat
    - sudo ./runtest -s v2 -m check $TEST_NAME
  after_script:
    - DIR=$(pwd)
    - cd $TOOLS_DIR/netlab
    - sudo ./stop
    - "mkdir $DIR/netlab-failure"
    - git status --porcelain > $DIR/netlab-failure.log
    - for f in $(git status --porcelain | sed -rn 's#^.[^DRT] netlab/##p'); do mkdir -p $DIR/netlab-failure/$(dirname $f); sudo chmod a+rw $f; sudo mv $f $DIR/netlab-failure/$(dirname $f); done
  artifacts:
    when: on_failure
    untracked: true

{% for test in netlab %}
test-{{ test["name"] }}:
  <<: *test-base
  variables:
    TEST_NAME: cf-{{ test["name"] }}
{% endfor %}
