# Gitlab-CI Workflow
# stages:
#   build:
#     - Runs on commits on master or tags that match the pattern v1.0, v2.1rc1
#   deploy-staging:
#     - Runs on commits on master or tags that match the pattern v1.0, v2.1rc1 (continues deployment)
#   deploy-production:
#     - Runs on tags that match the pattern v1.0, v2.1rc1 (manual deployment)

variables:
  CONTAINER_REPO:                  "docker.io/parity/substrate-api-sidecar"
  HELM_NAMESPACE:                  "substrate-api-sidecar"
  HELM_RELEASE_NAME_1:             "kusama-sidecar"
  HELM_RELEASE_NAME_2:             "polkadot-sidecar"
  HELM_CUSTOM_VALUES_FILE_1:       "values-kusama.yaml"
  HELM_CUSTOM_VALUES_FILE_2:       "values-polkadot.yaml"
  HELM_REPO:                       "helm/"
  DOCKERFILE_DIRECTORY:            "./"
  CI_IMAGE:                        "$BUILDAH_IMAGE" # defined in group variables
  BUILDAH_COMMAND:                 "buildah --storage-driver overlay2"
  NODE_IMAGE:                      "node:18"
  BENCHMARK_IMAGE:                 "paritytech/node-wrk:latest"

default:
  retry:
    max: 2
    when:
      - runner_system_failure
      - unknown_failure
      - api_failure
  interruptible:                   true
  before_script:
    - |-
      if [[ $CI_COMMIT_TAG =~ ^v[0-9]+\.[0-9]+.*$ ]]; then
        export DOCKER_IMAGE_TAG="${CI_COMMIT_TAG}"
        export BUILD_LATEST_IMAGE="true"
      else
        export DOCKER_IMAGE_TAG="${CI_COMMIT_SHORT_SHA}-beta"
      fi

stages:
  - test
  - build
  - deploy-staging
  - deploy-production
  - benchmark
  - check-benchmark
  - push-benchmark

.collect-artifacts:                &collect-artifacts
  artifacts:
    name:                          "${CI_JOB_NAME}_${CI_COMMIT_REF_NAME}"
    when:                          on_success
    expire_in:                     1 days
    paths:
      - ./artifacts/

.test-refs:                        &test-refs
  rules:
    - if: $CI_COMMIT_REF_NAME =~ /^[0-9]+$/                         # PRs

.test-refs-manual:                 &test-refs-manual
  rules:
    - if: $CI_COMMIT_REF_NAME =~ /^[0-9]+$/                         # PRs
      when: manual

.publish-refs:                     &publish-refs
  rules:
    - if: $CI_PIPELINE_SOURCE == "pipeline"
      when: never
    - if: $CI_PIPELINE_SOURCE == "schedule"
    - if: $CI_COMMIT_REF_NAME == "master"
    - if: $CI_COMMIT_REF_NAME =~ /^v[0-9]+\.[0-9]+.*$/              # i.e. v1.0, v2.1rc1

.dockerize:                        &dockerize
  stage:                           build
  image:                           $CI_IMAGE
  tags:
    - linux-docker

.docker-env:                   &docker-env
  image:                           $CI_IMAGE
  tags:
    - linux-docker

.deploy-k8s:                       &deploy-k8s
  image:                           paritytech/kubetools:3.5.3
  script:
    - |-
      kubectl get cm helm-custom-values -n $HELM_NAMESPACE -o jsonpath='{.data.values-kusama\.yaml}' > values-kusama.yaml
      kubectl get cm helm-custom-values -n $HELM_NAMESPACE -o jsonpath='{.data.values-polkadot\.yaml}' > values-polkadot.yaml
    - helm upgrade
        --install
        --atomic
        --timeout 120s
        --namespace $HELM_NAMESPACE
        --set image.repository="${CONTAINER_REPO}"
        --set image.tag="${DOCKER_IMAGE_TAG}"
        --values ${HELM_CUSTOM_VALUES_FILE_1}
        ${HELM_RELEASE_NAME_1} ${HELM_REPO}
    - helm upgrade
        --install
        --atomic
        --timeout 120s
        --namespace $HELM_NAMESPACE
        --set image.repository="${CONTAINER_REPO}"
        --set image.tag="${DOCKER_IMAGE_TAG}"
        --values ${HELM_CUSTOM_VALUES_FILE_2}
        ${HELM_RELEASE_NAME_2} ${HELM_REPO}
  tags:
    - linux-docker

.e2e-template:                     &e2e-template
  stage:                           test
  <<:                              *docker-env
  variables:
    CI_IMAGE:                      $NODE_IMAGE
    CHAIN_NAME:                    ""
    CHAIN_URL:                     ""
  script:
    - yarn --immutable
    - echo "Tests for ${CHAIN_URL}"
    - yarn test:latest-e2e-tests --log-level info --chain ${CHAIN_NAME} --local ${CHAIN_URL}
  allow_failure: true

e2e-westend:
  <<:                              *e2e-template
  variables:
    CI_IMAGE:                      $NODE_IMAGE
    CHAIN_NAME:                    "westend"
    CHAIN_URL:                     "wss://westend-rpc.polkadot.io"

e2e-kusama:
  <<:                              *e2e-template
  variables:
    CI_IMAGE:                      $NODE_IMAGE
    CHAIN_NAME:                    "kusama"
    CHAIN_URL:                     "wss://kusama-rpc.polkadot.io"

e2e-polkadot:
  <<:                              *e2e-template
  variables:
    CI_IMAGE:                      $NODE_IMAGE
    CHAIN_NAME:                    "polkadot"
    CHAIN_URL:                     "wss://rpc.polkadot.io"

build-docker:
  <<:                              *dockerize
  <<:                              *publish-refs
  script:
    - echo building "$CONTAINER_REPO:$DOCKER_IMAGE_TAG"
    - if [[ $BUILD_LATEST_IMAGE ]]; then
        $BUILDAH_COMMAND build
        --format=docker
        --tag "$CONTAINER_REPO:$DOCKER_IMAGE_TAG"
        --tag "$CONTAINER_REPO:latest" "$DOCKERFILE_DIRECTORY";
      else
        $BUILDAH_COMMAND build
        --format=docker
        --tag "$CONTAINER_REPO:$DOCKER_IMAGE_TAG" "$DOCKERFILE_DIRECTORY";
      fi
    - $BUILDAH_COMMAND info
    - echo ${Docker_Hub_Pass_Parity} |
        buildah login --username ${Docker_Hub_User_Parity} --password-stdin docker.io
    - echo pushing "$CONTAINER_REPO:$DOCKER_IMAGE_TAG"
    - if [[ $BUILD_LATEST_IMAGE ]]; then
        $BUILDAH_COMMAND push --format=v2s2 "$CONTAINER_REPO:$DOCKER_IMAGE_TAG";
        $BUILDAH_COMMAND push --format=v2s2 "$CONTAINER_REPO:latest";
      else
        $BUILDAH_COMMAND push --format=v2s2 "$CONTAINER_REPO:$DOCKER_IMAGE_TAG";
      fi

push-docker-image-description:
  stage:                           build
  before_script:
    - echo
  extends:
    - .docker-env
  variables:
    CI_IMAGE:                      paritytech/dockerhub-description
    DOCKERHUB_REPOSITORY:          parity/substrate-api-sidecar
    DOCKER_USERNAME:               $Docker_Hub_User_Parity
    DOCKER_PASSWORD:               $Docker_Hub_Pass_Parity
    README_FILEPATH:               $CI_PROJECT_DIR/Dockerfile.README.md
    SHORT_DESCRIPTION:             "REST service to interact with blockchain nodes built using Substrate's FRAME framework."
  rules:
    - if: $CI_COMMIT_REF_NAME == "master"
      changes:
      - Dockerfile.README.md
  script:
    - cd / && sh entrypoint.sh

# checks that dockerimage can be built without publishing
build-docker-pr:
  <<:                              *dockerize
  <<:                              *test-refs
  script:
    - echo building "$CONTAINER_REPO:$DOCKER_IMAGE_TAG"
    - if [[ $BUILD_LATEST_IMAGE ]]; then
        $BUILDAH_COMMAND build
        --format=docker
        --tag "$CONTAINER_REPO:$DOCKER_IMAGE_TAG"
        --tag "$CONTAINER_REPO:latest" "$DOCKERFILE_DIRECTORY";
      else
        $BUILDAH_COMMAND build
        --format=docker
        --tag "$CONTAINER_REPO:$DOCKER_IMAGE_TAG" "$DOCKERFILE_DIRECTORY";
      fi
    - $BUILDAH_COMMAND info

deploy-staging:
  stage:                           deploy-staging
  <<:                              *deploy-k8s
  <<:                              *publish-refs
  environment:
    name:                          parity-stg

deploy-production:
  stage:                           deploy-production
  <<:                              *deploy-k8s
  environment:
    name:                          parity-chains
  rules:
    - if: $CI_COMMIT_REF_NAME =~ /^v[0-9]+\.[0-9]+.*$/              # i.e. v1.0, v2.1rc1
      when: manual

bench-polkadot:                    &bench-polkadot
  stage:                           benchmark
  <<:                              *docker-env
  <<:                              *collect-artifacts
  <<:                              *publish-refs
  variables:
    CI_IMAGE:                      $BENCHMARK_IMAGE
    CHAIN_NAME:                    "polkadot"
    CHAIN_URL:                     "wss://rpc.polkadot.io"
  script:
    - yarn --immutable
    - echo "Benchmarks for ${CHAIN_URL}"
    - mkdir -p artifacts
    - yarn bench --log-level info --ws-url ${CHAIN_URL}
    - mv benchmarks.txt artifacts/

# manual step to run benchmarks in PR pipeline
bench-polkadot-manual-pr:
  stage:                           benchmark
  <<:                              *bench-polkadot
  <<:                              *test-refs-manual


# temporary disabled for collecting results
# check-benchmark:
#   stage: check-benchmark
#   <<:                              *publish-refs
#   <<:                              *docker-env
#   <<:                              *collect-artifacts
#   needs:
#     - job:                         benchmark
#       artifacts:                   true
#   variables:
#     GITHUB_REPO:                   "paritytech/substrate-api-sidecar"
#     CI_IMAGE:                      "paritytech/benchmarks:latest"
#     THRESHOLD:                     60000
#     GITHUB_TOKEN:                  $GITHUB_PR_TOKEN
#   script:
#     - export RESULT=$(cat artifacts/result.txt | grep AvgRequestTime | awk '{print $2}')
#     - check_single_bench_result -g $GITHUB_REPO
#                                 -c $THRESHOLD
#                                 -v $RESULT

push-benchmark:
  stage:                           push-benchmark
  <<:                              *publish-refs
  <<:                              *docker-env
  needs:
    - job:                         bench-polkadot
      artifacts:                   true
  variables:
    PROMETHEUS_URL:                "https://pushgateway.parity-build.parity.io"
    CI_IMAGE:                      "paritytech/benchmarks:latest"
  script:
    - scripts/ci/benchmarks/push_benchmark_results.sh artifacts/benchmarks.txt
