CircleCI 2 has been released, which makes your CI faster and flexible.
I’ve accomplished 3 times faster CI build time on my public project.
Here is how I configured my circle.yml
.
Before: Circle 1.0 configuration
Circle 1.0 configuration is very simple.
# circle.yml
machine:
ruby:
version: 2.4.1
general:
artifacts:
- coverage
- tmp/capybara
After: Circle 2.0 configuration
Circle 2.0 configuration becomes a bit overwhelming, but I’ll explain it one by one.
# .circleci/config.yml
jobs:
build:
working_directory: ~/app
docker:
- image: circleci/ruby:2.5-node-browsers
environment:
RAILS_ENV: test
steps:
- checkout
# Restore bundle cache
- type: cache-restore
key: bundle-{{ checksum "Gemfile.lock" }}
# Bundle install dependencies
- run: bundle install --path vendor/bundle
# Store bundle cache
- type: cache-save
key: bundle-{{ checksum "Gemfile.lock" }}
paths:
- vendor/bundle
# Database setup
- run: bundle exec rails db:create db:schema:load
# RSpec
- run: bundle exec rspec
- store_artifacts:
path: coverage
- store_artifacts:
path: tmp/capybara
Working Directory
First of all, set your working_directory
, any name is okay.
working_directory: ~/app
docker image
Then, you need to specify base docker image on CircleCI 2. In this case, I used CircleCI official docker image listed here(All available images are listed here).
docker:
- image: circleci/ruby:2.5-node-browsers
environment:
RAILS_ENV: test
In environment
section, I configured environment variables for the base image.
Repository checkout
This line means checkout your code base from the repository.
- checkout
Bundle cache configuration
As of CircleCI 2, you need to configured cache setting by yourself. In my Rails project, bundler is used, so I configured bundle install cache as the following.
# Restore bundle cache
- type: cache-restore
key: bundle-{{ checksum "Gemfile.lock" }}
# Bundle install dependencies
- run: bundle install --path vendor/bundle
# Store bundle cache
- type: cache-save
key: bundle-{{ checksum "Gemfile.lock" }}
paths:
- vendor/bundle
Rails testing
Rails database setup and runnning RSpec:
# Database setup
- run: bundle exec rails db:create db:schema:load
# RSpec
- run: bundle exec rspec
PhantomJS
Update: If you use circleci/ruby:2.5-node-browsers
docker image, PhantomJS is bundled in the image. Therefore, you don’t have to follow the following step.
I used poltergeist as a Capybara javascript driver. It requires PhantomJS as a dependency but official Ruby docker image doesn’t include PhantomJS, so I needed to install PhantomJS by myself.
- run:
name: Install PhantomJS
command: |
mkdir -p ~/.phantomjs/${PHANTOM_JS_VERSION}
curl -L --output ~/.phantomjs/${PHANTOM_JS_VERSION}/phantomjs.tar.bz2 https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-${PHANTOM_JS_VERSION}-linux-x86_64.tar.bz2
tar xfvj ~/.phantomjs/${PHANTOM_JS_VERSION}/phantomjs.tar.bz2 -C ~/.phantomjs/${PHANTOM_JS_VERSION}/
chmod ugo+x ~/.phantomjs/${PHANTOM_JS_VERSION}/phantomjs-${PHANTOM_JS_VERSION}-linux-x86_64/bin/phantomjs
sudo ln -sf ~/.phantomjs/${PHANTOM_JS_VERSION}/phantomjs-${PHANTOM_JS_VERSION}-linux-x86_64/bin/phantomjs /usr/local/bin/phantomjs
I created environment variable of PhantomJS version(PHANTOM_JS_VERSION
) so that we can upgrade PhantomJS version easily.
Artifacts
You can upload artifacts by specifying store_artifacts
and the path
.
- store_artifacts:
path: coverage
- store_artifacts:
path: tmp/capybara
Comparison
CircleCI 1.0 Phase | CircleCI 1.0 | CircleCI 2.0 | improvement |
---|---|---|---|
INFRASTRUCTURE | 25 sec | 1 sec | 25x faster |
CHECKOUT | 10 sec | 1 sec | 10x faster |
MACHINE(cache restore) | 15 sec | 3 sec | 5x faster |
DEPENDENCIES(bundle install) | 6 sec | 1 sec | 6x faster |
DATABASE | 11 sec | 6 sec | 2x faseter |
TEST(RSpec) | 20 sec | 22 sec | - |
TEARDOWN(artifacts) | 26 sec | 1 sec | 26x fasetr |
Total build time on CircleCI | 02:02 | 00:40 | 3x faster |
* 0 sec is rounded to 1 sec
Conclusion
CircleCI 2.0 is much faster than CircleCI 1.0. Although CircleCI 2 configuration looks complex, it gives you flexibility and better CI experience. It’ll be worth it.