version: 2

# Docker environment.
defaults: &defaults
  working_directory: /go/src/istio.io/istio
  docker:
    - image: istio/ci:go1.10-k8s1.9-helm2.7.2-minikube0.25
  environment:
    GOPATH: /go

# org context settings. If developing on a clone, please configure:

# DOCKER_USER
# DOCKER_PASS
# HUB: ex istio, costinm (it is not the hub, but the dockerhub org or user)

# VM environment. Includes docker.
integrationDefaults: &integrationDefaults
  machine: true
  working_directory: /go/src/istio.io/istio #same as docker
  environment:
    CHANGE_MINIKUBE_NONE_USER: true
    HUB: docker.io/dnerepo
    TAG: dontpush
    GOPATH: /go

jobs:
  e2e-simple:
    <<: *integrationDefaults
    environment:
            - KUBECONFIG: /go/out/minikube.conf
            - TEST_ENV: minikube-none
            - GOPATH: /go
    steps:
      - type: shell
        name: Initialize Working Directory
        pwd: /
        command: |
          sudo mkdir -p /go/src/istio.io/istio
          sudo chown -R circleci /go
          mkdir -p /go/out
          mkdir /home/circleci/logs
      - checkout
      - attach_workspace:
          at:  /go
      - run: make sync
      - run: bin/testEnvRootMinikube.sh start
      - run:
          command: |
            if [ ! -f /go/out/linux_amd64/release/pilot-discovery ]; then
              # Should only happen when re-running a job, and the workspace is gone
              time make build test-bins
            fi
            make docker.all generate_yaml
      - run: bin/testEnvRootMinikube.sh wait
      - run: docker images
      - run: make test/minikube/noauth/e2e_simple
      - run:
          name: dumpsys
          when: always
          command: |
            mkdir -p /go/out/logs
            # TODO: move to a make target 'dumpsys'.
            kubectl get all -o wide --all-namespaces
            kubectl cluster-info dump > /go/out/logs/cluster-info.dump.txt
            kubectl describe pods -n istio-system > /go/out/logs/pods-system.txt
            /go/bin/go-junit-report </go/out/tests/test-report-noauth-simple.raw > /go/out/tests/test-report-noauth-simple.xml
      - store_artifacts:
          path: /home/circleci/logs
      - store_artifacts:
          path: /tmp
      - store_artifacts:
          path: /var/lib/localkube/
      - store_test_results:
          path: /go/out/tests

  e2e-dashboard:
    <<: *integrationDefaults
    environment:
            - KUBECONFIG: /go/out/minikube.conf
            - TEST_ENV: minikube-none
            - GOPATH: /go
    steps:
      - type: shell
        name: Initialize Working Directory
        pwd: /
        command: |
          sudo mkdir -p /go/src/istio.io/istio
          sudo chown -R circleci /go
          mkdir -p /go/out
          mkdir /home/circleci/logs
      - checkout
      - attach_workspace:
          at:  /go
      - run: make sync
      - run: bin/testEnvRootMinikube.sh start
      - run:
          command: |
            if [ ! -f /go/out/linux_amd64/release/pilot-discovery ]; then
              # Should only happen when re-running a job, and the workspace is gone
              time make build test-bins
            fi
            make docker.all generate_yaml
      - run: bin/testEnvRootMinikube.sh wait
      - run: docker images
      - run: PATH=$GOPATH/bin:$PATH make e2e_dashboard E2E_ARGS="--skip_cleanup -use_local_cluster -test.v"
      - store_artifacts:
          path: /home/circleci/logs
      - store_artifacts:
          path: /tmp
      - store_artifacts:
          path: /var/lib/localkube/

  e2e-mixer:
    <<: *integrationDefaults
    environment:
            - KUBECONFIG: /go/out/minikube.conf
            - TEST_ENV: minikube-none
            - GOPATH: /go
    steps:
      - type: shell
        name: Initialize Working Directory
        pwd: /
        command: |
          sudo mkdir -p /go/src/istio.io/istio
          sudo chown -R circleci /go
          mkdir -p /go/out
          mkdir /home/circleci/logs
      - checkout
      - attach_workspace:
          at:  /go
      - run: make sync
      - run: bin/testEnvRootMinikube.sh start
      - run:
          command: |
            if [ ! -f /go/out/linux_amd64/release/pilot-discovery ]; then
              # Should only happen when re-running a job, and the workspace is gone
              time make build test-bins
            fi
            make docker.all generate_yaml
      - run: bin/testEnvRootMinikube.sh wait
      - run: docker images
      - run:
            no_output_timeout: 20m
            # Run the test even if previous failed
            when: always
            command: |
                  make e2e_mixer E2E_ARGS="--skip_cleanup -use_local_cluster -cluster_wide -test.v"
      - store_artifacts:
          path: /home/circleci/logs
      - store_artifacts:
          path: /tmp

  e2e-bookinfo:
    <<: *integrationDefaults
    environment:
            - KUBECONFIG: /go/out/minikube.conf
            - TEST_ENV: minikube-none
            - GOPATH: /go
    steps:
      - type: shell
        name: Initialize Working Directory
        pwd: /
        command: |
          sudo mkdir -p /go/src/istio.io/istio
          sudo chown -R circleci /go
          mkdir -p /home/circleci/logs
      - checkout
      - attach_workspace:
          at:  /go
      - run: make sync
      - run: bin/testEnvRootMinikube.sh start
      - run:
          command: |
            if [ ! -f /go/out/linux_amd64/release/pilot-discovery ]; then
              # Should only happen when re-running a job, and the workspace is gone
              time make build test-bins
            fi
            make docker.all generate_yaml
      - run: bin/testEnvRootMinikube.sh wait
      - run: docker images
      - run:
            no_output_timeout: 20m
            when: always
            command: |
              make e2e_bookinfo E2E_ARGS="--skip_cleanup -use_local_cluster -cluster_wide -test.v"
      - store_artifacts:
          path: /home/circleci/logs
      - store_artifacts:
          path: /tmp

  e2e-pilot:
    <<: *integrationDefaults
    environment:
            - GOPATH: /go
            - KUBECONFIG: /go/out/minikube.conf
            - TEST_ENV: minikube-none
            - HUB: docker.io/dnerepo
            - TAG: dontpush
            - SKIP_EGRESS: 1
    steps:
      - type: shell
        name: Initialize Working Directory
        pwd: /
        command: |
          sudo mkdir -p /go/src/istio.io/istio
          sudo chown -R circleci /go
          mkdir -p /home/circleci/logs
      - checkout
      - attach_workspace:
          at:  /go
      - run: make sync
      - run: bin/testEnvRootMinikube.sh start
      - run:
          command: |
            if [ ! -f /go/out/linux_amd64/release/pilot-discovery ]; then
              # Should only happen when re-running a job, and the workspace is gone
              time make build test-bins
            fi
            make docker.all generate_yaml
      - run: bin/testEnvRootMinikube.sh wait
      - run: docker images
      - run: make test/minikube/noauth/e2e_pilot_alpha1 HUB="${HUB}" TAG="${TAG}"
      - run:
          name: dumpsys
          when: always
          command: |
            # TODO: move to a make target 'dumpsys'.
            kubectl get all -o wide --all-namespaces
            kubectl cluster-info dump > /go/out/logs/cluster-info.dump.txt
            kubectl describe pods -n pilot-noauth-system > /go/out/logs/pods-system.txt
            kubectl describe pods -n pilot-noauth > /go/out/logs/pods-test.txt
            cat /go/out/tests/*.raw | /go/bin/go-junit-report > /go/out/tests/test-report-noauth-pilot.xml
      - store_artifacts:
          path: /go/out/tests
      - store_artifacts:
          path: /go/out/logs
      - store_artifacts:
          path: /tmp
      - store_test_results:
          path: /go/out/tests

  e2e-pilot-alpha3:
    <<: *integrationDefaults
    environment:
            - GOPATH: /go
            - KUBECONFIG: /go/out/minikube.conf
            - TEST_ENV: minikube-none
            - HUB: docker.io/dnerepo
            - TAG: dontpush
            - SKIP_EGRESS: 1
    steps:
      - type: shell
        name: Initialize Working Directory
        pwd: /
        command: |
          sudo mkdir -p /go/src/istio.io/istio
          sudo chown -R circleci /go
          mkdir -p /home/circleci/logs
      - checkout
      - attach_workspace:
          at:  /go
      - run: make sync
      - run: bin/testEnvRootMinikube.sh start
      - run:
          command: |
            if [ ! -f /go/out/linux_amd64/release/pilot-discovery ]; then
              # Should only happen when re-running a job, and the workspace is gone
              time make build test-bins
            fi
            make docker.all generate_yaml
      - run: bin/testEnvRootMinikube.sh wait
      - run: docker images
      - run: make test/minikube/noauth/e2e_pilot HUB="${HUB}" TAG="${TAG}"
      - run:
          name: dumpsys
          when: always
          command: |
            # TODO: move to a make target 'dumpsys'.
            kubectl get all -o wide --all-namespaces
            kubectl cluster-info dump > /go/out/logs/cluster-info.dump.txt
            kubectl describe pods -n pilot-noauth-system > /go/out/logs/pods-system.txt
            kubectl describe pods -n pilot-noauth > /go/out/logs/pods-test.txt
            /go/bin/go-junit-report </go/out/tests/test-report-noauth-pilot.raw > /go/out/tests/test-report-noauth-pilot.xml
      - store_artifacts:
          path: /go/out/tests
      - store_artifacts:
          path: /go/out/logs
      - store_artifacts:
          path: /tmp
      - store_test_results:
          path: /go/out/tests

  e2e-pilot-auth:
    <<: *integrationDefaults
    environment:
            - GOPATH: /go
            - KUBECONFIG: /go/out/minikube.conf
            - TEST_ENV: minikube-none
            - HUB: docker.io/dnerepo
            - TAG: dontpush
            - SKIP_EGRESS: 1
    steps:
      - type: shell
        name: Initialize Working Directory
        pwd: /
        command: |
          sudo mkdir -p /go/src/istio.io/istio
          sudo chown -R circleci /go
          mkdir -p /home/circleci/logs
      - checkout
      - attach_workspace:
          at:  /go
      - run: make sync
      - run: bin/testEnvRootMinikube.sh start
      - run:
          command: |
            if [ ! -f /go/out/linux_amd64/release/pilot-discovery ]; then
              # Should only happen when re-running a job, and the workspace is gone
              time make build test-bins
            fi
            make docker.all generate_yaml
      - run: bin/testEnvRootMinikube.sh wait
      - run: docker images
      - run: make test/minikube/auth/e2e_pilot HUB="${HUB}" TAG="${TAG}"
      - run:
          name: alpha1
          when: always
          command: |
            make test/minikube/auth/e2e_pilot_alpha1 HUB="${HUB}" TAG="${TAG}"
      - run:
          name: dumpsys
          when: always
          command: |
            # TODO: move to a make target 'dumpsys'.
            kubectl get all -o wide --all-namespaces
            kubectl cluster-info dump > /go/out/logs/cluster-info.dump.txt
            kubectl describe pods -n pilot-auth > /go/out/logs/pods-system.txt
            kubectl describe pods -n pilot-auth-system > /go/out/logs/pods-test.txt
            cat /go/out/tests/*.raw | /go/bin/go-junit-report > /go/out/tests/test-report-noauth-pilot.xml
      - store_artifacts:
          path: /go/out/tests
      - store_artifacts:
          path: /go/out/logs
      - store_artifacts:
          path: /tmp
      - store_test_results:
          path: /go/out/tests

  # Until alpha1 is deprecated
  e2e-pilot-auth-egress:
    <<: *integrationDefaults
    environment:
            - GOPATH: /go
            - KUBECONFIG: /go/out/minikube.conf
            - TEST_ENV: minikube-none
            - HUB: docker.io/dnerepo
            - TAG: dontpush
    steps:
      - type: shell
        name: Initialize Working Directory
        pwd: /
        command: |
          sudo mkdir -p /go/src/istio.io/istio
          sudo chown -R circleci /go
          mkdir -p /home/circleci/logs
      - checkout
      - attach_workspace:
          at:  /go
      - run: make sync
      - run: bin/testEnvRootMinikube.sh start
      - run:
          command: |
            if [ ! -f /go/out/linux_amd64/release/pilot-discovery ]; then
              # Should only happen when re-running a job, and the workspace is gone
              time make build test-bins
            fi
            make docker.all generate_yaml
      - run: bin/testEnvRootMinikube.sh wait
      - run: docker images
      - run: make test/minikube/auth/e2e_pilot_alpha1 HUB="${HUB}" TAG="${TAG}"
      - run:
          name: dumpsys
          when: always
          command: |
            # TODO: move to a make target 'dumpsys'.
            kubectl get all -o wide --all-namespaces
            kubectl cluster-info dump > /go/out/logs/cluster-info.dump.txt
            kubectl describe pods -n pilot-auth > /go/out/logs/pods-system.txt
            kubectl describe pods -n pilot-auth-system > /go/out/logs/pods-test.txt
            /go/bin/go-junit-report </go/out/tests/test-report-auth-pilot-v1.raw > /go/out/tests/test-report-auth-pilot-v1.xml
      - store_artifacts:
          path: /go/out/tests
      - store_artifacts:
          path: /go/out/logs
      - store_artifacts:
          path: /tmp
      - store_test_results:
          path: /go/out/tests

  # Run nightly, to verify 'dep update' works
  depupdate:
    <<: *defaults
    steps:
      - checkout
      - run: make submodule-sync
      - run: make depend.status # check before any change
      - run: make depend.update
      - run: ( cd vendor ; git status  ) # just to see what changes
      - run: make init build
      - run:
          name: Status and artifacts
          command: make depend.status ISTIO_OUT=/go/out
      - store_artifacts:
          path: vendor/Gopkg.lock
      - store_artifacts:
          path: /go/out/dep.dot
      # TODO: auto-commit Gopkg.lock if test is successful

  codecov:
    <<: *defaults
    resource_class: xlarge
    environment:
      KUBECONFIG: /go/src/istio.io/istio/.circleci/config
      ISTIO_BIN: /go/bin
    steps:
      - checkout
      - run: make submodule-sync
      - run:
          name: Starting Kubernetes API Server standalone and running tests
          command: |
            make localTestEnv
            cd /go/src/istio.io/istio
            # Not failing if coverage number changes - integration tests are still not counted,
            MAXPROCS=6 bin/codecov.sh || true
      - run:
          name: Uploading code coverage to codecov.io
          when: always
          command: bash <(curl -s https://codecov.io/bash) -f /go/out/codecov/coverage.txt
      - store_artifacts:
          path: /go/out/codecov

  test:
    <<: *defaults
    environment:
      KUBECONFIG: /go/src/istio.io/istio/.circleci/config
    resource_class: xlarge
    steps:
      - checkout
      - run: make sync
      - run:
          command: |
            mkdir -p /go/out/tests
            trap "go-junit-report </go/out/tests/go-test-report.out > /go/out/tests/go-test-report.xml" EXIT
            make localTestEnv
            make test T=-v | tee -a /go/out/tests/go-test-report.out
      - store_test_results:
          path: /go/out/tests

  dependencies:
    <<: *defaults
    steps:
      - run: echo "Placeholder until an admin removes the required job"

  racetest:
    <<: *defaults
    environment:
      KUBECONFIG: /go/src/istio.io/istio/.circleci/config
      RACE_TEST: 1
    resource_class: xlarge
    steps:
      - checkout
      - run: make submodule-sync
      - run:
          command: |
            mkdir -p /go/out/racetests
            trap "go-junit-report </go/out/racetests/go-racetest-report.out > /go/out/racetests/go-racetest-report.xml" EXIT
            make localTestEnv
            make -k pilot-racetest mixer-racetest broker-racetest security-racetest T=-v | tee -a /go/out/racetests/go-racetest-report.out
      - store_test_results:
          path: /go/out/racetests

  benchcheck:
    <<: *defaults
    environment:
      KUBECONFIG: /go/src/istio.io/istio/.circleci/config
    steps:
      - checkout
      - run: make submodule-sync
      - run:
          command: |
            mkdir -p /go/out/benchcheck
            make benchcheck | tee -a /go/out/benchcheck/go-benchcheck-report.out
      - store_test_results:
          path: /go/out/benchcheck

  build:
    <<: *defaults
    resource_class: xlarge
    steps:
      - checkout
      - run: make sync
      - run: make build test-bins /go/bin/go-junit-report
      - persist_to_workspace:
          root: /go
          paths:
            - pkg/linux_amd64
            - bin
            - out
      - run:  make sidecar.deb
      - store_artifacts:
          path: /go/out/istio-sidecar.deb

  lint:
    <<: *defaults
    environment:
      KUBECONFIG: /go/src/istio.io/istio/.circleci/config
    resource_class: xlarge
    steps:
      - checkout
      - run: make sync
      - run: make lint

  nightly:
    <<: *defaults
    resource_class: xlarge
    environment:
      TAG: circleci-nightly
    steps:
      - checkout
      - attach_workspace:
          at:  /go
      - run: make sync
      - setup_remote_docker:
          docker_layer_caching: true
      - run: make istio-archive
      # Build the docker+extra
      - run: make docker.push.basedebug
      - run:
          command: |
            if [ ! -z "${DOCKER_USER}" ] ; then
              echo "Pushing docker images"
              docker login -u ${DOCKER_USER} -p ${DOCKER_PASS}
              # The xenail debug image is built first, will be used in the next steps
              make docker.push.basedebug docker.all push
            fi

  goxbuild:
    <<: *defaults
    resource_class: xlarge
    steps:
      - checkout
      - run: make submodule-sync
      - run:
          command: |
            cp -a /usr/local/go /go
            export PATH=/go/go/bin:$PATH
            export GOROOT=/go/go
            cd /go/src/istio.io/istio
            make build GOOS=darwin KUBECONFIG=/go/src/istio.io/istio/.circleci/config
            make build GOOS=linux GOARCH=arm KUBECONFIG=/go/src/istio.io/istio/.circleci/config
      - store_artifacts:
          path: /go/bin

workflows:
  version: 2
  nightly:
    triggers:
       - schedule:
           cron: "0 0 * * *"
           filters:
             branches:
               only:
                 - master
    jobs: #daisy chained steps ending with docker push
      - depupdate
      - build
      - test
      - e2e-simple:
          requires:
            - test
            - build
      - e2e-dashboard:
          requires:
            - test
            - build
      - e2e-mixer:
          requires:
            - test
            - build
      - e2e-pilot:
          requires:
            - test
            - build
      - e2e-pilot-alpha3:
          requires:
            - test
            - build
      - e2e-pilot-auth:
          requires:
            - test
            - build
      - benchcheck:
          requires:
            - test
            - build
      # Compile for mac and arm
      - goxbuild:
          requires:
            - test
            - build
      # Nightly release
      - nightly:
          context: org-global
          requires:
            - e2e-simple
            - e2e-pilot
            - e2e-pilot-alpha3

  periodic:
    triggers:
       - schedule:
           cron: "20 1,4,7,10,13,16,19,22 * * *"
           filters:
             branches:
               only:
                 - master
    jobs:
      - depupdate
      - build
      - test
      - e2e-simple:
          requires:
            - build
      - e2e-dashboard:
          requires:
            - build
      - e2e-pilot-alpha3:
          requires:
            - build
      - e2e-pilot:
          requires:
            - build
      - e2e-pilot-auth:
          requires:
            - build
      - benchcheck:
          requires:
            - test
            - build
      - e2e-mixer:
          requires:
            - build

  flaky:
    triggers:
       - schedule:
           cron: "20 2,8,14,20 * * *"
           filters:
             branches:
               only:
                 - master
    jobs:
      - build
      - racetest
      - e2e-pilot-auth-egress:
          requires:
            - build
      # Bookinfo requires 3 nodes, not a good fit for CircleCI.
      - e2e-bookinfo:
          requires:
            - build

  all:
    jobs:
      - dependencies
      - lint
      - build
      - test
      - codecov:
           requires:
            - build
      - e2e-pilot:
          requires:
            - build
      - e2e-pilot-alpha3:
          requires:
            - build
      - e2e-pilot-auth:
          requires:
            - build
      - e2e-simple:
          requires:
            - build
      - racetest:
          requires:
            - test
