This article is the second in a series discussing trends, tools, and processes related to your Software Delivery processes. We will uncover how taking on a DevOps mindset and making incremental changes can have a tremendous impact and ROI to your organization. In this installment, we explore a foundational component to DevOps, effective use of source control and planning for the throughput which DevOps will bring to your teams with best practice branching strategies.
Are you using source control effectively?
Version control is the foundational component to development teams. It acts as the recorder of development history and catalyst for enabling high performing development teams to multi-task. There are several choices out there for source control – most notably Git and Subversion. The two are based on two different paradigms: distributed versus centralized, respectively. As some of you may know Git was used as the source control technology of choice for linux kernel development.
At UDig we recommend moving teams to Git for several reasons: Git allows for remote development which is faster, more powerful, and takes up less space. For those who previously held onto Subversion for the lack of visual clients for Git in the past, there are now several options including Sourcetree and TourtoiseGit. However, whichever route you choose, the step of getting your organization to adopt source control is an absolute must and a foundation for moving towards a DevOps culture.
Successful Branching Strategies
After choosing a solution for your source control the next step is to define a branching strategy. Over the years many different branching strategies have evolved: stable trunk with all development in branches, release branches with all development in master, using pull requests, and GitFlow. Our end goal of Continuous Delivery and keeping software development as efficient as possible with an emphasis on team communication shifts our focus to keeping all development in the mainline and avoiding long-lived feature branches.
Developers should pull and commit often, avoiding large check-ins that can cause conflicts. The goal here is to have every commit result in a build that should be able to be pushed to production (or at least a production-like environment). Feature branches might seem to make a lot of sense…working in isolation without the fear of breaking another person’s code or having someone else’s code break theirs. However, a couple things can result from this, the developers will develop in their isolated branches and one developer could be left with a very messy merge. Also, when any refactoring work needs to be done the resulting renaming or moving of files can create large conflicts. So to avoid this, developers tend to be less likely to attempt refactoring in fear of these types of conflicts and the team is left with an untidy codebase.
Instead we encourage developing together in mainline which promotes smaller and more frequent commits and easier to maintain merges. This also encourages the team to communicate more often when conflicts do arise taking a look at how to refactor shared pieces of code, and keeping a much more tidy and easy to maintain codebase. Resolving issues quickly is essential since the mainline of code should remain healthy and theoretically be able to be deployed to production at any time (given the build is passing).
One of the primary goals of continuous integration is that every build should be able to result in a push to production. Having a mainline development strategy forces developer code integrations and a stable code base. Adopting a mainline development strategy, one might ask, “What happens if a feature isn’t ready to be released to all customers?” In the past, feature branches have been used as a weak attempt at modular architecture – releasing only branches of code when the feature is ready to be fully released. Instead, patterns such as feature toggle should be implemented to control who has access to these new features (if anyone). If the feature isn’t code complete and seems to be affecting other functionality, then take a look at the above paragraph. The codebase should have been refactored to separate the concerns of that one piece of code.
The ability to cherry pick commits is no longer an option with Continuous Integration and Continuous Delivery models. CI and CD force communication within the team when a developer goes to pull and notices a conflict or issue immediately.
Recently, we developed 5 Misconceptions about DevOps, a guide highlighting the top misconceptions around DevOps today and sharing our perspective on the true state of DevOps today. Download it today and get it touch to talk about the DevOps strategy for your organization.