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}
buildis a special job that will be run every time we push our code to our VCS provider.working_directoryis a directory where the steps will be run. If it doesn’t exist, the directory will be created automatically.imageis the docker image that we would like to use. In my case, it’s thecircleci/node:10.18.0. Since it’s the earliest Node version that’s still being maintaned. The Yarn package manager is also included in this image.checkoutis a special step that will pull our code to the specifiedworking_directory.- The
restore_cacheis a step that will try to restore the previously saved cache based on itskey. In our case, the cache is the node modules, that’s why we use theyarn.lockto uniquely identify the cache. - While the
save_cacheis a step where we store the cache for any further builds. runis used for invoking a shell command. The firstrunis for installing all dependencies. The secondrunis for running the test suites.
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.