variables:
  UI_DOMAIN_PATH: '$CI_PROJECT_DIR/ui_domain'

default:
  before_script:
    - set -e
    # env -0 | sort -z | tr '\0' '\n': Sort env output alphabetically, keeping multiline variables intact
    # egrep: Remove sensitive information from the output of env
    #- env -0 | sort -z | tr '\0' '\n' | egrep -ve '^(DOCKER_AUTH_CONFIG|GOOGLE_APPLICATION_CREDENTIALS)=.*'

# job templates

.web_deploy:
  image:
    name: 'europe-north1-docker.pkg.dev/holi-shared/docker-hub-remote/hashicorp/terraform:1.9.8'
    # default entrypoint is terraform command, but we want to run shell scripts
    entrypoint: ['/bin/sh', '-c']
  variables:
    ENVIRONMENT_ID: $CI_ENVIRONMENT_SLUG
  dependencies: [] # explicitly disable artifact usage
  artifacts:
    paths:
      - 'terraform/environments/crash.log' # optional, only available in case of a crash/panic
      - 'terraform/environments/terraform-*.log' # separate log for every step/command
      - $UI_DOMAIN_PATH
    name: '${CI_JOB_NAME}_${CI_JOB_ID}'
    when: always
    expire_in: 1 week
  script:
    - terraform/environments/scripts/create-or-update-env.sh "$ENVIRONMENT_ID" "$CI_COMMIT_SHA"
    - echo "$(terraform/environments/scripts/get-output.sh app_domain)" > "$UI_DOMAIN_PATH"
  resource_group: $ENVIRONMENT_ID # never execute terraform in parallel on the same environment
  interruptible: false

.web_e2e:
  image: 'mcr.microsoft.com/playwright:v1.49.1-noble'
  cache: !reference [.yarn-cache-readonly]
  dependencies: [] # explicitly disable artifact usage
  artifacts:
    name: 'web e2e test report'
    expose_as: 'web e2e test report'
    expire_in: 1 week
    paths:
      - e2e/web/playwright-report
      - e2e/web/playwright-report/junit-report.xml
    when: always
    reports:
      junit: e2e/web/playwright-report/junit-report.xml
  script: |
    export UI_DOMAIN=`cat $UI_DOMAIN_PATH`
    terraform/environments/scripts/wait-for-ssl.sh "https://${UI_DOMAIN}"
    cd e2e/web
    corepack enable
    yarn install --immutable --immutable-cache
    BASE_URL="https://${UI_DOMAIN}" yarn run test
  interruptible: true
  tags:
    - 4cpu-16gb

.web_destroy:
  image:
    name: 'europe-north1-docker.pkg.dev/holi-shared/docker-hub-remote/hashicorp/terraform:1.9.8'
    # default entrypoint is terraform command, but we want to run shell scripts
    entrypoint: ['/bin/sh', '-c']
  variables:
    # has to be set to none for auto stop
    GIT_STRATEGY: none
  dependencies: [] # explicitly disable artifact usage
  artifacts:
    paths:
      - 'terraform/environments/crash.log' # optional, only available in case of a crash/panic
      - 'terraform/environments/terraform-*.log' # separate log for every step/command
    name: '${CI_JOB_NAME}_${CI_JOB_ID}'
    when: on_failure
    expire_in: 1 week
  before_script:
  script:
    # branch may have been deleted, so we clone and checkout main
    - git clone "$CI_REPOSITORY_URL" main-clone
    - cd main-clone
    - terraform/environments/scripts/destroy-env.sh "$CI_ENVIRONMENT_SLUG"
  resource_group: $CI_ENVIRONMENT_SLUG # never execute terraform in parallel on the same environment
  interruptible: false

.web_smoketest:
  image: 'europe-north1-docker.pkg.dev/holi-shared/docker/holi-docker/holi-k6-builder'
  cache: [] # explicitly disable cache
  script:
    - UI_DOMAIN=$(cat "$UI_DOMAIN_PATH")
    - terraform/environments/scripts/wait-for-ssl.sh "https://${UI_DOMAIN}"
    - BASE_URL="https://${UI_DOMAIN}/api/health" k6 run smoketest/main.js
    # TODO should/could we roll back the service to the last working revision on test failure?

# end job templates

# pipeline in chronological order

## common steps

web_build:
  needs: ['lint_compile_test']
  image: 'europe-north1-docker.pkg.dev/holi-shared/docker/holi-docker/node-expo-eas'
  script:
    - corepack enable
    - yarn install --immutable --immutable-cache
    - yarn web:build
    - ./scripts/generate-license-documents.sh
  cache: !reference [.yarn-cache-readonly]
  dependencies: [] # explicitly disable artifact usage
  artifacts:
    paths:
      - apps/web/.next
    exclude:
      - apps/web/.next/cache
    expire_in: 1 week
  interruptible: true
  tags:
    - 4cpu-16gb
  rules:
    - !reference [.rule_templates, not_on_git_tags]
    - if: $CI_COMMIT_BRANCH =~ /^noweb\/.*/
      when: never
    - !reference [.rule_templates, automatically_on_any_other]
  variables:
    WEB_BUILD: true

storybook_publish:
  needs: ['lint_compile_test']
  environment:
    name: storybook-main
    url: https://main--63846e9768032326df3b0c75.chromatic.com
    deployment_tier: staging
  image: 'europe-north1-docker.pkg.dev/holi-shared/docker/holi-docker/node-expo-eas' # too much, but since it is there...
  cache: !reference [.yarn-cache-readonly]
  script:
    - corepack enable
    - yarn install --immutable --immutable-cache
    - yarn storybook:publish
  dependencies: [] # explicitly disable artifact usage
  artifacts:
    paths:
      - apps/storybook/build-storybook.log
    expire_in: 1 week
  interruptible: true
  tags:
    - 4cpu-16gb
  rules:
    - !reference [.rule_templates, not_on_git_tags]
    - if: $CI_COMMIT_BRANCH == "main"
      changes:
        - apps/storybook/**/*
        - packages/ui/**/*
        - '**/*.stories.tsx'

holi_bricks_publish:
  needs: ['lint_compile_test']
  environment:
    name: holi-bricks-main
    url: https://main--67210d8631103790622bc60c.chromatic.com
    deployment_tier: staging
  image: 'europe-north1-docker.pkg.dev/holi-shared/docker/holi-docker/node-expo-eas' # too much, but since it is there...
  cache: !reference [.yarn-cache-readonly]
  script:
    - corepack enable
    - yarn install --immutable --immutable-cache
    - yarn bricks:publish
  dependencies: [] # explicitly disable artifact usage
  artifacts:
    paths:
      - holi-bricks/build-storybook.log
    expire_in: 1 week
  interruptible: true
  tags:
    - 4cpu-16gb
  rules:
    - !reference [.rule_templates, not_on_git_tags]
    - if: $CI_COMMIT_BRANCH == "main"
      changes:
        - holi-bricks/components/**/*
        - '**/*.stories.tsx'
        - '**/*.mdx'

web_build_docker:
  needs: ['web_build']
  image: 'europe-north1-docker.pkg.dev/holi-shared/docker-hub-remote/docker:28'
  services:
    - name: 'europe-north1-docker.pkg.dev/holi-shared/docker-hub-remote/docker:28-dind'
      alias: 'docker'
  dependencies:
    - web_build
  variables:
    # this could be fetched via terraform output ("gcr_location" in infra project), but then we would need an extra job for terraform
    GCR_IMAGE: europe-north1-docker.pkg.dev/holi-shared/docker/holi-frontends-web
    # https://about.gitlab.com/blog/2019/07/31/docker-in-docker-with-docker-19-dot-03/
    DOCKER_TLS_CERTDIR: '/certs'
  script:
    - cd apps/web/
    - docker pull "$GCR_IMAGE" || true # Allows us to use --cache-from, we need to tag with latest in the next command for this to work
    - docker build --cache-from "$GCR_IMAGE" -t "$GCR_IMAGE":latest -t "$GCR_IMAGE":"$CI_COMMIT_SHA" -t "$GCR_IMAGE":"$CI_COMMIT_REF_SLUG" .
    - docker push "$GCR_IMAGE":"$CI_COMMIT_SHA" # this is the tag that is used for deployment
    - docker push "$GCR_IMAGE":"$CI_COMMIT_REF_SLUG" # just for easyly knowing which is the last image for a branch
    - docker push "$GCR_IMAGE":latest # for caching the build
  interruptible: true
  rules:
    - !reference [.rule_templates, not_on_git_tags]
    - !reference [.rule_templates, skip_environment_for_web]
    - !reference [.rule_templates, automatically_on_any_other]

## only for review environments

.rules_web_review:
  - !reference [.rule_templates, any_but_production_staging]
  - !reference [.rule_templates, skip_environment_for_web]

web_review_deploy:
  extends: .web_deploy
  needs: ['web_build_docker']
  environment:
    name: web-review/$CI_COMMIT_REF_SLUG
    url: https://$CI_ENVIRONMENT_SLUG.dev.holi.social
    on_stop: web_review_destroy
    auto_stop_in: 1 week
  rules:
    - !reference [.rules_web_review]
    - !reference [.rule_templates, automatically_on_any_other]

web_review_smoketest:
  needs: ['web_review_deploy']
  extends: .web_smoketest
  rules:
    - !reference [.rules_web_review]
    - !reference [.rule_templates, automatically_on_any_other]

web_review_e2e:
  extends: .web_e2e
  needs: ['web_review_deploy']
  allow_failure: true # optional build step, won't block the pipeline to succeed
  dependencies:
    - web_review_deploy
  rules:
    - !reference [.rules_web_review]
    - !reference [.rule_templates, manually_on_any_other]

web_review_destroy:
  extends: .web_destroy
  needs: ['web_review_deploy']
  allow_failure: true # optional build step, won't block the pipeline to succeed
  environment:
    name: web-review/$CI_COMMIT_REF_SLUG
    action: stop
  rules:
    - !reference [.rule_templates, any_but_production_staging]
    - !reference [.rule_templates, skip_environment_for_web]
    - if: $CI_COMMIT_BRANCH
      when: manual

## staging environment

web_staging_deploy:
  extends: .web_deploy
  needs: ['web_build_docker']
  environment:
    name: web-staging
    deployment_tier: staging
    url: https://staging.dev.holi.social
  variables:
    ENVIRONMENT_ID: staging
  rules:
    - !reference [.rule_templates, automatically_on_staging]

web_staging_smoketest:
  needs: ['web_staging_deploy']
  extends: .web_smoketest
  rules:
    - !reference [.rule_templates, automatically_on_staging]

web_staging_e2e:
  extends: .web_e2e
  needs: ['web_staging_deploy']
  allow_failure: true # optional build step, won't block the pipeline to succeed
  dependencies:
    - web_staging_deploy
  rules:
    - !reference [.rule_templates, automatically_on_scheduled_e2e_test_run]
    - !reference [.rule_templates, manually_on_staging]

## production environment

web_release_candidate_deploy:
  extends: .web_deploy
  needs: ['web_build_docker']
  environment:
    name: web-rc/${CI_COMMIT_BRANCH}
    url: https://$CI_ENVIRONMENT_SLUG.dev.holi.social
    on_stop: web_release_candidate_destroy
    auto_stop_in: 1 week
  rules:
    - !reference [.rule_templates, only_on_production_release]
  after_script: | # only wget is available in the terraform image
    if [ $CI_JOB_STATUS == 'success' ]; then
      wget --header="Content-Type: application/json" \
        --post-data='{"channel": "#release-status", "branch": "'$CI_COMMIT_REF_SLUG'", "text":"The web environment for the release candidate \"'$CI_COMMIT_REF_SLUG'\" for release '$(git describe --tags --abbrev=0|sed "s|release/||")'. has been updated to \"'"$CI_COMMIT_TITLE"'\". and is available and/or updated under:\nhttps://'"$(cat $UI_DOMAIN_PATH)"'\nIf the environment was deployed for the first time, availability might take 30 to 60 minutes due to SSL certificate rollout. Meanwhile, you will see a 'PR_END_OF_FILE_ERROR' in your browser.\nTo deploy this version to web production go to this Pipeline: '$CI_PIPELINE_URL'"}' \
        --output-document - \
        https://projectholi.rocket.chat/hooks/$ROCKETCHAT_HOOK_RELEASE_NOTIFIER
    fi

web_release_candidate_destroy:
  extends: .web_destroy
  needs: ['web_release_candidate_deploy']
  allow_failure: true # optional build step, won't block the pipeline to succeed
  environment:
    name: web-rc/${CI_COMMIT_BRANCH}
    action: stop
  rules:
    - !reference [.rule_templates, manually_on_production_release]

web_release_deploy:
  extends: .web_deploy
  needs: ['web_release_candidate_deploy']
  allow_failure: false
  environment:
    name: web-production
    deployment_tier: production
    url: https://app.holi.social
  variables:
    ENVIRONMENT_ID: production
  rules:
    - !reference [.rule_templates, manually_on_production_release]
  after_script: | # only wget is available in the terraform image
    if [ $CI_JOB_STATUS == 'success' ]; then
      wget --header="Content-Type: application/json" \
        --post-data='{"channel": "#release-status", "branch": "'$CI_COMMIT_REF_SLUG'", "text":"The production web environment has been manually released from \"'$CI_COMMIT_REF_SLUG'\" for release '$(git describe --tags --abbrev=0|sed "s|release/||")'. It has been updated to \"'"$CI_COMMIT_TITLE"'\" and is available and/or updated under https://app.holi.social"}' \
        --output-document - \
        https://projectholi.rocket.chat/hooks/$ROCKETCHAT_HOOK_RELEASE_NOTIFIER
    fi

web_release_smoketest:
  needs: ['web_release_deploy']
  extends: .web_smoketest
  rules:
    - !reference [.rule_templates, only_on_production_release]
