stages:
  - quality
  - build
  - deploy_staging
  - deploy_production

# ------------------------------------------------------------------------------------------------
# Common Variables
# ------------------------------------------------------------------------------------------------
variables:
  NAMESPACE: "default"
  REGISTRY_GCP: europe-west1-docker.pkg.dev/ops-shared-e3afff9d/gitlab-pipeline
  IMAGE_NAME: "${REGISTRY_GCP}/${APPLICATION_NAME}"
  RELEASE_NAME: ${APPLICATION_NAME}
  CHART_DIR: helm-chart
  CI_TEMPLATES_GIT_USER: pipeline-git-ro
  CI_TEMPLATES_GIT_PROJECT_URL: gitlab.com/finboot/it-operations/ci-templates.git
  CI_TEMPLATES_GIT_PASSWORD: gphEDJxZScK9cC9qUdE3
  GKE_REGION: europe-west1
  SONAR_ENDPOINT: ${SONAR_ENDPOINT}
  SONAR_TOKEN: ${SONAR_TOKEN}

# ------------------------------------------------------------------------------------------------
# Job Functions
# ------------------------------------------------------------------------------------------------
.extract_version_from_package_json: &extract_version_from_package_json |-
  apk add --update nodejs
  TAG_VERSION=$(node -p "require('./package.json').version")
  echo TAG_VERSION=${TAG_VERSION}
  TAG_IMAGE=${TAG_VERSION}-${CI_COMMIT_SHORT_SHA}
  echo "${TAG_IMAGE}" > tag-image

.notify_slack_pipeline_started: &notify_slack_pipeline_started |-
  apk add --update git curl
  git clone https://${CI_TEMPLATES_GIT_USER}:${CI_TEMPLATES_GIT_PASSWORD}@${CI_TEMPLATES_GIT_PROJECT_URL}
  cd ci-templates
  scripts/notify-slack-start-pipeline.sh
  cd ..

.build_docker_image: &build_docker_image |-
  apk add --update gettext
  cat Dockerfile | envsubst > Dockerfile_LOAD | docker build --no-cache -t "${IMAGE_NAME}:${TAG_IMAGE}" -f Dockerfile_LOAD .
  docker login -u _json_key -p "$SA_GCR" https://europe-west1-docker.pkg.dev
  docker push "${IMAGE_NAME}:${TAG_IMAGE}"
  echo Image uploaded "${IMAGE_NAME}:${TAG_IMAGE}"

.tag_git_image: &tag_git_image |-
  # CREATE TAG
  git config user.email "${GITLAB_USER_EMAIL}"
  git config user.name "${GITLAB_USER_NAME}"
  echo "Debug gitlab.com/${CI_PROJECT_PATH}"
  git tag
  git remote set-url origin https://oauth2:${GITLAB_ACCESS_TOKEN}@gitlab.com/${CI_PROJECT_PATH}
  # Check if not exist this tag
  |
    if git rev-parse "${TAG_IMAGE}" >/dev/null 2>&1;
    then
      echo "Tag Version $VERSION already exists"
    else
      git tag -a "${TAG_IMAGE}" -m "Version created by gitlab-ci Build"
      git push origin "${TAG_IMAGE}"
    fi

.run_typescript_sonar_quality_check: &run_typescript_sonar_quality_check
  - >
    sonar-scanner
    -Dsonar.projectKey=${APPLICATION_NAME}
    -Dsonar.projectVersion=${TAG_VERSION}
    -Dsonar.host.url=${SONAR_ENDPOINT}
    -Dsonar.login=${SONAR_TOKEN}
    -Dsonar.scm.provider=git
    -Dsonar.qualitygate.wait=true
    -Dsonar.typescript.lcov.reportPaths=coverage/lcov.info

# ------------------------------------------------------------------------------------------------
# Job Interfaces
# ------------------------------------------------------------------------------------------------
.check_sonar_qube_template:
  image: europe-west1-docker.pkg.dev/ops-shared-e3afff9d/sync-images/sonarsource/sonar-scanner-cli:stable
  stage: quality
  before_script:
    - *notify_slack_pipeline_started
    - *extract_version_from_package_json
  tags:
    - docker
  script:
    - *run_typescript_sonar_quality_check
    - echo 'Finished Sonar check'
  only:
    - /^feature\/.*$/
    - /^hotfix\/.*$/
    - master

.build_docker_template:
  image: europe-west1-docker.pkg.dev/ops-shared-e3afff9d/sync-images/finboot-custom/docker-git:stable
  stage: build
  tags:
    - docker
  before_script:
    - *extract_version_from_package_json
    - *notify_slack_pipeline_started
    - *tag_git_image
  artifacts:
    paths:
      - tag-image

.build_staging_template:
  extends: .build_docker_template
  environment:
    name: staging
  variables:
    MARCO_API_PARENT_URL: https://api-marco.finboot-test.com
  before_script:
    - *extract_version_from_package_json
  script:
    - *build_docker_image
  only:
    - /^feature\/.*$/
    - /^hotfix\/.*$/
  except:
    - master

.build_production_template:
  extends: .build_docker_template
  variables:
    MARCO_API_PARENT_URL: https://api-marco.finboot.com
  environment:
    name: production
  before_script:
    - *extract_version_from_package_json
  script:
    - *build_docker_image
  only:
    - master

.deployment_script_template:
  tags:
    - docker
  before_script:
    - *extract_version_from_package_json
  image: europe-west1-docker.pkg.dev/ops-shared-e3afff9d/sync-images/finboot-custom/gitlab-job-deploy:stable
  script:
    - pip3 install untangle
    # Configure Gcloud Deploy
    - mkdir -p /etc/deploy
    - echo ${SA_GKE} | base64 -d | base64 -d  > /etc/deploy/sa.json
    - gcloud auth activate-service-account --key-file /etc/deploy/sa.json --project=${GKE_PROJECT}
    - gcloud container clusters get-credentials ${GKE_CLUSTER_NAME} --zone ${GKE_REGION} --project ${GKE_PROJECT}
    # Helm Deploy
    - helm init --client-only --skip-refresh
    - helm repo rm stable
    - helm repo add stable https://charts.helm.sh/stable
    - helm list
    # Notify Deploy
    - TAG_IMAGE=$(cat tag-image)
    - echo TAG_IMAGE=${TAG_IMAGE}
    - git clone https://${CI_TEMPLATES_GIT_USER}:${CI_TEMPLATES_GIT_PASSWORD}@${CI_TEMPLATES_GIT_PROJECT_URL}
    - cd ci-templates
    - scripts/deploy.sh "${TAG_IMAGE}"
  artifacts:
    paths:
      - tag-image
  timeout: 10m

.deploy_staging_template:
  extends: .deployment_script_template
  stage: deploy_staging
  variables:
    SA_GKE: ${SA_GKE_STAGE}
    GKE_PROJECT: ${STAGE_GKE_PROJECT}
    GKE_CLUSTER_NAME: ${STAGE_GKE_CLUSTER_NAME}
    STACK: stage
    HEALTHCHECK: ${STAGE_HEALTHCHECK}
    HEALTHCHECK_MARCO_APPLICATION_TOKEN: ${STAGE_HEALTHCHECK_MARCO_APPLICATION_TOKEN}
  environment:
    name: staging
    url: https://${APPLICATION_NAME}.finboot-test.com
  rules:
    - if: '$CI_MERGE_REQUEST_EVENT_TYPE == "detached"'
      # Avoid creating additional pipeline when in merge requests
      when: never
    - if: '$CI_COMMIT_REF_SLUG =~ /^(feature|hotfix)/'
      when: manual # Force manual deploy for branches
      allow_failure: true
    - if: '$CI_COMMIT_REF_SLUG == $CI_DEFAULT_BRANCH' # Auto deploy on default branch
      when: on_success

.deploy_production_template:
  extends: .deployment_script_template
  stage: deploy_production
  variables:
    SA_GKE: ${SA_GKE_PROD}
    GKE_PROJECT: ${PROD_GKE_PROJECT}
    GKE_CLUSTER_NAME: ${PROD_GKE_CLUSTER_NAME}
    STACK: prod
    HEALTHCHECK: ${PROD_HEALTHCHECK}
    HEALTHCHECK_MARCO_APPLICATION_TOKEN: ${PROD_HEALTHCHECK_MARCO_APPLICATION_TOKEN}
  environment:
    name: production
    url: https://${APPLICATION_NAME}.finboot.com
  when: manual
  only:
    - master
