CircleCI has quickly become one of the dominating continuous integration platforms available today, boasting support for Docker, Android, and now iOS through the use of OS X virtual machines.
GitHub has been the de facto standard for hosting Git repositories for some time now. While worthy competitors do exist, GitHub‘s ability to innovate around a piece of freely available version control software adds significant value to its brand.
While both CircleCI and GitHub technically work in their own light, their combination into a software development workflow creates a valuable synergy.
Since there are many ways to setup a development workflow, this article will describe one particular way that we’ve integrated both GitHub and CircleCI into our workflow. There may certainly be other ways that work better for your team, so only use this brief guide as one example.
Our development flow is very similar to http://nvie.com/posts/a-successful-git-branching-model/ — with the exception being how we integrate CircleCI. Our circle.yml file looks a bit like this:
After our tests complete we have three separate deployment sections that handle unique scenarios based on the branch being built.
dev branch
Each time our dev branch has a feature branch merged into it, a build is triggrered, tests are run, and a deploy script pushes our Docker images to our private registry. Once that process completes, the same script deploy the Docker images to our Elastic Beanstalk environment
release branches
We use release branches to prevent our master branch from containing untested code. When we’re ready to ship, we use our Slack bot, Hubot, to create a new branch from a recent commit and prefix the name with “release-“. Instead of actually deploying anything, this deployment section runs our merge_master.sh script which merges the release branch with master and pushes it to GitHub, triggering a build on master.
While this does add an extra step and a bit of extra build time, it ensures that our master branch is always tested and deployable at any given time. Release branches also give us the opportunity to easily deploy releases to our QA environment for testing and create an easy path for patches.
master branch
Our master branch is ultimately responsible for deployments. Once our release branch is merged, a build on master is triggered, and master successfully builds, the Docker images are pushed to our private registry and a new Elastic Beanstalk version is created.
When we’re ready to ship, a command to Hubot deploys the given Elastic Beanstalk version to our environment.
Protecting master
Our workflow dictates that master should always be stable and deployable. To strengthen this concept we protect our master branch in GitHub which prevents force pushes and merges from untested branches from occurring.
The combination of GitHub and CircleCI provides us with a clean and relatively simple workflow that supports staged deployments, a stable master branch, and continuous integration.
Leave a Reply