version: 2.1

aliases:
  make_out_dirs: &make_out_dirs
    run: mkdir -p /tmp/circleci-artifacts /tmp/circleci-workspace /tmp/circleci-test-results/{unit,sharness}
  restore_gomod: &restore_gomod
    restore_cache:
      keys:
        - v4-dep-{{ .Branch }}-{{ checksum "~/ipfs/go-ipfs/go.sum" }}-{{ .Environment.CIRCLE_JOB }}
        - v4-dep-{{ .Branch }}-{{ checksum "~/ipfs/go-ipfs/go.sum" }}-
        - v4-dep-{{ .Branch }}-
        - v4-dep-master-
  store_gomod: &store_gomod
      save_cache:
        key: v4-dep-{{ .Branch }}-{{ checksum "~/ipfs/go-ipfs/go.sum" }}-{{ .Environment.CIRCLE_JOB }}
        paths:
          - ~/go/pkg/mod
          - ~/.cache/go-build/

default_environment: &default_environment
  SERVICE: circle-ci
  TRAVIS: 1
  CIRCLE: 1
  CIRCLE_TEST_REPORTS: /tmp/circleci-test-results
  CIRCLE_ARTIFACTS: /tmp/circleci-artifacts
  GIT_PAGER: cat

executors:
  golang:
    docker:
      - image: circleci/golang:1.13
    working_directory: ~/ipfs/go-ipfs
    environment:
      <<: *default_environment
      GO111MODULE: "on"
      TEST_NO_DOCKER: 1
      TEST_NO_FUSE: 1
      GOPATH: /home/circleci/go
      TEST_VERBOSE: 1
  node:
    docker:
      - image: circleci/node:10
    working_directory: ~/ipfs/go-ipfs
    environment:
      <<: *default_environment

jobs:
  gobuild:
    executor: golang
    steps:
    - checkout
    - *make_out_dirs
    - *restore_gomod
    - run:
        command: make cmd/ipfs-try-build
        environment:
          TEST_NO_FUSE: 0
    - run:
        command: make cmd/ipfs-try-build
        environment:
          TEST_NO_FUSE: 1
    - *store_gomod
  golint:
    executor: golang
    steps:
    - checkout
    - *make_out_dirs
    - *restore_gomod
    - run: |
        make -O test_go_lint
    - *store_gomod
  gotest:
    executor: golang
    steps:
    - checkout
    - *make_out_dirs
    - *restore_gomod

    - run: |
        make -j 1 test/unit/gotest.junit.xml \
        && [[ ! $(jq -s -c 'map(select(.Action == "fail")) | .[]' test/unit/gotest.json) ]]
    - run: 
        when: always
        command: bash <(curl -s https://codecov.io/bash) -cF unittests -X search -f coverage/unit_tests.coverprofile

    - run:
        when: always
        command: mv "test/unit/gotest.junit.xml" /tmp/circleci-test-results/unit

    - *store_gomod

    - store_test_results:
        path: /tmp/circleci-test-results
    # Save artifacts
    - store_artifacts:
        path: /tmp/circleci-artifacts
    - store_artifacts:
        path: /tmp/circleci-test-results
  sharness:
    executor: golang
    steps:
    - run: sudo apt install socat
    - checkout
    - *make_out_dirs
    - *restore_gomod

    - run: make -O -j 10 coverage/sharness_tests.coverprofile test/sharness/test-results/sharness.xml TEST_GENERATE_JUNIT=1 CONTINUE_ON_S_FAILURE=1

    - run:
        when: always
        command: bash <(curl -s https://codecov.io/bash) -cF sharness -X search -f coverage/sharness_tests.coverprofile

    - run: mv "test/sharness/test-results/sharness.xml" /tmp/circleci-test-results/sharness
    # make sure we fail if there are test failures
    - run: find test/sharness/test-results -name 't*-*.sh.*.counts' | test/sharness/lib/sharness/aggregate-results.sh | grep 'failed\s*0'

    - *store_gomod

    - store_test_results:
        path: /tmp/circleci-test-results
    # Save artifacts
    - store_artifacts:
        path: /tmp/circleci-artifacts
    - store_artifacts:
        path: /tmp/circleci-test-results
  build:
    executor: golang
    steps:
      - checkout
      - *make_out_dirs
      - *restore_gomod
      - run:
          name: Building
          command: make build
      - run:
          name: Storing
          command: |
            mkdir -p /tmp/circleci-workspace/bin
            cp cmd/ipfs/ipfs /tmp/circleci-workspace/bin
      - persist_to_workspace:
          root: /tmp/circleci-workspace
          paths:
            - bin/ipfs
      - *store_gomod
  interop:
    executor: node
    parallelism: 4
    steps:
      - *make_out_dirs
      - attach_workspace:
          at: /tmp/circleci-workspace
      - run:
          name: Cloning
          command: |
            git clone https://github.com/ipfs/interop.git
            git -C interop log -1
      - restore_cache:
          keys:
            - v1-interop-{{ checksum "~/ipfs/go-ipfs/interop/package-lock.json" }}
            - v1-interop-
      - run:
          name: Installing dependencies
          command: |
            npm install
          working_directory: ~/ipfs/go-ipfs/interop
      - save_cache:
          key: v1-interop-{{ checksum "~/ipfs/go-ipfs/interop/package-lock.json" }}
          paths:
            - ~/ipfs/go-ipfs/interop/node_modules
      - run:
          name: Installing js-ipfs
          command: |
            npm install ipfs ipfs-http-client
          working_directory: ~/ipfs/go-ipfs/interop
      - run:
          name: Installing reporting tools
          command: |
            npm install --save-dev mocha-junit-reporter@1.23.1 mocha-multi-reporters@1.1.0
          working_directory: ~/ipfs/go-ipfs/interop
      - run:
          name: Running tests
          command: |
            mkdir -p /tmp/test-results/interop/
            export MOCHA_FILE="$(mktemp /tmp/test-results/interop/unit.XXXXXX.xml)"
            echo '{"reporterEnabled": "mocha-junit-reporter, spec"}' > mocha-conf.json
            node_modules/.bin/mocha -R mocha-multi-reporters --reporter-options "configFile=mocha-conf.json" \
              $(sed -n -e "s|^require('\(.*\)')$|test/\1|p" test/node.js | circleci tests split)
          working_directory: ~/ipfs/go-ipfs/interop
          environment:
            IPFS_REUSEPORT: false
            LIBP2P_ALLOW_WEAK_RSA_KEYS: true
            IPFS_GO_EXEC: /tmp/circleci-workspace/bin/ipfs
      - store_test_results:
          path: /tmp/test-results
  go-ipfs-api:
    executor: golang
    steps:
      - *make_out_dirs
      - attach_workspace:
          at: /tmp/circleci-workspace
      - run:
          name: Cloning
          command: |
            git clone https://github.com/ipfs/go-ipfs-api.git
            git -C go-ipfs-api log -1
      - run:
          name: Starting the daemon
          command: /tmp/circleci-workspace/bin/ipfs daemon --init --enable-namesys-pubsub
          background: true
      - run:
          name: Waiting for the daemon
          no_output_timeout: 30s
          command: |
            while ! /tmp/circleci-workspace/bin/ipfs id --api=/ip4/127.0.0.1/tcp/5001 2>/dev/null; do
              sleep 1
            done
      - restore_cache:
          keys:
            - v1-go-api-{{ checksum "~/ipfs/go-ipfs/go-ipfs-api/go.sum" }}
            - v1-go-api-
      - run:
          command: go test -v ./...
          working_directory: ~/ipfs/go-ipfs/go-ipfs-api
      - save_cache:
          key: v1-go-api-{{ checksum "~/ipfs/go-ipfs/go-ipfs-api/go.sum" }}
          paths:
            - ~/go/pkg/mod
            - ~/.cache/go-build/
      - run:
          name: Stopping the daemon
          command: /tmp/circleci-workspace/bin/ipfs shutdown
  go-ipfs-http-client:
    executor: golang
    steps:
      - *make_out_dirs
      - attach_workspace:
          at: /tmp/circleci-workspace
      - run:
          name: Cloning
          command: |
            git clone https://github.com/ipfs/go-ipfs-http-client.git
            git -C go-ipfs-http-client log -1
      - restore_cache:
          keys:
            - v1-http-client-{{ checksum "~/ipfs/go-ipfs/go-ipfs-http-client/go.sum" }}
            - v1-http-client-
      - run:
          name: go test -v ./...
          command: |
            export PATH=/tmp/circleci-workspace/bin:$PATH
            go test -v ./...
          working_directory: ~/ipfs/go-ipfs/go-ipfs-http-client
      - save_cache:
          key: v1-http-client-{{ checksum "~/ipfs/go-ipfs/go-ipfs-http-client/go.sum" }}
          paths:
            - ~/go/pkg/mod
            - ~/.cache/go-build/
workflows:
  version: 2
  test:
    jobs:
    - gobuild
    - golint
    - gotest
    - sharness
    - build
    - interop:
        requires:
          - build
    - go-ipfs-api:
        requires:
          - build
    - go-ipfs-http-client:
        requires:
          - build
