stages:
  - build
  - test
  - build_image
  - test_build
  - pages
  - staging

variables:
  CONTAINER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME
  DOCKER_DRIVER: overlay2

# ========================== Build Testing section =========================== #
build_test_env:
  image: python:3.6
  stage: build
  script:
    - python -m venv .venv
    - source .venv/bin/activate
    - make install
  artifacts:
    paths:
      - .venv/
    expire_in: 20 minutes
  cache:
    key: "$CI_JOB_NAME"
    paths:
      - .venv
  tags:
    - docker

build_frontend:
  image: node:carbon
  stage: build
  script:
    - cd frontend
    - yarn
    - yarn build
  artifacts:
    paths:
      - frontend/dist
    expire_in: 20 minutes
  cache:
    key: "$CI_JOB_NAME"
    paths:
      - frontend/dist
      - frontend/node_modules/
  tags:
    - docker

# ============================== Testing section ============================= #
# ----------------------------- Backend subsection --------------------------- #
.test_template_virtualenv: &test_definition_virtualenv
  image: python:3.6
  before_script:
    - source .venv/bin/activate
  dependencies:
    - build_test_env
  tags:
    - docker

test_pytest:
  <<: *test_definition_virtualenv
  stage: test
  services:
    - postgres:9.6
  script:
    - pytest --cov --ds=grady.settings.test core/tests
  artifacts:
    paths:
      - .coverage
  cache:
    key: "$CI_JOB_NAME"
    paths:
      - .coverage

test_flake8:
  <<: *test_definition_virtualenv
  stage: test
  script:
    - flake8 --exclude=migrations core util functional_tests

# ----------------------------- Frontend subsection -------------------------- #
.test_template_frontend: &test_definition_frontend
  image: docker.gitlab.gwdg.de/robinwilliam.hundt/python-geckodriver:master
  before_script:
    - source .venv/bin/activate
  dependencies:
    - build_test_env
    - build_frontend
  tags:
    - docker

test_frontend:
  <<: *test_definition_frontend
  stage: test
  services:
    - postgres:9.6
  script:
    - cp frontend/dist/index.html core/templates
    - python util/format_index.py
    - python manage.py collectstatic --no-input
    - HEADLESS_TESTS=True pytest --ds=grady.settings.test functional_tests


# =========================== Build Image section ============================ #
build_backend:
  image: docker:latest
  stage: build_image
  services:
    - docker:dind
  variables:
    DOCKER_HOST: tcp://docker:2375/
    DOCKER_DRIVER: overlay2
  script:
    - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
    - docker pull "$CONTAINER_IMAGE-base" || true
    - docker build --cache-from "$CONTAINER_IMAGE-base" -t "$CONTAINER_IMAGE-base" --target node .
    - docker pull $CONTAINER_IMAGE || true
    - docker build --cache-from $CONTAINER_IMAGE --cache-from "$CONTAINER_IMAGE-base" -t $CONTAINER_IMAGE .
    - docker push "$CONTAINER_IMAGE-base"
    - docker push $CONTAINER_IMAGE
  tags:
    - docker

# =========================== Gitlab pages section =========================== #
pages:
  <<: *test_definition_virtualenv
  stage:
    pages
  script:
    - coverage html -d public
  dependencies:
    - test_pytest
    - build_test_env
  artifacts:
    paths:
      - public
  only:
    - master


# ============================== Staging section ============================= #
.staging_template: &staging_definition
   stage: staging
   image: docker:latest
   only:
     - master
   before_script:
     - apk add --update py-pip && pip install docker-compose
   tags:
    - grady-staging

staging:
  <<: *staging_definition
  environment:
    name: review/$CI_COMMIT_REF_NAME
    url: https://staging.grady.janmax.org
    on_stop: staging_stop
  script:
    - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
    - docker-compose stop
    - docker-compose pull
    - docker-compose up -d --force-recreate

staging_stop:
  <<: *staging_definition
  script:
    - docker-compose rm --force --stop
  when: manual
  environment:
    name: review/$CI_COMMIT_REF_NAME
    action: stop