stages:
    - build-base
    - push-base
    - run-schema
    - build-dev
    - unit-test-dev
    - test-coverage
    - push-dev
    - deploy-coverage-page
    - deploy-dev
    - .post
    # - deploy-test

variables:
    PROJECT_NAME: "workspaces"
    DEFAULT_DEPLOY_ENV: "dev"
    # Postgres Service Variables
    POSTGRES_DB: archive
    POSTGRES_USER: "archive"
    POSTGRES_PASSWORD: "docker"

# CI Postgres Service
services:
    - name: marconi.aoc.nrao.edu/ops/ci/db:workspaces
      alias: db

image: docker:19.03.12

workflow:
  rules:
    - if: $CI_MERGE_REQUEST_IID
    - if: $CI_COMMIT_TAG
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

# Import Templates
include:
    - '/ci/build.template.yml'
    - '/ci/push.template.yml'
    - '/ci/cleanup.template.yml'
    - '/ci/unit-test.template.yml'

# Build Base Image
build base image:
    stage: build-base
    script:
        - docker build -t ${REGISTRY_URL}/ops/base:${PROJECT_NAME} -f Dockerfile.base .
        - docker tag ${REGISTRY_URL}/ops/base:${PROJECT_NAME} ${REGISTRY_URL}/ops/base:${CI_COMMIT_SHORT_SHA}
    rules:
        - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_COMMIT_MESSAGE =~ /\A(?i)-ops/'
          changes:
            - Dockerfile.base
            - docker.properties

# Push Base Image Stage
push base image:
    stage: push-base
    script:
        - echo "$HARBOR_PASSWORD" | docker login -u "$HARBOR_USER" --password-stdin $REGISTRY_URL
        - docker push ${REGISTRY_URL}/ops/base:${PROJECT_NAME}
        - docker push ${REGISTRY_URL}/ops/base:${CI_COMMIT_SHORT_SHA}
    rules:
        - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_MESSAGE =~ /\A(?i)-ops/'
          changes:
            - Dockerfile.base
            - docker.properties

# Run Schema
run schema:
    stage: run-schema
    image: ${REGISTRY_URL}/ops/base:${PROJECT_NAME}
    script:
        - export PGPASSWORD=$POSTGRES_PASSWORD
        - cd schema && ./bin/run-migrations.sh "docker"
    rules:
        - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
          when: always
        - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
          when: always

# Build Stages
build dev workflow:
    stage: build-dev
    variables:
        SERVICE_NAME: "workflow"
        PATH_PREFIX: "services/"
    extends: .build

build dev capability:
    stage: build-dev
    variables:
        SERVICE_NAME: "capability"
        PATH_PREFIX: "services/"
    extends: .build

build dev notification:
    stage: build-dev
    variables:
        SERVICE_NAME: "notification"
        PATH_PREFIX: "services/"
    extends: .build

build dev web:
    stage: build-dev
    variables:
        SERVICE_NAME: "web"
        PATH_PREFIX: "apps/"
    extends: .build

## Test Stages ##

# Unit Tests
unit test dev workflow:
    stage: unit-test-dev
    variables:
        SERVICE_NAME: "workflow"
    extends: .unit-test
    needs:
        - build dev workflow

unit test dev capability:
    stage: unit-test-dev
    variables:
        SERVICE_NAME: "capability"
    extends: .unit-test
    needs:
        - build dev capability

unit test dev notification:
    stage: unit-test-dev
    variables:
        SERVICE_NAME: "notification"
    extends: .unit-test
    needs:
        - build dev notification


# Generate Coverage reports 
unit test coverage:
    stage: test-coverage
    image: python:3.8-slim
    before_script:
        - pip install pytest pytest-cov
    script:
        - coverage combine --append
        - coverage report
        - coverage xml
        - coverage html
    artifacts:
        reports:
            cobertura: coverage.xml
        paths:
            - coverage.xml
            - htmlcov/
    dependencies:
      - unit test dev workflow
      - unit test dev capability
      - unit test dev notification
    rules:
        - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
        - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'

# Push Stages
push dev workflow:
    stage: push-dev
    variables:
        SERVICE_NAME: "workflow"
    extends: .push
    needs:
        - unit test dev workflow

push dev capability:
    stage: push-dev
    variables:
        SERVICE_NAME: "capability"
    extends: .push
    needs:
        - unit test dev capability

push dev notification:
    stage: push-dev
    variables:
        SERVICE_NAME: "notification"
    extends: .push
    needs:
        - unit test dev notification

push dev web:
    stage: push-dev
    variables:
        SERVICE_NAME: "web"
    extends: .push
    # UI tests coming soon!
    # needs:
    #     - unit test dev ui

# Cleanup
clean build workflow:
    stage: .post
    variables:
        SERVICE_NAME: "workflow"
    extends: .cleanup
    allow_failure: true

clean build capability:
    stage: .post
    variables:
        SERVICE_NAME: "capability"
    extends: .cleanup
    allow_failure: true

clean build notification:
    stage: .post
    variables:
        SERVICE_NAME: "notification"
    extends: .cleanup
    allow_failure: true

clean build web:
    stage: .post
    variables:
        SERVICE_NAME: "web"
    extends: .cleanup
    allow_failure: true

# Deploy Stages
pages:
    stage: deploy-coverage-page
    image: python:3.8-slim
    dependencies:
        - unit test coverage
    script:
        - mkdir public
        - mv htmlcov/* public/
    artifacts:
        paths:
        - public
        expire_in: 2 weeks
    rules:
        - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

# Development 
deploy dev:
    stage: deploy-dev
    variables:
        ENV: "dev"
    script:
        - SWARM_NODE_ENV=$ENV TAG_TO_DEPLOY=$CI_DEFAULT_BRANCH docker stack deploy --compose-file docker-compose.${ENV}.yml workspaces-${ENV}
    rules:
        - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
          when: manual

# Development 
# deploy dev:
#     stage: deploy-dev
#     script:
#         - |
#             if [ "$CI_COMMIT_BRANCH" != "" ]; then \
#                 if [ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]; then \
#                     echo "Deploying merged branch: ${CI_COMMIT_BRANCH} to dev environment"; \
#                     SWARM_NODE_ENV="dev" TAG_TO_DEPLOY="development" docker stack deploy --compose-file docker-compose.dev.yml workspaces-dev ; \
#                 else
#                     if [ "$CAPABILITY_BRANCH" != "" ]; then \
#                         echo "Updating Capability Service: ${CI_COMMIT_BRANCH} in dev environment"; \
#                         docker service update --image marconi.aoc.nrao.edu/workspaces/capability:"$CAPABILITY_BRANCH" workspaces-dev_capability
#                     fi
#                     if [ "$WORKFLOW_BRANCH" != "" ]; then \
#                         echo "Updating Workflow Service: ${CI_COMMIT_BRANCH} in dev environment"; \
#                         docker service update --image marconi.aoc.nrao.edu/workspaces/workflow:"$WORKFLOW_BRANCH" workspaces-dev_workflow
#                     fi
#                     if [ "$WORKFLOW_BRANCH" == "" && "$CAPABILITY_BRANCH" == "" ]; then \
#                         echo "Deploying branch: ${CI_COMMIT_BRANCH} to dev environment"; \
#                         SWARM_NODE_ENV="dev" TAG_TO_DEPLOY="${CI_COMMIT_BRANCH}" docker stack deploy --compose-file docker-compose.dev.yml workspaces-dev ; \
#                     fi
#                 fi
#             fi
#             if [ "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" != "" ]; then \
#                 if [ "$CAPABILITY_BRANCH" != "" ]; then \
#                         echo "Updating Capability Service with PR Branch: ${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} in dev environment"; \
#                         docker service update --image marconi.aoc.nrao.edu/workspaces/capability:"$CAPABILITY_BRANCH" workspaces-dev_capability
#                     fi
#                     if [ "$WORKFLOW_BRANCH" != "" ]; then \
#                         echo "Updating Workflow Service with PR Branch: ${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} in dev environment"; \
#                         docker service update --image marconi.aoc.nrao.edu/workspaces/workflow:"$WORKFLOW_BRANCH" workspaces-dev_workflow
#                     fi
#                     if [ "$WORKFLOW_BRANCH" == "" && "$CAPABILITY_BRANCH" == "" ]; then \
#                         echo "Deploying branch: ${CI_COMMIT_BRANCH} to dev environment"; \
#                         SWARM_NODE_ENV="dev" TAG_TO_DEPLOY="${CI_COMMIT_BRANCH}" docker stack deploy --compose-file docker-compose.dev.yml workspaces-dev ; \
#                     fi
#                 echo "Deploying PR branch: ${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} to dev environment"; \
#                 SWARM_NODE_ENV="dev" TAG_TO_DEPLOY="dev-branch" docker stack deploy --compose-file docker-compose.dev.yml workspaces-dev ; \
#             fi
#     environment: development
#     rules:
#         - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
#           when: always
#         - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
#           when: manual

# Testing
# deploy test:
#     stage: deploy-test
#     script:
#         |
#             echo "branch: ${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}"
#             echo "tag: ${CI_COMMIT_TAG}"
#             SWARM_NODE_ENV="test" TAG_TO_DEPLOY="${CI_COMMIT_TAG}" docker stack deploy --compose-file docker-compose.dev.yml workspaces-dev
#     rules:
#         - if: $CI_COMMIT_TAG
#           when: manual
