.circleci/config.yml

Summary

Maintainability
Test Coverage
version: 2.0

default-docker-config: &default-docker-config
  docker:
    - image: circleci/python:3.6-browsers
      environment:
        CI_NODE_VERSION: 6.14.4
        NPM_CONFIG_ENGINE_STRICT: true
        WD_CHROME_ARGS: --headless --no-sandbox --disable-setuid-sandbox
        SKIP_STATIC_ASSET_BUILDING: yup
        DEBUG: yup
        DATABASE_URL: postgres://postgres@localhost/calc

        # Some of our integration tests either take a really long time to run or
        # are very error-prone via Selenium, so prefer RoboBrowser for now.
        TEST_WITH_ROBOBROWSER: yup

        # These environment variables affect the running of Webdriver/Selenium
        # tests.
        DJANGO_LIVE_TEST_SERVER_ADDRESS: 127.0.0.1:8000-8010,8080,9200-9300
    - image: circleci/postgres:9.5
      environment:
        POSTGRES_USER: postgres
        POSTGRES_DB: calc
    - image: redis:3.2-alpine

jobs:
  prod-test:
    working_directory: ~/calc
    <<: *default-docker-config
    steps:
      - checkout
      - restore_cache:
          key: v1-py-cache-{{ .Branch }}-{{ checksum "requirements-dev.txt" }}-{{ checksum "requirements.txt" }}
      - run:
          name: Activate venv and install requirements
          command: |
            python3 -m venv ~/venv

            echo ". ~/venv/bin/activate" >> $BASH_ENV
            source $BASH_ENV

            pip install -r requirements-dev.txt
      - save_cache:
          name: Save python deps cache
          key: v1-py-cache-{{ .Branch }}-{{ checksum "requirements-dev.txt" }}-{{ checksum "requirements.txt" }}
          paths:
            - ~/venv
      - run:
          name: Run tests against production instance
          command: py.test production_tests
      
  build:
    working_directory: ~/calc
    <<: *default-docker-config
    steps:
      - checkout

      - restore_cache:
          key: v1-py-cache-{{ .Branch }}-{{ checksum "requirements-dev.txt" }}-{{ checksum "requirements.txt" }}
      - run:
          name: Activate venv and install requirements
          command: |
            python3 -m venv ~/venv

            echo ". ~/venv/bin/activate" >> $BASH_ENV
            source $BASH_ENV

            pip install -r requirements-dev.txt
      - save_cache:
          name: Save python deps cache
          key: v1-py-cache-{{ .Branch }}-{{ checksum "requirements-dev.txt" }}-{{ checksum "requirements.txt" }}
          paths:
            - ~/venv

      - run:
          name: Install nvm and node @ CI_NODE_VERSION
          command: |
            curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash
            echo ". ~/.nvm/nvm.sh" >> $BASH_ENV
            source $BASH_ENV
            nvm install $CI_NODE_VERSION

      - run:
          name: Uninstall any old version of gulp (only needed for upgrade)
          command: |
            npm rm --g gulp
      
      - run:
          name: Install yarn and gulp
          command: |
            npm install -g yarn gulp-cli
      
      - run:
          name: Ensure gulp4 is installed
          command: |
            npm install -g gulp4

      - run:
          name: Install node dependencies
          command: |
            yarn --frozen-lockfile
      - save_cache:
          name: Save node deps cache
          key: v1-node-cache-{{ .Branch }}-{{ checksum "yarn.lock" }}
          paths:
            - node_modules
            - ~/.yarn-cache

      - run:
          name: Display versions
          command: |
            echo $(node --version)
            echo $(npm --version)
            echo $(yarn --version)
            echo $(google-chrome -version)
            echo $(chromedriver -version)
            echo $(pwd)
      - run:
          name: Run linters and static analysis
          command: |
            python manage.py ultratest flake8 eslint mypy bandit typescript
      - run:
          name: Build front end and run front end tests
          command: |
            yarn gulp build
            yarn test --runInBand

      - run:
          name: CodeClimate before-build
          command: |
            curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
            chmod +x ./cc-test-reporter
            ./cc-test-reporter before-build

      - run:
          name: Run python tests
          command: |
            # Note that this MUST come after building the front end assets
            py.test --cov=. --cov-report xml:./coverage/python/coverage.xml

      - run:
          name: CodeClimate combine and upload coverage
          command: |
            # Format the various coverage reports
            ./cc-test-reporter format-coverage -t lcov -o coverage/codeclimate.jest.json coverage/jest/lcov.info
            ./cc-test-reporter format-coverage -t coverage.py -o coverage/codeclimate.python.json coverage/python/coverage.xml
            # Combine the test coverage reports
            ./cc-test-reporter sum-coverage coverage/codeclimate.*.json
            # Attempt to submit the coverage report, but don't fail the build if this fails (`|| true`)
            ./cc-test-reporter upload-coverage || true

      - deploy:
          name: Deploy to dev
          command: |
            if [[ "${CIRCLE_BRANCH}" == "develop" ]]; then
              DEPLOY_ENV=dev ./.circleci/deploy-circle.sh
            fi
      - deploy:
          name: Deploy to prod
          command: |
            if [[ "${CIRCLE_BRANCH}" == "master" ]]; then
              DEPLOY_ENV=prod ./.circleci/deploy-circle.sh
            fi

workflows:
  version: 2
  build-test-and-deploy:
    jobs:
      - build
  nightly:
    jobs:
      - prod-test
    triggers:
      - schedule:
          # every night at 2:11 AM UTC (10:11 PM ET)
          cron: "11 02 * * *"
          filters:
            branches:
              only:
                - master