version: 2

defaults: &defaults
  working_directory: /go/src/github.com/cosmos/cosmos-sdk
  docker:
    - image: circleci/golang:1.11.1
  environment:
    GOBIN: /tmp/workspace/bin

docs_update: &docs_deploy
  working_directory: ~/repo
  docker:
    - image: tendermint/docs_deployment
  environment:
    AWS_REGION: us-east-1

jobs:

  setup_dependencies:
    <<: *defaults
    steps:
      - run: mkdir -p /tmp/workspace/bin
      - run: mkdir -p /tmp/workspace/profiles
      - checkout
      - restore_cache:
          keys:
            - v1-pkg-cache
      - run:
          name: tools
          command: |
            export PATH="$GOBIN:$PATH"
            make get_tools
      - run:
          name: dependencies
          command: |
            export PATH="$GOBIN:$PATH"
            make get_vendor_deps
      - run:
          name: binaries
          command: |
            export PATH="$GOBIN:$PATH"
            make install
            make install_examples
      - persist_to_workspace:
          root: /tmp/workspace
          paths:
            - bin
            - profiles

  lint:
    <<: *defaults
    parallelism: 1
    steps:
      - attach_workspace:
          at: /tmp/workspace
      - checkout
      - run:
          name: dependencies
          command: |
            export PATH="$GOBIN:$PATH"
            make get_vendor_deps
      - run:
          name: Get metalinter
          command: |
            export PATH="$GOBIN:$PATH"
            make get_tools
            make get_dev_tools
      - run:
          name: Lint source
          command: |
            export PATH="$GOBIN:$PATH"
            make test_lint

  integration_tests:
    <<: *defaults
    parallelism: 1
    steps:
      - attach_workspace:
          at: /tmp/workspace
      - checkout
      - run:
          name: dependencies
          command: |
            export PATH="$GOBIN:$PATH"
            make get_vendor_deps
      - run:
          name: Test cli
          command: |
            export PATH="$GOBIN:$PATH"
            make test_cli
            make test_examples

  test_sim_modules:
    <<: *defaults
    parallelism: 1
    steps:
      - attach_workspace:
          at: /tmp/workspace
      - checkout
      - run:
          name: dependencies
          command: |
            export PATH="$GOBIN:$PATH"
            make get_vendor_deps
      - run:
          name: Test individual module simulations
          command: |
            export PATH="$GOBIN:$PATH"
            make test_sim_modules

  test_sim_gaia_nondeterminism:
    <<: *defaults
    parallelism: 1
    steps:
      - attach_workspace:
          at: /tmp/workspace
      - checkout
      - run:
          name: dependencies
          command: |
            export PATH="$GOBIN:$PATH"
            make get_vendor_deps
      - run:
          name: Test individual module simulations
          command: |
            export PATH="$GOBIN:$PATH"
            make test_sim_gaia_nondeterminism

  test_sim_gaia_fast:
    <<: *defaults
    parallelism: 1
    steps:
      - attach_workspace:
          at: /tmp/workspace
      - checkout
      - run:
          name: dependencies
          command: |
            export PATH="$GOBIN:$PATH"
            make get_vendor_deps
      - run:
          name: Test full Gaia simulation
          command: |
            export PATH="$GOBIN:$PATH"
            make test_sim_gaia_fast

  test_sim_gaia_import_export:
    <<: *defaults
    parallelism: 1
    steps:
      - attach_workspace:
          at: /tmp/workspace
      - checkout
      - run:
          name: dependencies
          command: |
            export PATH="$GOBIN:$PATH"
            make get_vendor_deps
      - run:
          name: Test Gaia import/export simulation
          command: |
            export PATH="$GOBIN:$PATH"
            make test_sim_gaia_import_export

  test_sim_gaia_multi_seed:
    <<: *defaults
    parallelism: 1
    steps:
      - attach_workspace:
          at: /tmp/workspace
      - checkout
      - run:
          name: dependencies
          command: |
            export PATH="$GOBIN:$PATH"
            make get_vendor_deps
      - run:
          name: Test multi-seed Gaia simulation
          command: |
            export PATH="$GOBIN:$PATH"
            make test_sim_gaia_multi_seed

  test_cover:
    <<: *defaults
    parallelism: 4
    steps:
      - attach_workspace:
          at: /tmp/workspace
      - checkout
      - run:
          name: dependencies
          command: |
            export PATH="$GOBIN:$PATH"
            make get_vendor_deps
      - run: mkdir -p /tmp/logs
      - run:
          name: Run tests
          command: |
            export PATH="$GOBIN:$PATH"
            make install
            export VERSION="$(git describe --tags --long | sed 's/v\(.*\)/\1/')"
            for pkg in $(go list github.com/cosmos/cosmos-sdk/... | grep -v github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test | grep -v '/simulation' | circleci tests split --split-by=timings); do
              id=$(basename "$pkg")
              GOCACHE=off go test -timeout 8m -race -coverprofile=/tmp/workspace/profiles/$id.out -covermode=atomic "$pkg" | tee "/tmp/logs/$id-$RANDOM.log"
            done
      - persist_to_workspace:
          root: /tmp/workspace
          paths:
            - "profiles/*"
      - store_artifacts:
          path: /tmp/logs

  upload_coverage:
    <<: *defaults
    parallelism: 1
    steps:
      - attach_workspace:
          at: /tmp/workspace
      - checkout
      - run:
          name: dependencies
          command: |
            export PATH="$GOBIN:$PATH"
            make get_vendor_deps
      - run:
          name: gather
          command: |
            set -ex

            echo "mode: atomic" > coverage.txt
            for prof in $(ls /tmp/workspace/profiles/); do
              tail -n +2 /tmp/workspace/profiles/"$prof" >> coverage.txt
            done
      - run:
          name: upload
          command: bash <(curl -s https://codecov.io/bash) -f coverage.txt

  localnet:
      working_directory: /home/circleci/.go_workspace/src/github.com/cosmos/cosmos-sdk
      machine:
        image: circleci/classic:latest
      environment:
        GOBIN: /home/circleci/.go_workspace/bin
        GOPATH: /home/circleci/.go_workspace/
        GOOS: linux
        GOARCH: amd64
      parallelism: 1
      steps:
        - checkout
        - run:
            name: run localnet and exit on failure
            command: |
              pushd /tmp
              wget https://dl.google.com/go/go1.11.linux-amd64.tar.gz
              sudo tar -xvf go1.11.linux-amd64.tar.gz
              sudo rm -rf /usr/local/go
              sudo mv go /usr/local
              popd
              set -x
              make get_tools
              make get_vendor_deps
              make build-linux
              make localnet-start
              ./scripts/localnet-blocks-test.sh 40 5 10 localhost
  deploy_docs:
    <<: *docs_deploy
    steps:
      - checkout
      - run:
          name: Trigger website build
          command: |
            export LAST_COMMIT=`git rev-parse HEAD`
            export DOCS_COMMIT=`git log -1 --format=format:%H --full-diff docs`
            if [[ $DOCS_COMMIT == $LAST_COMMIT ]]; then
              chamber exec cosmos-sdk -- start_website_build
            else
              echo "No changes to docs detected"
            fi

workflows:
  version: 2
  test-suite:
    jobs:
      - deploy_docs
      - setup_dependencies
      - lint:
          requires:
            - setup_dependencies
      - integration_tests:
          requires:
            - setup_dependencies
      - test_sim_modules:
          requires:
            - setup_dependencies
      - test_sim_gaia_nondeterminism:
          requires:
            - setup_dependencies
      - test_sim_gaia_fast:
          requires:
            - setup_dependencies
      - test_sim_gaia_import_export:
          requires:
            - setup_dependencies
      - test_sim_gaia_multi_seed:
          requires:
            - setup_dependencies
      - test_cover:
          requires:
            - setup_dependencies
      - localnet:
          requires:
            - setup_dependencies
      - upload_coverage:
          requires:
            - test_cover
