version: 2.1
orbs:
    docker: circleci/docker@1.0.1
    kube-orb: circleci/kubernetes@0.11.0
    go: circleci/go@1.1.1

parameters:
  ci_service_controller_image:
    default: quay.io/nicob87/service-controller:${CIRCLE_SHA1}
    type: string

  ci_site_controller_image:
    default: quay.io/nicob87/site-controller:${CIRCLE_SHA1}
    type: string

  ci_test_image:
    default: quay.io/nicob87/skupper-tests:${CIRCLE_SHA1}
    type: string

executors:
  local_cluster_test_executor:
    machine:
      image: circleci/classic:latest

commands:
  minikube-install:
    description: Installs the minikube executable onto the system.
    steps:
      - run:
          command: >-
            curl -Lo minikube
            https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 && 
            chmod +x minikube && sudo
            mv minikube /usr/local/bin/
          name: Install Minikube Executable

  minikube-start:
    description: Starts the minikube service.
    steps:
      - run:
          command: >-
            minikube start --vm-driver=docker --cpus 2 --memory 2048
          name: Start Minikube Cluster

  minikube-start-load-balancer:
    description: Starts the minikube tunnel
    steps:
      - run:
          command: minikube tunnel
          name: Start Minikube Tunnel
          background: true

  prepare_for_local_cluster_tests:
    description: install right versions of go, docker, kubectl, and also build
    steps:
      - run:
          name: Export environment variables persistent in execution shell
          command: |
            echo 'export KUBECONFIG=/home/circleci/.kube/config' >> $BASH_ENV
            echo 'export GOROOT=/usr/local/go' >> $BASH_ENV
            echo 'export GOPATH=$HOME/go' >> $BASH_ENV
            echo 'export PATH=$GOPATH/bin:$GOROOT/bin:$PATH' >> $BASH_ENV
            echo 'export SKUPPER_SERVICE_CONTROLLER_IMAGE=<< pipeline.parameters.ci_service_controller_image >>' >> $BASH_ENV
            echo 'export SKUPPER_SITE_CONTROLLER_IMAGE=<< pipeline.parameters.ci_site_controller_image >>' >> $BASH_ENV
            echo 'export TEST_IMAGE=<< pipeline.parameters.ci_test_image >>' >> $BASH_ENV
            source $BASH_ENV
      - checkout
      - run:
          name: cleanup previous go installation
          command: sudo rm -rf /usr/local/go
      - docker/install-docker
      - go/install
      - kube-orb/install-kubectl
      - run: make

  run_cluster_tests:
    description: run all e2e tests inside the current KUBECONFIG configured cluster
    parameters:
      args:
        default: ""
        type: string
    steps:
      - run:
          name: Run Integration Tests
          no_output_timeout: 60m
          command: |
            make build-cmd && sudo install skupper /usr/local/bin
            go test -tags=integration -timeout=60m -v -p 1 ./test/integration/...
      - run:
          name: Run client tests in real cluster
          command: go test -v -count=1 ./client -use-cluster
      - run:
          name: Run skupper cli tests in real cluster
          command: go test -v -count=1 ./cmd/skupper -use-cluster
      - run:
          name: Run site-controller tests in real cluster
          command: go test -v -count=1 ./cmd/site-controller -use-cluster

  compile_go_program:
    description: Compile specified platform.
    parameters:
      platform:
        type: string
      goos:
        type: string
      goarch:
        type: string
      exesuffix:
        default: ""
        type: string
    steps:
      - run:
          name: Building << parameters.platform >>
          command: >-
            VERSION="${CIRCLE_TAG:-ci-${CIRCLE_BUILD_NUM}}";
            GOOS=<< parameters.goos >>
            GOARCH=<< parameters.goarch >>
            go build -ldflags "-X github.com/skupperproject/skupper/client.Version=${VERSION}"
            -o dist/<< parameters.platform >>/skupper<< parameters.exesuffix >>
            ./cmd/skupper

yaml-templates:
  branch_filters: &run_for_all_branches_and_numeric_tags
    filters:
      tags:
        only: /[0-9].*/

  release_filters: &run_for_numeric_tags
    filters:
      branches:
        ignore: /.*/
      tags:
        only: /[0-9].*/

  release_requires: &release_requires
    requires:
      - build-all
      - test
      - minikube_local_cluster_tests

workflows:
  version: 2.1
  build-workflow:
    jobs:
      - build-all:
          <<: *run_for_all_branches_and_numeric_tags
      - test:
          <<: *run_for_all_branches_and_numeric_tags
      - build_and_push_test_images:
          <<: *run_for_all_branches_and_numeric_tags

      - minikube_local_cluster_tests:
          <<: *run_for_all_branches_and_numeric_tags
          pre-steps:
            - prepare_for_local_cluster_tests
          requires:
            - test
            - build_and_push_test_images

      - publish-github-release-artifacts:
          <<: *run_for_numeric_tags
          <<: *release_requires

      - publish-github-release-images:
          <<: *run_for_numeric_tags
          <<: *release_requires

      - remove_from_registry: # will not run for tags, by default
          requires:
            - test
            - minikube_local_cluster_tests

jobs:
  test:
    executor:
      name: go/default
      tag: "1.13"
    steps:
      - checkout
      - run:
          name: "Enforce Go Formatted Code"
          command: >
              if [ `make format -s | wc -l` -ne 0 ]; then
                git --no-pager diff
                echo "Bad formatting! execute \"\$make format\" locally and push again!"
                exit 1
              fi
      - go/mod-download-cached
      - run: make
      - run: make package
      - run: make clean
      - go/test

  build_and_push_test_images:
    executor: local_cluster_test_executor
    steps:
      - docker/install-docker
      - checkout
      - run:
          name: Export environment variables persistent in execution shell
          command: |
            echo 'export SERVICE_CONTROLLER_IMAGE=<< pipeline.parameters.ci_service_controller_image >>' >> $BASH_ENV
            echo 'export SITE_CONTROLLER_IMAGE=<< pipeline.parameters.ci_site_controller_image >>' >> $BASH_ENV
            echo 'export TEST_IMAGE=<< pipeline.parameters.ci_test_image >>' >> $BASH_ENV
            source $BASH_ENV
      - run: echo "skupper_image = ${SKUPPER_SERVICE_CONTROLLER_IMAGE}"
      - run: docker login quay.io -u ${DOCKER_LOGIN} -p ${DOCKER_PASSWORD}
      - run: make -e docker-build
      - run: make -e docker-push

  remove_from_registry:
    executor:
      name: go/default
      tag: "1.13"
    steps:
      - setup_remote_docker
      - run: docker login quay.io -u ${DOCKER_LOGIN} -p ${DOCKER_PASSWORD}
      - run: go get github.com/genuinetools/reg
      - run: reg rm << pipeline.parameters.ci_service_controller_image >>
      - run: reg rm << pipeline.parameters.ci_site_controller_image >>
      - run: reg rm << pipeline.parameters.ci_test_image >>

  build-all:
    executor:
      name: go/default
      tag: "1.13"
    steps:
      - checkout
      - go/mod-download-cached

      - compile_go_program:
          goos: linux
          goarch: amd64
          platform: linux-amd64

      - compile_go_program:
          goos: linux
          goarch: "386"
          platform: linux-i386

      - compile_go_program:
          goos: windows
          goarch: "386"
          platform: windows-i386
          exesuffix: ".exe"

      - compile_go_program:
          goos: windows
          goarch: amd64
          platform: windows-amd64
          exesuffix: ".exe"

      - compile_go_program:
          goos: darwin
          goarch: "386"
          platform: mac-i386

      - compile_go_program:
          goos: darwin
          goarch: amd64
          platform: mac-amd64

      - compile_go_program:
          goos: linux
          goarch: arm
          platform: linux-arm32

      - compile_go_program:
          goos: linux
          goarch: arm64
          platform: linux-arm64

      - persist_to_workspace:
          root: .
          paths:
              - dist

  minikube_local_cluster_tests:
    executor: local_cluster_test_executor
    steps:
      - run: echo "skupper_image = ${SKUPPER_SERVICE_CONTROLLER_IMAGE}"
      - minikube-install
      - minikube-start
      - minikube-start-load-balancer
      - run: kubectl cluster-info
      - run_cluster_tests

  publish-github-release-artifacts:
    docker:
      - image: cibuilds/github:0.10
    steps:
      - attach_workspace:
          at: .
      - run:
          name: "Create a Draft Release on GitHub"
          command: |
            VERSION="${CIRCLE_TAG}"
            BASEDIR=`pwd`
            mkdir "${BASEDIR}/archives"
            for p in `ls dist` ; do
              cd "$BASEDIR/dist/$p"
              if [[ $p == windows* ]] ; then
                zip -q "${BASEDIR}/archives/skupper-cli-${VERSION}-$p.zip" *
              else
                tar -zcf "${BASEDIR}/archives/skupper-cli-${VERSION}-$p.tgz" *
              fi
            done
            cd ${BASEDIR}
            ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} -replace -prerelease -draft ${VERSION} "${BASEDIR}/archives"

  publish-github-release-images:
    executor:
      name: go/default
      tag: "1.13"
    steps:
      - checkout
      - setup_remote_docker
      - run: docker login quay.io -u ${DOCKER_LOGIN} -p ${DOCKER_PASSWORD}
      - run:
          name:
          command: |
            echo 'export SERVICE_CONTROLLER_IMAGE=quay.io/nicob87/service-controller:${CIRCLE_TAG}' >> $BASH_ENV
            echo 'export SITE_CONTROLLER_IMAGE=quay.io/nicob87/site-controller:${CIRCLE_TAG}' >> $BASH_ENV
            echo 'export TEST_IMAGE=quay.io/nicob87/skupper-tests:${CIRCLE_TAG}' >> $BASH_ENV
            source $BASH_ENV
            make -e docker-build
            make -e docker-push
