Risan Bagja

Switching to Circle CI

I used to use Travis CI for running my test suites. But now I’m switching to Circle CI for my latest open-source JavaScript project: helpers. Though it has no build matrix feature out of the box, the test suites often complete faster (I’m speaking about the free version here).

Similar to Travis CI, Circle CI also uses a YAML file for configuration. We have to store this configuration file in .circleci/config.yml. Here’s the Circle CI configuration file that I use in my latest JavaScript project. Note that I use Yarn instead of the built in NPM for the package manager in this project.

version: 2.1
jobs:
  build:
    working_directory: ~/repo
    docker:
      - image: circleci/node:10.18.0
    steps:
      - checkout
      - restore_cache:
          key: dependency-cache-{{ checksum "yarn.lock" }}
      - run:
          name: install-dependencies
          command: yarn install --frozen-lockfile
      - save_cache:
          key: dependency-cache-{{ checksum "yarn.lock" }}
          paths:
            - ~/.cache/yarn
      - run:
          name: run-tests
          command: yarn test
      - run:
          name: upload-coverage
          command: bash <(curl -s https://codecov.io/bash) -t ${CODECOV_TOKEN}

Code Coverage

I’m using Jest to run my test suites and it can collect code coverage information out of the box. All we have to do is to set the collectCoverage in our jest.config.js file to true:

module.exports = {
  // other options...

  collectCoverage: true,
};

By default, the coverage report will be stored in a coverage directory. And in the last run I invoke a command to upload this coverage report to Codecov. I’m using an environment variable named CODECOV_TOKEN to store the Codecov upload token. You can set this environment variable in Project Settings > Environment Variables.

There’s also an Orb (sharable configuration element in Circle CI) for Codecov integration that we can use: codecov/codecov. But I think the Codecov bash uploader is a very simple command that we can use directly.

Note for NPM

If you use a default NPM package manager, there’s a slight configuration difference.

- restore_cache:
    # Use package-lock.json
    key: dependency-cache-{{ checksum "package-lock.json" }}
- run:
    name: install-dependencies
    command: npm install
- save_cache:
    key: dependency-cache-{{ checksum "package-lock.json" }}
    paths:
      - ./node_modules # Different cache paths
- run:
    name: run-tests
    command: npm run test

Also, note that the caching mechanism will only work if you track the generated yarn.lock or package-lock.json. If you don’t track these files, as an alternative you can use the package.json file directly to generate a unique checksum for the cache key.