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

variables:
  DEV_IMAGE: $CI_REGISTRY_IMAGE/dev-image
  DEV_IMAGE_BASE: $CI_REGISTRY_IMAGE/dev-image-base
  RELEASE_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG
  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
      - frontend/node_modules/
    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

test_frontend_unit:
  image: node:carbon
  stage: test
  dependencies:
    - build_frontend
  tags: 
    - docker
  script:
    - cd frontend/
    - yarn test:unit


# =========================== Build Image section ============================ #
build_dev_image:
  image: docker:latest
  stage: build_image
  only:
    - branches
  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 $DEV_IMAGE_BASE || true
    - docker build --cache-from $DEV_IMAGE_BASE -t $DEV_IMAGE_BASE --target node .
    - docker pull $DEV_IMAGE || true
    - docker build --cache-from $DEV_IMAGE --cache-from $DEV_IMAGE_BASE -t $DEV_IMAGE .
    - docker push $DEV_IMAGE_BASE
    - docker push $DEV_IMAGE
  tags:
    - docker

build_release_image:
  image: docker:latest
  stage: build_image
  only:
    - tags
  except:
    - branches
  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 $DEV_IMAGE_BASE || true
    - docker pull $DEV_IMAGE || true
    - docker build --cache-from $DEV_IMAGE --cache-from $DEV_IMAGE_BASE -t $RELEASE_IMAGE .
    - docker push $RELEASE_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
   when: manual
   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