Trunk Based Development with feature toggles for continuous delivery
Being a developer have you ever felt that you or your colleague have/has been working on a feature branch for too long leading to a merge hell? Not delivering features frequently? Build is failing frequently? Not able to work on a shared piece of code/ feature? If you are working with the general git flow then these are the common bottlenecks with the continuous delivery and Trunk based development (TBD) is the answer to the above problems.
General git flow
There are many ways to design your CI flow, most people have a master/trunk branch which is protected, then a develop branch derived from master which is unprotected, team will work on feature branches made from develop and request for a merge into develop which gets merged to master after code review on feature branch. Release branches are made from master once or twice each in sprint to move the features to the production. This is how most of the projects work and is secure way of working. Some teams skip having develop branch and make the feature branches out of master and merge them into master after the reviews on feature branch. Both these ways will work perfectly but as stated above you can still make it better using trunk based development.
Trunk Based Development
Trunk based development is not a new way of working with git flow, it’s just an improved version of above two methods, in which you will (This is how we implemented TBD):
- Have single master/trunk branch which is unprotected
- Work on review branches which are small pieces of work pointing to a JIRA task rather than JIRA story or a bug found in production
- Commit either directly to the master, or to a review branch
- Commit always with task/feature name as first line of the comment
- Commit small working bits of code completed with test, with this you can emphasize on test driven development too
- Merge the review branches to master frequently, at least twice a day. So you are actually continuously Integrating with the master and pipeline
- Review incoming commits to merge into the master
- Be ready to send each and every commit to the production
- Hide the code behind the feature toggles whenever required
- Delete branches after merge so that commit graph is clean and understandable
- Make release/hot fix branches from master whenever required.
Having an unprotected master branch sounds dangerous but it’s not, Google and Facebook are doing this with over 20k developers doing thousands of commits into a single master every day, if we follow few basic guidelines we can take the leverage of this approach too to increase the velocity of the sprint to 2X at least, to work on shared pieces of code, to avoid the merge hell and to improve the CI/CD pipeline.
General git flow vs TBD
View here the short lived feature/task review branches.
F1, f2 – long lived feature branches, t1, t2 – short lived task branches, r1.1 – release branches.
Feature toggles (FF4J)
You can use the feature toggles to hide the feature recently went to the production if it failed in production, to perform A/B testing for a feature or to hide the code which is not ready to go to production yet. You can even have properties which can be changed during run time. Below is an example on how to implement FF4J in application with spring(Data) bean, annotations and mongoDB to store the features/properties.
- These code is an example on configuring FF4J with mongo and spring. Before the code you want to hide you can do
- When you deploy these solution you will see on the ff4j console(/FF4J/home) as
- So unless you enable the feature the code behind it will never execute. Having FF4J in place requires you to add the security for its UI or APIs.
Securing feature toggles
FF4J does not provide any out of the box security mechanism. But any servlet security mechanism should work.
There are two ways to secure FF4J.
- Securing the APIs
- Securing the web console
While securing the APIs is easy. For Securing the web console you need general security configuration like Spring Security.
FF4J is a single servlet so the request to URL /FF4J** will be served by FF4JDispatcherServlet, these are not part of spring context and not served by any Spring controller. We will cover securing GUI for FF4J in the next article.