version: 2.1

executors:
  golang:
    parameters:
      version:
        type: string
        default: "1.16.7"
      resource_class:
        type: string
        default: medium
    docker:
      - image: circleci/golang:<< parameters.version >>
    resource_class: << parameters.resource_class >>
    working_directory: /go/src/github.com/pilosa/pilosa

commands:
  add-github-auth:
    steps:
      - run: git config --global url."https://moleculacorp:${GITHUB_PERSONAL_ACCESS_TOKEN}@github.com".insteadOf "https://github.com"
  restore-mod-cache:
    steps:
      - restore_cache:
          key: mod-cache-{{ checksum "go.sum" }}
  save-mod-cache:
    steps:
      - save_cache:
          key: mod-cache-{{ checksum "go.sum" }}
          paths:
            - /go/pkg/mod/
  checkout-plus:
    steps:
      - add-github-auth
      - checkout
      - restore-mod-cache

jobs:
  setup:
    executor:
      name: golang
    steps:
      - checkout-plus
      - run: go mod download
      - save-mod-cache
  check-license-headers:
    executor:
      name: golang
    steps:
      - checkout-plus
      - run: make check-license-headers
  linter:
    executor:
      name: golang
    steps:
      - checkout-plus
      - run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sudo sh -s -- -b /usr/local/bin v1.31.0
      - run: make golangci-lint
  go-mod-tidy:
    executor:
      name: golang
    steps:
      - checkout-plus
      - run: go mod tidy
      - run: git diff --exit-code -- go.mod go.sum
  check-changelog-label:
    executor:
      name: golang
    steps:
      - run: '[[ -n $CIRCLE_PULL_REQUEST ]] || circleci step halt || true' # Skip if this is not a pull request
      - run: curl https://moleculacorp:$GITHUB_PERSONAL_ACCESS_TOKEN@api.github.com/repos/molecula/featurebase/pulls/$(basename $CIRCLE_PULL_REQUEST) | jq "[.labels[] | .name | startswith(\"changelog\")] | any" -e
  test-build-arm:
    executor:
      name: golang
    steps:
      - checkout-plus
      - run: make build GOOS=linux GOARCH=arm GOARM=5
      - run: make build GOOS=linux GOARCH=arm GOARM=6
      - run: make build GOOS=linux GOARCH=arm GOARM=7
      - run: make build GOOS=linux GOARCH=arm64
  test:
    parameters:
      resource_class:
        type: string
        default: medium
      golang_version:
        type: string
        default: "1.16.7"
      shard_width:
        type: string
        default: "20"
      test_make_target:
        type: string
        default: "test"
      test_flags:
        type: string
        default: ""
      goarch:
        type: string
        default: amd64
    executor:
      name: golang
      version: << parameters.golang_version >>
      resource_class: << parameters.resource_class >>
    steps:
      - checkout-plus
      - run: sudo apt-get install lsof
      - run:
          command: make << parameters.test_make_target >> SHARD_WIDTH=<< parameters.shard_width >> GOARCH=<< parameters.goarch >>
          no_output_timeout: 30m
  cluster-tests:
    executor:
      name: golang
    steps:
      - checkout-plus
      - setup_remote_docker
      - run: make clustertests-build
  prerelease:
    executor:
      name: golang
    steps:
      - checkout-plus
      - run: make prerelease
      - store_artifacts:
          path: build
      - persist_to_workspace:
          root: .
          paths: build
  release:
    executor:
      name: golang
    steps:
      - checkout-plus
      - attach_workspace:
          at: .
      - setup_remote_docker:
          version: 19.03.13 # see https://support.circleci.com/hc/en-us/articles/360050934711
      - run: echo -n $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin
      - run: make docker-release
      - store_artifacts:
          path: build
      - persist_to_workspace:
          root: .
          paths: build
  publish_release:
    executor:
      name: golang
    steps:
      - attach_workspace:
          at: .
      - run: go get github.com/tcnksm/ghr
      - run: ghr -t ${GITHUB_PERSONAL_ACCESS_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} -delete ${CIRCLE_TAG} ./build/
  prerelease-upload:
    docker:
      - image: circleci/python:2.7-jessie
    steps:
      - checkout-plus
      - attach_workspace:
          at: .
      - run: sudo pip install awscli
      - run: make prerelease-upload
  docker-build:
    executor:
      name: golang
    steps:
      - checkout-plus
      - setup_remote_docker:
          version: 19.03.13 # see https://support.circleci.com/hc/en-us/articles/360050934711
      - run: echo -n $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin
      - run: make docker
      - run: docker run pilosa:$(git describe --tags) help
  dockerhub-upload-unstable:
    executor:
      name: golang
    steps:
      - checkout-plus
      - setup_remote_docker:
          version: 19.03.13 # see https://support.circleci.com/hc/en-us/articles/360050934711
      - run: echo -n $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin
      - run: make docker
      - run: docker run pilosa:$(git describe --tags) help
      - run: docker login -u $DOCKER_USER -p $DOCKER_PASS
      - run: make docker-tag-push DOCKER_TARGET=moleculacorp/pilosa:<< pipeline.git.branch >>
  dockerhub-upload-stable:
    executor:
      name: golang
    steps:
      - checkout-plus
      - setup_remote_docker:
          version: 19.03.13 # see https://support.circleci.com/hc/en-us/articles/360050934711
      - run: echo -n $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin
      - run: make docker
      - run: docker run pilosa:$(git describe --tags) help
      - run: docker login -u $DOCKER_USER -p $DOCKER_PASS
      - run: make docker-tag-push DOCKER_TARGET=moleculacorp/pilosa:<< pipeline.git.tag >>
      - run: make docker-tag-push DOCKER_TARGET=moleculacorp/pilosa:latest

workflows:
  build:
    jobs:
      - setup:
          context: molecula
          filters:
            tags:
              only: /^v.*/
      - linter:
          requires:
            - setup
      - check-license-headers:
          requires:
            - setup
      - go-mod-tidy:
          requires:
            - setup
      - check-changelog-label:
          context: molecula
          requires:
            - setup
      - test-build-arm:
          requires:
            - setup
      - test:
          name: test-golang-<< matrix.golang_version >>
          resource_class: large
          context: molecula
          requires:
            - setup
          matrix:
            parameters:
              golang_version: ["1.16.7"]
      - test:
          name: << matrix.test_make_target >>
          resource_class: xlarge
          context: molecula
          requires:
            - setup
          matrix:
            parameters:
              test_make_target: ["test-race"]
      - test:
          name: test-shardwidth-22
          shard_width: "22"
          resource_class: large
          requires:
            - setup
      - cluster-tests:
          requires:
            - setup
      - docker-build:
          context: molecula
          requires:
            - setup
      - prerelease:
          requires:
            - linter
            - check-license-headers
            - test-golang-1.16.7
      - release:
          context: molecula
          requires:
            - setup
          filters:
            tags:
              only: /^v.*/
      - publish_release:
          context: molecula
          requires:
            - release
          filters:
            tags:
              only: /^v.*/
            branches:
              ignore: /.*/
      - dockerhub-upload-unstable:
          context: molecula
          requires:
            - setup
          filters:
            branches:
              only: master
      - dockerhub-upload-stable:
          context: molecula
          requires:
            - setup
          filters:
            tags:
              only: /^v.*/
            branches:
              ignore: /.*/
