version: 2.1
orbs:
  go: gotest/tools@0.0.9

executors:
  golang:
    docker:
      - image: circleci/golang:1.13

commands:
  install-deps:
    steps:
      - go/install-ssh
      - go/install: {package: git}
  prepare:
    steps:
      - checkout
      - run: git submodule sync
      - run: git submodule update --init
  download-params:
    steps:
      - restore_cache:
          name: Restore parameters cache
          keys: 
            - 'v2-lotus-params-{{ checksum "build/proof-params/parameters.json" }}'
            - 'v2-lotus-params-'
          paths:
            - /var/tmp/filecoin-proof-parameters/
      - run:  ./lotus fetch-params
      - save_cache:
          name: Save parameters cache
          key: 'v2-lotus-params-{{ checksum "build/proof-params/parameters.json" }}'
          paths:
            - /var/tmp/filecoin-proof-parameters/


jobs:
  mod-tidy-check:
    executor: golang
    steps:
      - install-deps
      - prepare
      - go/mod-download
      - go/mod-tidy-check

  test:
    description: |
      Run tests with gotestsum.
    parameters:
      executor:
        type: executor
        default: golang
      go-test-flags:
        type: string
        default: ""
        description: Flags passed to go test.
      packages:
        type: string
        default: "./..."
        description: Import paths of packages to be tested.
      test-suite-name:
        type: string
        default: unit
        description: Test suite name to report to CircleCI.
      gotestsum-format:
        type: string
        default: short
        description: gotestsum format. https://github.com/gotestyourself/gotestsum#format
      coverage:
        type: string
        default: -coverprofile=coverage.txt
        description: Coverage flag. Set to the empty string to disable.
      codecov-upload:
        type: boolean
        default: false
        description: |
          Upload coverage report to https://codecov.io/. Requires the codecov API token to be
          set as an environment variable for private projects.
    executor: << parameters.executor >>
    steps:
      - install-deps
      - prepare
      - go/mod-download
      - run:
          command: make deps lotus
          no_output_timeout: 30m
      - download-params
      - go/install-gotestsum:
          gobin: $HOME/.local/bin
      - run:
          name: go test
          environment:
            GOTESTSUM_JUNITFILE: /tmp/test-reports/<< parameters.test-suite-name >>/junit.xml
            GOTESTSUM_FORMAT: << parameters.gotestsum-format >>
          command: |
            mkdir -p /tmp/test-reports/<< parameters.test-suite-name >>
            gotestsum -- \
              << parameters.coverage >> \
              << parameters.go-test-flags >> \
              << parameters.packages >>
      - store_test_results:
          path: /tmp/test-reports
      - when:
          condition: << parameters.codecov-upload >>
          steps:
            - go/install: {package: bash}
            - go/install: {package: curl}
            - run:
                shell: /bin/bash -eo pipefail
                command: |
                  bash <(curl -s https://codecov.io/bash)

  lint: &lint
    description: |
      Run golangci-lint.
    parameters:
      executor:
        type: executor
        default: golang
      golangci-lint-version:
        type: string
        default: 1.17.1
      concurrency:
        type: string
        default: '2'
        description: |
          Concurrency used to run linters. Defaults to 2 because NumCPU is not
          aware of container CPU limits.
      args:
        type: string
        default: ''
        description: |
          Arguments to pass to golangci-lint
    executor: << parameters.executor >>
    steps:
      - install-deps
      - prepare
      - go/mod-download
      - run:
          command: make deps
          no_output_timeout: 30m
      - go/install-golangci-lint:
          gobin: $HOME/.local/bin
          version: << parameters.golangci-lint-version >>
      - run:
          name: Lint
          command: |
            $HOME/.local/bin/golangci-lint run -v \
              --concurrency << parameters.concurrency >> << parameters.args >>
  lint-changes:
    <<: *lint

  lint-all:
    <<: *lint


workflows:
  version: 2
  ci:
    jobs:
      - lint-changes:
          args: "--new-from-rev origin/master"
      - test:
          codecov-upload: true
      - mod-tidy-check