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.
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.
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
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.
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.
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.