# .gitlab-ci.yml
#
# canvas
#
# pipelines can be triggered manually in the web


stages:
  - fmt
  - build-linux
  - build-mac
  - publish

variables:                         &default-vars
  GIT_STRATEGY:                    fetch
  GIT_DEPTH:                       100
  CARGO_INCREMENTAL:               0
  CARGO_TARGET_DIR:                "/ci-cache/${CI_PROJECT_NAME}/targets/${CI_COMMIT_REF_NAME}/${CI_JOB_NAME}"
  VAULT_SERVER_URL:                "https://vault.parity-mgmt-vault.parity.io"
  VAULT_AUTH_PATH:                 "gitlab-parity-io-jwt"
  VAULT_AUTH_ROLE:                 "cicd_gitlab_parity_${CI_PROJECT_NAME}"

workflow:
  rules:
    - if: $CI_COMMIT_TAG
    - if: $CI_COMMIT_BRANCH

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

.docker-env:                       &docker-env
  image:                           paritytech/ci-linux:production
  before_script:
    - cargo -vV
    - rustc -vV
    - rustup show
    - bash --version
    - mkdir -p ${CARGO_TARGET_DIR}
    - ./scripts/ci/pre_cache.sh
    - sccache -s
  interruptible:                   true
  retry:
    max: 2
    when:
      - runner_system_failure
      - unknown_failure
      - api_failure
  tags:
    - linux-docker

.kubernetes-env:                   &kubernetes-env
  retry:
    max: 2
    when:
      - runner_system_failure
      - unknown_failure
      - api_failure
  interruptible:                   true
  tags:
    - kubernetes-parity-build

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

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

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


### stage:                         fmt

fmt:
  stage:                           fmt
  <<:                              *docker-env
  script:
    - cargo +nightly fmt --verbose --all -- --check

### stage:                         build-linux

build-linux:
  stage:                           build-linux
  <<:                              *docker-env
  <<:                              *collect-artifacts
  <<:                              *build-refs
  script:
    - time cargo build --release
    - time cargo test --release --all
    - mkdir -p ./artifacts/canvas-linux/
    - cp ${CARGO_TARGET_DIR}/release/canvas ./artifacts/canvas-linux/canvas
    - cp ${CARGO_TARGET_DIR}/release/wbuild/canvas-runtime/canvas_runtime* ./artifacts/canvas-linux/
    - cp ./scripts/dockerfiles/canvas_injected.Dockerfile ./artifacts/canvas-linux/canvas_injected.Dockerfile

### stage:                         build-mac

build-mac:
  stage:                           build-mac
  <<:                              *docker-env
  <<:                              *collect-artifacts
  # we run the mac build only when we actually want to publish
  <<:                              *publish-refs
  before_script:
    - unset CARGO_TARGET_DIR
  script:
    - time cargo build --release
    - mkdir -p ./artifacts/canvas-mac/
    - cp target/release/canvas ./artifacts/canvas-mac/canvas
  tags:
    - osx

### stage:                         publish

.build-push-docker-image:          &build-push-docker-image
  <<:                              *master-refs
  <<:                              *kubernetes-env
  image:                           quay.io/buildah/stable
  variables:
    <<:                            *default-vars
    GIT_STRATEGY:                  none
    DOCKERFILE:                    canvas_injected.Dockerfile
    IMAGE_NAME:                    docker.io/paritytech/canvas
  secrets:
    DOCKER_HUB_USER:
      vault:                       cicd/gitlab/parity/DOCKER_HUB_USER@kv
      file:                        false
    DOCKER_HUB_PASS:
      vault:                       cicd/gitlab/parity/DOCKER_HUB_PASS@kv
      file:                        false
  needs:
    - job: build-linux
      artifacts: true
  before_script:
    - if [[ "${CI_COMMIT_TAG}" ]]; then
        VERSION=${CI_COMMIT_TAG};
      elif [[ "${CI_COMMIT_SHORT_SHA}" ]]; then
        VERSION=${CI_COMMIT_SHORT_SHA};
      fi
    - echo "Effective tags = ${VERSION} sha-${CI_COMMIT_SHORT_SHA} latest"
  script:
    - cd ./artifacts/canvas-linux/
    - test "$DOCKER_HUB_USER" -a "$DOCKER_HUB_PASS" ||
        ( echo "no docker credentials provided"; exit 1 )
    - buildah bud
        --format=docker
        --build-arg VCS_REF="${CI_COMMIT_SHA}"
        --build-arg BUILD_DATE="$(date -u '+%Y-%m-%dT%H:%M:%SZ')"
        --build-arg VERSION="$VERSION"
        --tag "$IMAGE_NAME:$VERSION"
        --tag "$IMAGE_NAME:latest"
        --file "$DOCKERFILE" .
    - echo "$DOCKER_HUB_PASS" |
        buildah login --username "$DOCKER_HUB_USER" --password-stdin docker.io
    - buildah info
    - buildah push --format=v2s2 "$IMAGE_NAME:$VERSION"
    - buildah push --format=v2s2 "$IMAGE_NAME:latest"
  after_script:
    - buildah logout --all


publish-docker:
  stage:                           publish
  <<:                              *build-push-docker-image

publish:
  stage:                           publish
  <<:                              *kubernetes-env
  image:                           paritytech/tools:latest
  <<:                              *publish-refs
  needs:
    - job: build-linux
      artifacts: true
    - job: build-mac
      artifacts: true
  secrets:
    GITHUB_TOKEN:
      vault:                       cicd/gitlab/parity/GITHUB_TOKEN@kv
      file:                        false
  script:
    - git describe --tags
    - TAG_NAME=`git describe --tags`
    - echo "tag name ${TAG_NAME}"
    - tar -czvf ./canvas-linux.tar.gz ./artifacts/canvas-linux/canvas
    - tar -czvf ./canvas-mac.tar.gz ./artifacts/canvas-mac/canvas
    - 'curl https://api.github.com/repos/paritytech/canvas/releases
        --fail-with-body
        -H "Cookie: logged_in=no"
        -H "Authorization: token ${GITHUB_TOKEN}"'
    - 'curl https://api.github.com/repos/paritytech/canvas/releases
        --fail-with-body
        -H "Cookie: logged_in=no"
        -H "Authorization: token ${GITHUB_TOKEN}" | jq .'
    - 'RELEASE_ID=$(curl https://api.github.com/repos/paritytech/canvas/releases
        --fail-with-body
        -H "Cookie: logged_in=no"
        -H "Authorization: token ${GITHUB_TOKEN}"
        | jq -r ".[] | select(.tag_name == \"$TAG_NAME\") | .id");
      echo "release id if existent: ${RELEASE_ID}"'
    - 'if [ -z "$RELEASE_ID" ]; then
        RESP=$(curl -X "POST" "https://api.github.com/repos/paritytech/canvas/releases"
          --fail-with-body
          -H "Cookie: logged_in=no"
          -H "Authorization: token ${GITHUB_TOKEN}"
          -H "Content-Type: application/json; charset=utf-8"
          -d $"{
              \"tag_name\": \"${TAG_NAME}\",
              \"name\": \"${TAG_NAME}\",
              \"prerelease\": false,
              \"draft\": true
          }");
          echo "api response ${RESP}";
          RELEASE_ID=$(echo $RESP | jq -r .id);
          echo "release id of created release ${RELEASE_ID}";
        fi'
    - echo "release id ${RELEASE_ID}"
    - 'curl -X "POST" "https://uploads.github.com/repos/paritytech/canvas/releases/$RELEASE_ID/assets?name=canvas-linux.tar.gz"
        --fail-with-body
        -H "Cookie: logged_in=no"
        -H "Authorization: token ${GITHUB_TOKEN}"
        -H "Content-Type: application/octet-stream"
        --data-binary @"./canvas-linux.tar.gz"'
    - 'curl -X "POST" "https://uploads.github.com/repos/paritytech/canvas/releases/$RELEASE_ID/assets?name=canvas-mac.tar.gz"
        --fail-with-body
        -H "Cookie: logged_in=no"
        -H "Authorization: token ${GITHUB_TOKEN}"
        -H "Content-Type: application/octet-stream"
        --data-binary @"./canvas-mac.tar.gz"'
