stages:
    - "docker"
    - "test"
    - "deploy"
    - "cleanup"

variables:
    DOCKER_VERSION: 18.09.9
    IMAGE_REGISTRY: renewal/recsystems-baseline

# Override the default workflow rules to only run pipelines on the master
# branch, merge requests, or branches that contain the string 'ci/'
# TODO: When gitlri.lri.fr is upgraded change this to using workflow.rules
#workflow:
#  rules:
#    - if: $CI_MERGE_REQUEST_ID
#    - if: $CI_COMMIT_TAG
#    - if: $CI_COMMIT_REF_NAME == "master" || $CI_COMMIT_REF_NAME =~ /^(.+\/)?ci[-\/].+/
.only: &only
    - master
    - /^(.+\/)?ci[-\/].+/
    - merge_requests


# build the Docker image
docker:build:
    stage: "docker"
    image: "docker:${DOCKER_VERSION}"
    only: *only
    before_script:
        - "docker info"
    script:
        - >
            docker build --cache-from ${IMAGE_REGISTRY}:master
            --tag ${IMAGE_REGISTRY}:${CI_COMMIT_SHA} .


.test: &test
    before_script:
        - "pip install --upgrade pip"
        - "pip install -r requirements.txt"
        - "pip install .[tests]"
        - "pip install pytest pytest-cov"
    script:
        - >
            pytest -v --color=yes --cov --cov-report=term
            --cov-report=xml --junit-xml=pytest-xunit.xml
    only: *only
    artifacts:
        reports:
            junit: pytest-xunit.xml
            # enable once we have coverage reports enabled on gitlab.lri.fr
            #cobertura: coverage.xml


test:python3.7:
    stage: "test"
    image: "python:3.7"
    <<: *test


# test the Docker image
test:docker:
    stage: "test"
    image: "python:3.7"
    only: *only
    <<: *test
    variables:
        CI_NETWORK_NAME: "${CI_PROJECT_PATH_SLUG}-${CI_BUILD_ID}"
        CI_TEMP_CONTAINER_NAME: "${CI_PROJECT_PATH_SLUG}-${CI_BUILD_ID}-test-docker"
    before_script:
        # need to actually install the Docker client somewhere
        - curl -fsSLO https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKER_VERSION}.tgz
        - tar xzvf docker-${DOCKER_VERSION}.tgz --strip 1 -C /usr/local/bin docker/docker
        - rm docker-${DOCKER_VERSION}.tgz
        - pip install --upgrade pip
        - pip install -r requirements.txt
        - pip install .[tests]
        - pip install pytest-error-for-skips
        # now we actually commit the current Docker image so we can create a
        # new container from it that we'll connect to the test network.
        # newer versions of GitLab CI support a feature of
        # automatically-created per-build networks, but since the current
        # GitLab on this instance does not have that feature we have to roll
        # our own
        - >
            export CI_CONTAINER_NAME=$(docker ps --format={{.Names}}
            -f "label=com.gitlab.gitlab-runner.job.id=$CI_JOB_ID"
            -f "label=com.gitlab.gitlab-runner.type=build")
        # we give the committed image the same name as the current container
        # plus "-test-docker"
        - >
            docker commit --change "WORKDIR $(pwd)"
            ${CI_CONTAINER_NAME} ${CI_TEMP_CONTAINER_NAME}
        # create the test network
        - docker network create ${CI_NETWORK_NAME}
    script:
        # run the new Docker image in which we run the tests; it must be
        # added to the test network, and must mount the Docker socket so the
        # test itself can start the container for the recsystem
        # cool hack to get the volume mounts of a container:
        - >
            export VOLUMES=$(docker inspect
            -f '{{range .Mounts}} -v {{.Source}}:{{.Destination}}{{end}}'
            ${CI_CONTAINER_NAME})
        - >
            docker run --rm ${VOLUMES} --network ${CI_NETWORK_NAME}
            --name ${CI_TEMP_CONTAINER_NAME} ${CI_TEMP_CONTAINER_NAME}
            pytest -v --color=yes --error-for-skips tests/test_baseline_docker.py
    after_script:
        # delete the network and container image created for the test
        - docker network rm ${CI_NETWORK_NAME} || true
        - docker rmi ${CI_TEMP_CONTAINER_NAME} || true
    artifacts: {}


.docker:tag: &docker_tag
    stage: "deploy"
    image: "docker:${DOCKER_VERSION}"
    before_script:
        - docker info
    script:
        - docker tag ${IMAGE_REGISTRY}:${CI_COMMIT_SHA} ${REGISTRY_IMAGE}:${TAG_NAME}


deploy:docker-master:
    <<: *docker_tag
    only: "master"
    variables:
        TAG_NAME: "master"


cleanup:docker:
    stage: "cleanup"
    image: "docker:${DOCKER_VERSION}"
    only: *only
    when: "always"
    before_script:
        - docker info
    script:
        - docker rmi ${IMAGE_REGISTRY}:${CI_COMMIT_SHA}
        - docker rmi $(docker images --filter dangling=true -q --no-trunc ${IMAGE_REGISTRY}) || true
