The guy with his head in his hands is me while lost researching continuous delivery for the nth time

The three laws of continuous delivery

James Ivings
Published in
4 min readApr 25, 2017

--

When starting our newest venture this year I once again lost hours (okay…days) working out the best way to approach it. With the project itself hoping to fill a missing segment of the continuous delivery lifecycle it was certainly an important consideration for us ✨

In this series of posts I will attack various aspects of continuous delivery and describe how we are tackling them.

Visibility & Feedback 👀

The superpower that we want to achieve is the ability to slip small incremental changes into production, as frequently as possible, without anyone noticing. Like all superpowers, this has it’s drawbacks. Although we don’t want the users to notice, we certainly do want our own team to be aware!

In other words — we need visibility of what will get deployed, where, and at what point.

With lots of things changing regularly it’s important that our app’s integrity does not suffer. For if it’s easy to deploy fixes, then it’s just as easy to deploy bugs 🐛

To combat this, at each step of the process it should be possible to review, request changes, and test everything that will make up the next release.

This two points lead us to the first draft of our three laws;

  1. we should always be able to see the code that is currently deployed to production so that we can use it for comparison
  2. every new feature must be tested and deployable
  3. all changes must be reviewed

I’ve always been a fan of the git flow model of branch management. The progression of code from developed features to review, testing, and finally deployment is well thought out and best of all — predictable.

As well as this, infinite lifetime branches (master and develop) make setting up deployments a breeze, and the uniform nature of other branch names make it simple to automate other tasks.

With git flow we can rephrase our previous laws like so;

  1. master should always represent what is currently deployed to production
  2. everything on develop must be tested and deployable
  3. all commits to develop must be reviewed

These form the basis of our continuous delivery lifecycle.

Deployment

I recently rediscovered CircleCI, which has excellent support for branch based deployment, making it a great fit for use with our three laws.

There are plenty of other CI tools around, but CircleCI has a good combination of pretty web-interface, good free trial, and agreeable documentation.

Using the suggested circle.yml file allows you to provide configuration within your repositories that CircleCI how to run your tests. You can also define deployment steps to run if certain branches change.

By adding this file, now anything that changes on any branch is tested by CircleCI. We can then follow our three laws easily for any new release;

  • when features are finished they are pushed to develop through pull-requests on GitHub in accordance with the third law.
  • develop is then automatically deployed to our staging environment and tested thoroughly in accordance with the second law.
  • if tests are green and we are happy the develop branch is manually merged onto master, which is deployed to production in accordance with the first law.

The deploy scripts that you can see are included in each project as a node_module dependency so that they can also be versioned in git. These are super simple and all basically do the following;

  1. create a tar from the built files
  2. copy the tar to the appropriate server, unpack it and update some symlinks
  3. restart the process on the server (we use pm2 for this which boasts clustering with zero downtime)

CircleCI allows you to specify environment variables for each project you build, so the addresses of the boxes that we deploy to are stored there, as well as any other private variables that we don’t want in git.

We’ve also replaced the default npm install with yarn, which lets you do some super awesome optimisations like;

yarn install --production --ignore-scripts --prefer-offline

This tells yarn to take a look at the current node_modules directory and discard all the modules that are not used in production. An easy and fast way of getting rid of all the development modules before we copy them to the server.

Using CircleCIs build numbers we also have a rudimentary rollback system in place, however this is yet to be used! 🎉

After several weeks use, I’m very happy with this setup. We have been releasing our software seamlessly, with very little interaction (except review), and so far we have encountered zero issues.

However, I’m sure there are plenty more improvements to be made, so please leave your suggestions in the comments!

The next steps in this series will cover the following;

  • updating running instances when things change
  • notifying users of changes

Want to see more articles like this? Click the 💙

--

--

James Ivings
ReleasePage

Leaving footsteps around the world in search of great food, strong coffee, and good times.