Git Workflow for Continuous Integration
A Git workflow tested in battle and adapted for continuous integration
Many companies are embracing new development practices such as adopting Git as their source control or version control tool. As soon as they adopt it, they have to create a workflow, meaning who is committing code, where do they commit, who is reviewing the code, and what code gets eventually pushed to production.
The naive engineer or decision maker goes about this as most other people do, they google it and most likely they land on the famous git-flow, which looks very appealing, has a diagram that people feel it makes sense, and is anyway better than the average ad-hoc git flow solution.
If you ever find yourself in this situation (looking for a git workflow), don’t do the same mistake other people did, don’t use git-flow!
Ok, you might be asking now: “Why not?”
Basically because it sucks. It’s not built for continuous integration and for multiple developers. It might work though if you are an one to two developer shop with no prospects to get bigger, but if you are a multiple developer, continuous integration, multiple per day deployment team, this git-flow will not work.
Here’s why: Because every feature is branched from an unhealthy state, which is develop. If you are branching from develop, you are tying yourself to all the other features. It’s all features go together into release or none does.
This situation is pretty bad and it takes you back in time, when the release cycle of a software was months and required a lot of coordination.
I’ll give you an example: Let’s say there are four developers working on four different feature branches, branched out from develop branch. The first two committed their changes already and they are in the QA process. The other two developers already have the changes that the previous developers merged to develop branch. Then one of the four developers successfully finishes the work and the QA process and wants to advance the feature to be pushed to production.
Surprise! He cannot because alongside his changes there are the changes of the other two developers, who didn't complete their features. Therefore the feature that was completed has to wait for the entire development cycle (all features to be completed) to cut the release for all four features.
This is very bad, as we cannot afford in today’s rapid software development world to block ourselves from releasing to production early and often.
“Ok. So what are you saying here? What is the solution you propose?”, you might ask. All right, let’s see the solution.
The solution is adapted for an infinite number of environments (local, development, QA, hotfix, production and many more, if your company requires more).
Here’s a short description on how it works:
Master branch is the source of truth. Everything that is in master branch is healthy, has passed code review and can serve as a base for every new feature.
Every environment has its own branch, and as soon as a feature named semantically feature/feature_name completes development, it can advance individually on each environment.
Each feature branch is pushed remotely, so if by any chance a developer’s machine crashes, the code is kept remotely and redundant.
So a developer works on a feature called buttons. It branches out of master with a feature branch called feature/buttons. After he completes his development, he merges his individually in the develop branch, which should be automatically deployed in the development environment.
If that works well, then he merges the individual feature branch in the QA branch and that is deployed to the QA environment and the quality assurance process gets triggered.
After all the dev testing and QA processes are complete, then the new feature needs to be merged to master. The developer makes a pull request and that triggers the code review process, which if it’s successful, then the code base owner / tech lead / library or software author or shepherd merges the feature branch into master.
The deployment to production is done via snapshots, aka git tags, so as soon as the feature is merged, the software keeper can tag and deploy the branch to production.
The feature branch can stay around for safety reasons for a few days, but it will usually get deleted after it’s in production.
This git workflow plays very well with unlimited numbers of teams and unlimited numbers of developers and branches and is continuous integration friendly.
In a normal development sprint, all branches will be in sync (develop, QA, master), given that the previous sprint was completed and all features were merged in all branches so they are in sync.
If the branches are not in sync, meaning that the develop branch has more features that are currently developed, this is fine and healthy because during a normal sprint the develop branch should have the most features which are in current development, the QA branch a few that are currently in the quality assurance process, and the master branch only the ones that are completed and code reviewed and ready to go to production.
This workflow has been successfully working for me as a tech lead for 3 years now. I hope you guys will find it as useful as I did and adopt it in your companies / ventures.