How we code at SoapBox
How SoapBox uses GitHub
As I reflect on the last 5 years at SoapBox, it is amazing to see how far our team has come, and how the the process of how we code has changed.
Out with the old
When we first started in 2010, we used an SVN code repository hosted by Assembla. Assembla has decent issue tracking and project management capabilities. But, the underlying code repository technology (SVN) had inherent issues dealing with code conflicts. We were constantly having merge issues, even for very trivial code changes. This was more an issue of our branching strategy, which at the time was none. We would pull and commit straight off of a master branch.
In with the new
After a year using SVN we switched to git, and began paying GitHub for hosting. In retrospect, this was a great decision. Code conflicts were mostly dealt with automatically by git, and when there were issues, the GitHub App / SourceTree helped to highlight exactly which files caused the problem.
Our initial setup was quite primitive. We split up our applications into their own repositories (SoapBox the app, soapboxhq.com website, management portal, and an analytics dashboard). We were able to use GitHub to manage the permissions for each developer. We set up our code branches with one master branch that everyone on the team would checkout, make their updates, and commit back into. Our development team consisted of 3 people working very closely together (1 backend, 1 frontend and 1 fullstack). It was very easy to manage.
We also made use of the issue tracking capabilities to document our bugs and prioritize which ones to tackle first. Simple, but effective at 3 people.
Everyone needs a mentor
It wasn’t until we got our first Technology Advisor, Ian Douglas, that we actually realized the power and potential of GitHub within our small but growing team. Ian is a Sr. Web Architect and Lead Engineer at SendGrid, and an amazing mentor, advisor and now, friend.
Ian introduced us to the Agile Development Methodology (which, i'll touch on in a later post), and introduced us to scalable branch management strategy and the power of pull-requests.
The process he introduced to us in 2012 is the same process we use now with our team of 9 engineers.
Repositories
Every app built by SoapBox has their own git repository. We also have a series of libraries (most of them open-source) with their own repository. The SoapBox platform is spread across multiple repositories, which helps us ensure a separation of concerns.
Branch Management
Each git repository contains a series of code branches. This limits the chance for introducing code conflicts when the team is doing development work.
The typical branch structure looks like this:
- master: The primary branch that is always ready to deploy to production.
- staging: Our pre-release branch that pulls in all of the features and maintenance tasks for one final test before going to production. This is deployable on our staging servers only and is the default branch in the GitHub settings.
- hotfix: Any critical or major bugs are tackled via hotfix branches off of the master branch typically prefixed with “h-”, or “h-{issue number}-”. (i.e h-102-error-on-add-idea)
- features: Any new feature work is prefixed with “f-” (i.e. f-new-widget ).
- maintenance: Any maintenance that provides performance improvements/code refactoring/etc… and does not affect user experience is prefixed with “m-” (i.e. m-speed-boost-to-app )
- issue: Any change request or non critical bug is tackled through an issue branch pulled off of staging, this is prefixed with “i-{issue number}” (i.e. i-122-page-load-problem )
- experimental: Any experimental work that you expect to throw away, prefixed with “e-” (i.e. e-add-raw-queries-for-stats )
We prefix our branches with the indication of what type of update is being worked on, so when you `git branch -a` (show all branches, including remote) you can quickly understand what the work being done is about. The issues also include the issue number, which can come in handy to quickly look up the GitHub issues.
The Power of Pull-Requests
I cannot even imagine a world where SoapBox engineers checkout and commit straight to a master branch. I cannot believe we did that for about a year. Pull-requests help us ensure code quality and help maintain detailed documentation that can be helpful in filing SR&ED tax claims (Canadian tax credit for R&D).
We start a pull-request right after the branch has been created and outline what needs to be done or link to the issue that describes the requirements in full, this will include user stories, assumptions, definition of done and the testing strategy. If you reference “will fix #{issue number}” your issue will be linked to the pull request, and once the pull-request is merged in, the issue will close automatically.
We use these PR’s to document the progress, pose questions to the team, show the iterative design process by attaching output samples or images, and reference other pull-requests/issues. Once the code is complete, the engineer marks it for Code Review [CR].
We tag pull requests, so the Sr. team members know which ones are ready to be reviewed and pushed to production.
- [NR] — not ready — indicates that the code is not ready to be reviewed, no prefix tag also indicates this.
- [CR] — code review — indicates that development is finished, and a review for a senior developer is required to push the code into the parent branch.
- [MC] — make changes — indicates the the senior developer has reviewed the code, made notes, and the developer needs to make changes.
- [T] — test — indicates that the code review was successful, but the reviewer would like all elements of the pull request thoroughly tested on our staging environment.
- [P] — indicates the code has been reviewed, tested, and ready to be pushed.
The tags are added as the beginning of the title of the pull-request, for visibility.
Continuous Integration
Another benefit of using Pull-Requests in GitHub, is the ability to hook up automated testing suites, such as Travis-CI, to run a full test suite before merging branches into staging or master.
Milestones as Agile Sprints
The Issue tracking capabilities of GitHub meet our needs, however we use other tools for project management and managing our roadmap (will discuss in detail in a later post). Since our developers are in GitHub every day, we really want to keep them in this tool and not have to flip around to using multiple tools. We use GitHub Milestones to manage major projects (called Epic’s) and our general sprint work.
Each milestone is associated with a Sprint period (a 2-week period of focused work). We use the due date feature to help decide when the tasks are to be accomplished, and all features, maintenance tasks, issues and hotfixes are associated with a milestone. This provides us with an indicator to show us how far along we are in a sprint and what is outstanding.
Metrics
We did not do a formal analysis to quantify how effective it was to move our development process to a GitHub workflow. However we definitely have seen significant value. We have seen an improvement to the velocity in the code created, visibility into what each engineer is doing, a detailed historical record for features, maintenance and bug fixes and an integrated automated testing to reduce the amount of bugs introduced into our production environment. Overall, developer happiness has increased at least 5x.
It has been a 5 year journey fine-tuning our approach of how we code. It has changed overtime as processes breakdown with scale and as we take influences from other great engineering teams, such as Etsy, Spotify and Facebook. I expect our processes will continue to change and I look forward to seeing how things develop here at SoapBox.
There are a few things in this post that I briefly touched on, but I did not go into great detail:
- Our deployment strategy
- How we do project management
- Our engineering process
- Our engineering team culture
I may go into them in greater detail, if you readers find it of interest. Let me know your thoughts. Is this helpful? What is your engineering teams process? How do you code?