Experience With CircleCI

We are now using CircleCI to automatically test and deploy our NodeJS services. The business-marketing term for this is “Continuous Integration”. With simple tools like CircleCI, Heroku, and our own managed database services, continuous integration is the norm for us, not the exception. The lynchpin of the process is CircleCi, and it is simple to set up, but there are a few tricks to be aware of.

What we had

Before CircleCI, we used a self-hosted Jenkins instance. Jenkins works well. Organizing jenkins to deploy were running two independent projects: one for testing code, and one for packaging and publishing the resulting asset.

This system only built assets for the master branch. All commands for testing, packaging, publishing were stored directly in Jenkins instead of being under version control.

Our setup was ok, but life can be easier. But, we found the time spent nursing our Jenkins environment to be painful.

Goals

Testing, packaging, and publishing steps

Being fans of #badassrockstartech, we are using Grunt, which is a modular Make system. We use Grunt to run our testing, packaging, and publishing steps.

Powered by npm, we can utilize 3rd-party code to accomplish common tasks (e.g. transpiling coffeescript into javascript) and can define our own tasks (e.g. packaging and publishing to s3).

By moving the logic of testing, packaging, and publishing out of Jenkins and into Grunt, configuring CircleCI becomes very simple and intuitive.

Don’t commit credentials

We moved our commands to publish to S3 into Grunt, but did not want to commmit our credentials. This is one thing we want to remain hard-coded in our CI settings separate from our code.

To accomplish this, I decided a simple export AWS_SECRET_KEY=1234 as a command hard-coded into CircleCI’s web interface would do the trick, but due to the way CircleCI executes your commands you cannot alter the environmental variables in this way.

I reached out to Circle for help, and David Lowe at Circle responded within a few hours with a solution.

We should be adding a secure credential storage mechanism soon, but for now, you will need to work around it.

You’ve got the right idea, but unfortunately, ‘export AWSSECRETKEY’ won’t quite work because each command runs in a separate shell. Instead, if you want to do this from the UI, you need to do something like:

echo 'export AWS_SECRET_KEY=1234' >> ~/.circlerc

The .circlerc file is sourced before each test and deploy command.

This works perfectly for our process. We hard-code our sensitive data bits into the pre-dependency section of the web UI.

Simply call test, package, and publish steps

Now that our tasks are defined and our build server configured with credentials, the only thing left is to do all the CI work.

The web UI is an easy way to specify commands to run, but you get more options and flexibility in defining a circle.yml file to tell CircleCI what to do.

This is our circle.yml file.

## Tests
test:  
  override:
    - grunt test

## Deployment options

deployment:  
  default:
    branch: [master, stage, dev]
    commands:
      - grunt clean coffee package publish:"$CIRCLE_BRANCH"

Conclusion

Being a service company ourselves, we value offloading tasks to others so we can focus more on what we’re good at. CircleCI integrates seamlessly with GitHub, allows us to customize what we need, and gives us a very pretty an intuitive UI with very little effort.

I’m happy to hear they just raised a bunch of money, and I’m excited to see how they continue to make the world of continuous integration easier.