stages:
 - build
 - test
 - test-report-aggregate
 - deploy
 - publish
 - cleanup

variables:
  # Variables required by Common CI jobs
  CI_COMMON_JOB_VERSION: "d4e29410ea168096e1a822f77c7ce741d9cfb57a"
  DOCKER_BUILDER_TAG: "$CI_COMMON_JOB_VERSION"
  DOCKER_DIND_TAG: "$CI_COMMON_JOB_VERSION"
  IMAGE_REMOVER_TAG: "$CI_COMMON_JOB_VERSION"

include:
  - template: Workflows/Branch-Pipelines.gitlab-ci.yml
  - project: 'hive/common-ci-configuration'
    ref: d4e29410ea168096e1a822f77c7ce741d9cfb57a # develop
    file: '/templates/docker_image_jobs.gitlab-ci.yml'

docker-build:
  extends: .docker_image_builder_job_template
  stage: build
  before_script:
    - !reference [.docker_image_builder_job_template, before_script]
    - |
      echo -e "\e[0Ksection_start:$(date +%s):login[collapsed=true]\r\e[0KLogging to Docker registry..."
      docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
      echo -e "\e[0Ksection_end:$(date +%s):login\r\e[0K"
  script:
    - |
      echo -e "\e[0Ksection_start:$(date +%s):tag[collapsed=true]\r\e[0KDetermining tag for the new image..."
      if [[ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]]; then
        echo "Running on default branch '$CI_DEFAULT_BRANCH': tag = 'latest'"
        export TAG="latest"
      else
        echo "Running on branch '$CI_COMMIT_BRANCH': tag = $CI_COMMIT_REF_SLUG"
        export TAG="$CI_COMMIT_REF_SLUG"
      fi
      echo -e "\e[0Ksection_end:$(date +%s):tag\r\e[0K"
      echo -e "\e[0Ksection_start:$(date +%s):build[collapsed=true]\r\e[0KBaking image "$CI_REGISTRY_IMAGE:$TAG"..."
      git config --global --add safe.directory "$CI_PROJECT_DIR"
      scripts/build_instance.sh --progress=plain "$CI_PROJECT_DIR"
      echo "IMAGE_NAME=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" > docker-build.env
      echo "Unique image tag:"
      cat docker-build.env
      echo -e "\e[0Ksection_end:$(date +%s):build\r\e[0K"
  artifacts:
    reports:
      dotenv: docker-build.env
  tags:
    - public-runner-docker

.node-job:
  extends: .job-defaults
  image:
    name: node:18.20-alpine3.20
    entrypoint: []
  stage: test
  script:
    - |
      echo -e "\e[0Ksection_start:$(date +%s):deps[collapsed=true]\r\e[0KInstalling dependencies..."
      npm ci --cache .npm
      echo -e "\e[0Ksection_end:$(date +%s):deps\r\e[0K"
  cache:
    key: block-explorer-ui-cache-1
    paths:
      - .npm/
      - .next/
  artifacts:
    name: "$CI_JOB_NAME-$CI_COMMIT_REF_NAME"
    when: always
    expire_in: 1 week
  tags:
    - public-runner-docker

lint:
  extends: .node-job
  script:
    - !reference [.node-job, script]
    - |
      echo -e "\e[0Ksection_start:$(date +%s):lint[collapsed=true]\r\e[0KRunning linter..."
      npm run lint 2>&1 | tee npm-lint.log
      echo -e "\e[0Ksection_end:$(date +%s):lint\r\e[0K"
  artifacts:
    paths:
      - "npm-lint.log"

startup-test:
  extends: .docker_image_builder_job_template
  stage: test
  needs:
    - docker-build
  variables:
    PORT: 5000
    API_ENDPOINT: http://192.168.4.250:3000/rpc
    HIVE_BLOG_API_ENDPOINT: https://api.hive.blog
    CONTAINER_NAME: block-explorer-ui
    MESSAGE: Waiting for container startup...
  before_script:
    - |
      echo -e "\e[0Ksection_start:$(date +%s):login[collapsed=true]\r\e[0KLogging to Docker registry..."
      docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
      echo -e "\e[0Ksection_end:$(date +%s):login\r\e[0K"
  script:
    - |
      echo -e "\e[0Ksection_start:$(date +%s):startup[collapsed=true]\r\e[0KStarting the test environment..."

      timeout -s INT -k 10 600 scripts/run_instance.sh \
        --image="$IMAGE_NAME" \
        --api-endpoint="$API_ENDPOINT" \
        --hive-blog-api-endpoint="$HIVE_BLOG_API_ENDPOINT" \
        --port="$PORT" \
        --name="$CONTAINER_NAME" \
        --detach

      echo -e "\e[0Ksection_end:$(date +%s):startup\r\e[0K"
      echo -e "\e[0Ksection_start:$(date +%s):wait[collapsed=true]\r\e[0K$MESSAGE"

      until [[ "healthy" == "$(docker inspect -f '{{ .State.Health.Status }}' "$CONTAINER_NAME")" ]]
      do
        echo "$MESSAGE"
        sleep 3
      done

      echo -e "\e[0Ksection_end:$(date +%s):wait\r\e[0K"
  after_script:
    - |
      docker logs --timestamps "$CONTAINER_NAME" > "$CONTAINER_NAME.log"
      docker stop "$CONTAINER_NAME"
  artifacts:
    paths:
      - "$CONTAINER_NAME.log"
  tags:
    - public-runner-docker

.e2e_tests_template:
  extends: .node-job
  image: mcr.microsoft.com/playwright:v1.47.0-jammy
  parallel:
    matrix:
      - PROJECT: ['chromium', 'firefox', 'webkit']
        SHARD_INDEX: [1, 2, 3, 4, 5]
        SHARD_TOTAL: 5
  script:
    - !reference [.node-job, script]
    - |
      echo -e "\e[0Ksection_start:$(date +%s):tests[collapsed=false]\r\e[0KRunning tests..."
      cd ./
      npx playwright test --project=$PROJECT --shard=$SHARD_INDEX/$SHARD_TOTAL --update-snapshots
      echo -e "\e[0Ksection_end:$(date +%s):tests\r\e[0K"
  artifacts:
    paths:
      - ./playwright-report/
      - ./test-results/
      - ./junit/
    reports:
      junit: ./junit/**/**/results.xml

e2e-tests:
  extends: .e2e_tests_template
  needs:
    - docker-build
  services:
    - name: $IMAGE_NAME
      alias: block-explorer
      variables:
        REACT_APP_API_ADDRESS: https://hafbe.openhive.network
        REACT_APP_HIVE_BLOG_API_ADDRESS: https://api.hive.blog
  variables:
    PORT: 5000
    BLOCK_EXPLORER_URL: http://block-explorer:$PORT

.e2e_report_aggregate_template:
  extends: .node-job
  stage: test-report-aggregate
  when: always
  image: mcr.microsoft.com/playwright:v1.47.0-jammy
  script:
    - cd ./
    - npm install playwright-merge-html-reports --dev
    - npx playwright test tests/playwright/merge-reports/ --config playwright.merge.config.ts
  artifacts:
    paths:
      - ./merged-html-report/
      - ./junit/

e2e-report-aggregate:
  extends: .e2e_report_aggregate_template
  needs:
    - e2e-tests
  variables:
    PROJECTS: '["chromium", "firefox", "webkit"]'
    SHARD_TOTAL: 5
    PORT: 5000
    BLOCK_EXPLORER_URL: http://block-explorer:$PORT

.deploy:
  extends: .job-defaults
  stage: deploy
  needs:
    - docker-build
    - startup-test
  before_script:
    - |
      echo -e "\e[0Ksection_start:$(date +%s):login[collapsed=true]\r\e[0KLogging to Docker registry..."
      docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
      echo -e "\e[0Ksection_end:$(date +%s):login\r\e[0K"
  script:
    - |
      scripts/run_instance.sh \
        --image="$IMAGE_NAME" \
        --api-endpoint="$API_ENDPOINT" \
        --hive-blog-api-endpoint="$HIVE_BLOG_API_ENDPOINT" \
        --port="$PORT" \
        --name="$CONTAINER_NAME" \
        --detach
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
      when: manual
      allow_failure: true
  tags:
    - hs-bexplorer

staging:deploy:
  extends: .deploy
  variables:
    PORT: 5000
    API_ENDPOINT: https://hafbe.openhive.network
    HIVE_BLOG_API_ENDPOINT: https://api.hive.blog
    CONTAINER_NAME: block-explorer-ui
  environment:
    name: staging
    action: start
    on_stop: staging:stop
  rules:
    - if: $CI_COMMIT_BRANCH == "master"
      when: manual
      allow_failure: true

test:deploy:
  extends: .deploy
  variables:
    PORT: 5001
    API_ENDPOINT: https://hafbe.openhive.network
    HIVE_BLOG_API_ENDPOINT: https://api.hive.blog
    CONTAINER_NAME: block-explorer-ui-2
  environment:
    name: test
    action: start
    on_stop: test:stop

.stop:
  extends: .job-defaults
  stage: deploy
  variables:
    GIT_STRATEGY: none
  script:
    - docker ps -q --filter "name=$CONTAINER_NAME" | grep -q . && docker stop $CONTAINER_NAME
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
      when: manual
      allow_failure: true
  tags:
    - hs-bexplorer

staging:stop:
  extends: .stop
  needs:
    - staging:deploy
  variables:
    CONTAINER_NAME: block-explorer-ui
    GIT_STRATEGY: none
  environment:
    name: staging
    action: stop
  rules:
    - if: $CI_COMMIT_BRANCH == "master"
      when: manual
      allow_failure: true

test:stop:
  extends: .stop
  needs:
    - test:deploy
  variables:
    CONTAINER_NAME: block-explorer-ui-2
    GIT_STRATEGY: none
  environment:
    name: test
    action: stop

build_and_publish_image:
  stage: publish
  extends: .publish_docker_image_template
  before_script:
    - !reference [.publish_docker_image_template, before_script]
  script:
    - scripts/ci-helpers/build_and_publish_instance.sh
  tags:
    - public-runner-docker
    - hived-for-tests

buildkit_cache_cleanup:
  stage: cleanup
  extends: .buildkit_cleanup_job_template
  needs: []
  variables:
    CACHE_REPOSITORIES: "cache"
