stages:
  - build
  - setup-cluster
  - install-apps
  - health-test
  - integration-test
  - cleanup

image: "${CI_REGISTRY_IMAGE}/openappstack-ci:${CI_COMMIT_REF_NAME}"

ci_test_image:
  stage: build
  variables:
    DOCKER_DRIVER: overlay2
  image: docker:stable
  services:
    - docker:18-dind  # FIXME This is an older version of DIND. Update when gitlab-runner fixes https://gitlab.com/gitlab-org/gitlab-runner/issues/4501
  before_script:
    - docker info
  script:
    - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
    - docker build -t ${CI_REGISTRY_IMAGE}/openappstack-ci:${CI_COMMIT_REF_NAME} test/
    - docker push ${CI_REGISTRY_IMAGE}/openappstack-ci:${CI_COMMIT_REF_NAME}
  only:
    changes:
      - Dockerfile
      - requirements.txt

bootstrap:
  stage: setup-cluster
  before_script:
    - ansible --version
  script:
    # Ensure test/ is not world-writable otherwise ansible-playbook refuses to run, see
    # https://docs.ansible.com/ansible/devel/reference_appendices/config.html#cfg-in-world-writable-dir
    - chmod 755 ansible/
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
    - python3 -m openappstack ci-$CI_PIPELINE_ID create --create-droplet openappstack.net --hostname "ci-$CI_PIPELINE_ID" --ssh-key-id 411 --create-domain-records --subdomain "ci-$CI_PIPELINE_ID.ci" 
    - python3 -m openappstack ci-$CI_PIPELINE_ID install --ansible-param skip-tags=helmfile --no-host-key-checking
  artifacts:
    paths:
    - ./clusters
    expire_in: 1 month
    when: always
  only:
    changes:
      - ansible/**/*
      - helmfiles/**/*
      - test/**/*
      - openappstack/**/*
      - .gitlab-ci.yml

install:
  stage: install-apps
  variables:
     ANSIBLE_HOST_KEY_CHECKING: 'False'
  script:
    # Ensure test/ is not world-writable otherwise ansible-playbook refuses to run, see
    # https://docs.ansible.com/ansible/devel/reference_appendices/config.html#cfg-in-world-writable-dir
    - chmod 755 ansible/
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
    - python3 -m openappstack ci-$CI_PIPELINE_ID install --ansible-param tags=helmfile --no-host-key-checking
    # Show versions of installed apps/binaries
    - ansible master -m shell -a 'oas-version-info.sh 2>&1'
  artifacts:
    paths:
    - ./clusters
    expire_in: 1 month
  only:
    changes:
      - ansible/**/*
      - helmfiles/**/*
      - test/**/*
      - openappstack/**/*
      - .gitlab-ci.yml

testinfra:
  stage: health-test
  script:
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
    - cd test/
    - py.test -v -m 'testinfra' --connection=ansible --ansible-inventory=../clusters/ci-$CI_PIPELINE_ID/inventory.yml --hosts='ansible://*'
  only:
    changes:
      - ansible/**/*
      - helmfiles/**/*
      - test/**/*
      - openappstack/**/*
      - .gitlab-ci.yml

certs:
  stage: health-test
  variables:
    OAS_DOMAIN: 'ci-${CI_PIPELINE_ID}.ci.openappstack.net'
  allow_failure: true
  script:
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
    - cd test/
    - py.test -s -m 'certs' --connection=ansible --ansible-inventory=../clusters/ci-$CI_PIPELINE_ID/inventory.yml --hosts='ansible://*'
  only:
    changes:
      - ansible/**/*
      - helmfiles/**/*
      - test/**/*
      - openappstack/**/*
      - .gitlab-ci.yml

behave-nextcloud:
  stage: integration-test
  script:
    - python3 -m openappstack ci-$CI_PIPELINE_ID test --behave --behave-headless --behave-tags nextcloud || python3 -m openappstack ci-$CI_PIPELINE_ID test --behave --behave-headless --behave-rerun-failing --behave-tags nextcloud
  artifacts:
    paths:
    - test/behave/screenshots/
    expire_in: 1 month
    when: on_failure
  retry: 2
  only:
    changes:
      - ansible/**/*
      - helmfiles/**/*
      - test/**/*
      - openappstack/**/*
      - .gitlab-ci.yml

behave-grafana:
  stage: integration-test
  script:
    - python3 -m openappstack ci-$CI_PIPELINE_ID test --behave --behave-headless --behave-tags grafana || python3 -m openappstack ci-$CI_PIPELINE_ID test --behave --behave-headless --behave-rerun-failing --behave-tags grafana
  artifacts:
    paths:
    - test/behave/screenshots/
    expire_in: 1 month
    when: on_failure
  only:
    changes:
      - ansible/**/*
      - helmfiles/**/*
      - test/**/*
      - openappstack/**/*
      - .gitlab-ci.yml

terminate:
  stage: cleanup
  script:
    # Remove droplet after successful tests
    - echo "$CI_COMMIT_MESSAGE" | grep '!ci_dont_terminate' && echo 'Termination of droplet disabled in commit message.' || python3 -m openappstack ci-$CI_PIPELINE_ID --terminate
    # Remove droplet older than 2 days
    - python3 -c "import openappstack.cosmos; openappstack.cosmos.terminate_droplets_by_name(\"^ci-\", 2)"
  only:
    changes:
      - ansible/**/*
      - helmfiles/**/*
      - test/**/*
      - openappstack/**/*
      - .gitlab-ci.yml

# This trivial job works around a Gitlab bug: if no job runs at all due to
# `only`, Gitlab gets confused and doesn't allow you to merge the MR:
# https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html#limitations
gitlab-merge-workaround:
  stage: cleanup
  script:
    - echo "That went well."