version: 2

defaults: &defaults
  working_directory: ~/repo
  docker:
    - image: circleci/node:14
    - image: mongo:4.2

jobs:
  build:
    <<: *defaults
    steps:
      - checkout
      - restore_cache:
          key: dependency-cache-{{ checksum "yarn.lock" }}
      - run:
          name: Install Dependences
          command: yarn install
      - save_cache:
          key: dependency-cache-{{ checksum "yarn.lock" }}
          paths:
            - ./node_modules
      - persist_to_workspace:
          root: ~/repo
          paths:
            - .

  test:
    <<: *defaults

    steps:
      - attach_workspace:
          at: ~/repo
      - run:
          name: Eslint
          command: yarn lint
      - run:
          name: Unit Test
          command: NODE_ENV=test yarn test --coverage
      - run:
          name: Upload Unit Test Coverage
          command: bash <(curl -s https://codecov.io/bash)
      - run:
          name: integration test
          command: NODE_ENV=test yarn test:int

  release:
    <<: *defaults

    steps:
      - attach_workspace:
          at: ~/repo
      - setup_remote_docker
      - run:
          name: Setup Environment Variables
          command: |
            echo "export TAG=`if test $CIRCLE_TAG; then echo $CIRCLE_TAG; else echo "$CIRCLE_BRANCH"; fi`" >> $BASH_ENV
            source $BASH_ENV
      - run:
          name: Build and Push Image
          command: |
            unset CI
            chmod +x bin/build-docker.sh
            bin/build-docker.sh $TAG $DOCKER_USER $DOCKER_PASS $DOCKER_REGISTRY

workflows:
  version: 2
  main:
    jobs:
      - build:
          filters: # required since `release` has tag filters AND requires `build`
            tags:
              only: /.*/
      - test:
          requires:
            - build
          filters: # required since `release` has tag filters AND requires `test`
            tags:
              only: /.*/
      - release:
          context: production
          requires:
            - test
          filters:
            tags:
              only: /v.*/
            branches:
              ignore: /.*/
