timhaley94/holdem

View on GitHub
.circleci/config.yml

Summary

Maintainability
Test Coverage
version: 2.1

orbs:
  aws-ecr: circleci/aws-ecr@6.12.2

executors:
  node:
    docker:
      - image: cimg/node:14.15.0
  terraform:
    docker:
      - image: hashicorp/terraform:0.14.2
  aws:
    docker:
      - image: circleci/python:3.7.1
  bash:
    docker:
      - image: bash:5.0.18

commands:
  javascript-setup:
    steps:
      - checkout:
          path: ~/repo
      - restore_cache:
          keys:
            - npm-deps-{{ checksum "package-lock.json" }}
      - run: npm ci
      - save_cache:
          key: npm-deps-{{ checksum "package-lock.json" }}
          paths:
            - node_modules
  terraform-setup:
    steps:
      - checkout:
          path: ~/repo
      - run: terraform init

jobs:
  lint-javascript:
    executor: node
    parameters:
      directory:
        default: ""
        type: string
    working_directory: ~/repo/<<parameters.directory>>
    steps:
      - javascript-setup
      - run: npm run lint
  test-javascript:
    executor: node
    parameters:
      directory:
        default: ""
        type: string
    working_directory: ~/repo/<<parameters.directory>>
    steps:
      - javascript-setup
      - attach_workspace:
          at: .
      - run: |
          npm run test
          ./cc/cc-test-reporter format-coverage --add-prefix=<<parameters.directory>> -t lcov -o cc/codeclimate.<<parameters.directory>>.json coverage/lcov.info
      - persist_to_workspace:
          root: .
          paths:
            - cc/codeclimate.<<parameters.directory>>.json
  setup-coverage:
    executor: node
    working_directory: ~/repo
    steps:
      - checkout:
          path: ~/repo
      - run:
          name:  Download cc-test-reporter
          command: |
            mkdir -p cc/
            curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc/cc-test-reporter
            chmod +x ./cc/cc-test-reporter
      - persist_to_workspace:
          root: .
          paths:
            - cc
  upload-coverage:
    executor: node
    working_directory: ~/repo
    environment: 
      - CC_TEST_REPORTER_ID: bccf9e20854b07b071ff25debf9d45fb35f99999febc7730a3458d023229386e
    steps:
      - checkout:
          path: ~/repo
      - attach_workspace:
          at: .
      - run:
          name: Upload coverage results to Code Climate
          command: |
            cc/cc-test-reporter sum-coverage cc/codeclimate.*.json -p 2 -o cc/codeclimate.total.json
            cc/cc-test-reporter upload-coverage -i cc/codeclimate.total.json
  build-javascript:
    executor: node
    working_directory: ~/repo/client
    steps:
      - javascript-setup
      - run: npm run build
      - persist_to_workspace:
          root: ./
          paths:
            - build
  lint-terraform:
    executor: terraform
    parameters:
      directory:
        default: ""
        type: string
    working_directory: ~/repo/infrastructure/<<parameters.directory>>
    steps:
      - terraform-setup
      - run: |
          if [[ $(terraform fmt) ]]; then
            echo "Terraform not formatted"
            exit 1
          fi
      - run: terraform validate
  build-terraform-vars:
    executor: bash
    parameters:
      directory:
        default: ""
        type: string
    working_directory: ~/repo/infrastructure/<<parameters.directory>>
    steps:
      - checkout:
          path: ~/repo
      - run: ./vars.sh > <<parameters.directory>>.tfvars
      - persist_to_workspace:
          root: ./
          paths:
            - <<parameters.directory>>.tfvars
  plan-terraform:
    executor: terraform
    parameters:
      directory:
        default: ""
        type: string
      plan_name:
        default: ""
        type: string
    working_directory: ~/repo/infrastructure/<<parameters.directory>>
    steps:
      - terraform-setup
      - attach_workspace:
          at: .
      - run: |
          if [ -f <<parameters.directory>>.tfvars ]; then
            cp ./<<parameters.directory>>.tfvars ./terraform.tfvars
          fi
      - run: terraform plan -out=./<<parameters.plan_name>>.plan
      - persist_to_workspace:
          root: ./
          paths:
            - <<parameters.plan_name>>.plan
      - store_artifacts:
          path: ./<<parameters.plan_name>>.plan
  apply-terraform:
    executor: terraform
    parameters:
      directory:
        default: ""
        type: string
      plan_name:
        default: ""
        type: string
      output_file:
        default: ""
        type: string
    working_directory: ~/repo/infrastructure/<<parameters.directory>>
    steps:
      - terraform-setup
      - attach_workspace:
          at: .
      - run: terraform apply ./<<parameters.plan_name>>.plan

workflows:
  deploy:
    jobs:
      - setup-coverage:
          context: AWS Prod
      - lint-javascript:
          name: lint-client-js
          directory: client
          context: AWS Prod
      - test-javascript:
          name: test-client-js
          directory: client
          context: AWS Prod
          requires:
            - setup-coverage
      - build-javascript:
          name: build-client-js
          context: AWS Prod
      - lint-javascript:
          name: lint-server-js
          directory: server
          context: AWS Prod
      - test-javascript:
          name: test-server-js
          directory: server
          context: AWS Prod
          requires:
            - setup-coverage
      - lint-terraform:
          name: lint-repo-terraform
          context: AWS Prod
          directory: repo
      - plan-terraform:
          name: plan-repo-terraform
          context: AWS Prod
          directory: repo
          plan_name: repo
      - lint-terraform:
          name: lint-app-terraform
          context: AWS Prod
          directory: app
      - build-terraform-vars:
          name: build-app-terraform-vars
          context: AWS Prod
          directory: app
      - plan-terraform:
          name: plan-app-terraform
          context: AWS Prod
          directory: app
          plan_name: app
          requires:
            - build-app-terraform-vars
      - upload-coverage:
          context: AWS Prod
          requires:
            - test-client-js
            - test-server-js
      - apply-terraform:
          name: apply-repo-terraform
          context: AWS Prod
          directory: repo
          plan_name: repo
          filters:
            branches:
              only: main
          requires:
            - lint-client-js
            - build-client-js
            - lint-server-js
            - lint-repo-terraform
            - plan-repo-terraform
            - lint-app-terraform
            - plan-app-terraform
            - upload-coverage
      - aws-ecr/build-and-push-image:
          name: build-server-image
          context: AWS Prod
          path: ./server
          repo: holdem_app
          tag: latest,$CIRCLE_SHA1
          filters:
            branches:
              only: main
          requires:
            - apply-repo-terraform
      - apply-terraform:
          name: apply-app-terraform
          context: AWS Prod
          directory: app
          plan_name: app
          filters:
            branches:
              only: main
          requires:
            - build-server-image