Software Development with GitFlow

1. Introduction

A well defined and implemented release management is critical to the success of Development Leads and Managers. The manager/ lead has to ensure that the engineering team is productive and working on stories or problems that provide the most business value. In the meantime, the work that is completed needs to be validated and approved by business for operational use. Therefore, at any given time, a release might be in progress and developers are working on the next stories. This is a pipeline problem and sometimes priorities necessitates changing features which means switching releases. On top of this, it has to be made certain that nothing breaks in production. As the release is moved into UAT stage, there may not be a code that is exactly matching the production version. 

We present in this paper, an approach on how GitFlow can help mitigate issues in development and release pipeline. First, in sections 2, 3, 4, and 5, we level set the versioning and development process so that the proposed GitFlow use cases have the background.

2. Build Versioning

 Software versioning is well understood and there are standard ways of managing it. We are following the standard versioning process as follows:

  • ­Major – New Epic or similar in the scope
  • ­Minor – Each feature addition or  defect fix
  • ­Build – Each major build QA/UAT should increate a number

For example, the version shall look like  Major.Minor.Build that is X.X.X. If version is 1.0.1 , then  Major version  is 1, minor version is 0 and build is 1.

3. Branches and corresponding deployment environment

We propose that you have 3 locked branches for every Git project. They are 

Branch NameLockedApplication
Deployed
Environment
Description
MasterYesProductionCode on this branch matches
production
ReleaseYesQA/UATCode on this branch matches the
User Acceptance Test (UAT) test.
In some organization, this may
be Quality Assurance (QA)
environment as well.
DevelopmentYesDev/QACode on this branch matches
Development and QA. 
Feature
(created per
need from
one of the
locked
branches)
NoDevIn this branch, developer
pushes their work.
Defect 
(created per
need from
one of the
locked
branches)
NoDevIn this branch, defect fixes
will be pushed to this branch.
HotFix
(created per
need from
one of the
locked
branches)
NoDevIn this branch, hotfix will be
worked on and pushed to this
branch. 

Figure 1 captures the above description.

Figure 1: Branches and corresponding application environment

4. CI/CD Process Overview

For the purpose of showing the Git flow cases, we assume following simple CI/CD process

  1. Developer pushes the code in the Git
  2. Jenkins executes the pipeline that may be doing code scanning and unit testing
  3. Code is uploaded to Artifactory (repository)
  4. A Deployment process deploys the artifacts to an application environment

Figure 2 depicts the process. 

Figure 2: A CI/CD Process Flow

5. Deployment and Testing Flow

For our Git flow discussion, we use deployment and testing flow as described in this section. This is a simple framework for deployment and testing. Many organization have fairly complex process that has different levels of controls and approvals. These controls and approvals are in place to meet audit and regulatory requirements.

Following is our flow:

  1. Developer pushes code into a feature or defect or hotfix branch after completing unit testing.
    • Developer is following a Test Driven Development 
    • Code coverage is met as per the definition of done
  2. Developer creates a Pull Request (PR) to merge to Develop Branch and request a colleague for Review in the PR.
    1. Code is reviewed and only then reviewer approves the merge – here reviewer is responsible to ensure that code meets the standard and meets the necessary requirements
    2. Reviewer Tags the release and merges the code
    3. Once merged to Develop Branch, the application is deployed to the Dev Environment
    4. All the testing is executed including manual testing and system testing
    5. Quality Assurance (QA) will also do testing here to ensure the feature developed meets the requirements
  3. Once QA approves that it is ready to move forward, a PR is created for Release branch
    1. The code is tagged and merged to Release branch
    2. the application built from release branch is deployed to User Acceptance Testing (UAT) environment. In some organization, this is their QA environment as well
    3. Business does the business testing to ensure that the feature is what they have requested
    4. Now the release is ready for deployment and shall be scheduled for release – NOTE: here the deployment is byte code move rather than full new build. There are many organization that does a full build for production releases; however, our best practice proposal is to move the UAT byte code as it is throughly testing and proved that the byte code works.
  4. At the scheduled time the application is deployed into production
    1. Create PR to merge into Master branch and merge part as a part of deployment. 
    2. Tag the the merged code 

Figure 3 depicts the deployment and testing flow as described above.

Figure 3: Deployment and Testing Flow

6. Development and Release Cases

In a project where analysis, development, testing, and usage is on going activities for new and additional features onto an operational product. Business users require new features or fixes to current features to work on their day to day business problem. In some cases, a new few feature may be a make or break for the business; other features may be nice to have that improve their efficiency but not urgent. Thus, managing the feature development, defect fixes and urgent production issues are the daily tasks of the development group. The development manager will task a lead to ensure proper release management to reduce risk of introducing codes that have not been fully developed or tested; in other words bugs. 

There are many cases where a company had lost a shirt through a bug in their critical application when they had done new release of application. Therefore, the goal is not to introduce risk through management of code and proper testing. We have boiled down to four major cases for the code management. All the cases that we had come across have been able to map to these four cases.

The goal here is to keep the code as clean as possible. This ensures that there is no additional code introduced when there is a defect or hot fix required. In addition, we want to put as fewer lines of code and least changes in the code to mitigate any adverse effect in the system. One of the best practice in doing HotFix is to change or introduce least amount of code so that the change is surgical. In such case, we can do code analysis and factually prove the level risk that business is taking by accepting the change. Thus, even without doing a lot testing, we can show what is the difference and thus risk involved. This is the reason that we need to keep as much of the code same as possible.

The following are four cases that we describe in detail and how to move along to product without introducing additional risk. 

Case 1 : Feature Development flow

In this case, a developer starts with a new story (requirements) for a feature and starts the development. If the story (requirement) that is a feature requires more than one developer, then they will collaborate to develop the feature. Thus, they will work with a single Feature Branch. A best practice is to analyze how many features can be developed together. If a set of stories can be worked together and shall go into the same release regardless, then they shall be developed together and thus, should work off of the same Feature Branch. The flow is as follows: 

  1. Create a Feature Branch from Develop Branch
    1. Developer(s) work on their features and pushes the tested code to the Feature Branch
  2. A PR is created with a reviewer to Develop Branch
    1. Reviewer reviews and accept the code and approves the merge
  3. The PR is merged into the Develop Branch
    1. Develop Branch Code built and deployed to Dev Environment 
    2. The feature and application is tested and automated tests were preformed
  4. Once the QA approves, a PR is created for Release Branch and Develop Branch is tagged
  5. Once the release is ready, the PR is merged to Release and tagged the Release Branch
    1. The Release Branch code is built and deployed to UAT environment for UAT and acceptance by the business
  6. Once the UAT is complete and approved for the release into production,
    1. A PR is created to merge into Master.
    2. The release is deployed in production.
    3. The PR is merged into master at the same time when application is deployed into production so that the application matches with Master Branch code

Figure 4 captures the flow.

Figure 4: A Feature Development Flow

Case 2 : A Defect in UAT Development flow

  • We found a defect in UAT testing that requires fix
  • There is no new feature added to the Develop Branch

The case is that a Defect is found during UAT testing. The defect must be fix for the release to be deployed in production. At the movement, no new features are checked in to Develop Branch. Thus, the Develop Branch and the Release Branch have the same code base. Therefore, we can branch off from Develop Branch to fix the UAT defect. Since, we are branching from the Develop Branch, the flow will be exactly same as the new feature development flow as in Case 1. However, we should name the new branch as Defect Branch to work on. 

NOTE: Though, you can branch off from Release Branch for defect fix, it is best practice to start from Develop Branch for development as long as that is possible. One of the reason is that if you start from Develop Branch, then you can go through your standard development process including your unit and QA testing. Since, the UAT defect is being fixed from the Develop Branch, until this defect is merged to release, no new features shall be merged into the Develop Branch.

The Defect in UAT Development flow is as follows:

  1. Create a Defect Branch from Develop Branch
    1. Developer(s) work on their defect and pushes the tested code to the Defect Branch
  2. A PR is created with a reviewer to Develop Branch
  3. Reviewer reviews and accept the code and approves the merge
    1. Develop Branch Code built and deployed to Dev Environment 
    2. The defect and application is tested with automated tests
  4. Once the QA approves the defect fixes, a PR is created for Release Branch and the Develop Branch is tagged
  5. The PR is merged to Release Branch and tagged
    1. The Release Branch code is built and deployed to UAT environment for UAT and acceptance by the business
  6. Once the UAT is complete and approved for the release into production,
    1. A PR is created to merge into Master.
    2. The release is deployed in production.
    3. The PR is merged into master at the same time when application is deployed into production so that the application matches with Master Branch code

Figure 5 captures the development flow for UAT defect fix.

Figure 5: An UAT Defect fix Development Flow I

Case 3 : A Defect in UAT Release but there are new features being tested in Develop Branch – Development flow

  • We found a defect in UAT testing that requires fix
  • There are new features in Develop Branch that are being tested that are not scheduled for release

The case is similar to Case 2 that a Defect is found during UAT testing, and it must be fix for the release to be deployed in production. There are new features checked in to Develop Branch and the features are actively being tested. Therefore, we branch the code from Release Branch to fix the UAT defect. 

In this case, you complete development and unit testing off of the Defect Branch and pushes the code into the Defect Branch. When the fixes are ready, create a PR into the Release Branch and select a reviewer. Thus, the fix goes directly into the Release Branch rather than to the Develop. Once, the code is reviewed and merged into the Release Branch, the application needs to be deployed in QA environment for the defect fix. Since, this is already tested in the UAT, the testing focus shall be only for the defect and run the automated tests to ensure all the features are working as before and no new bug is introduce. Once QA approves the fix, then the application is deployed into the UAT for further validation and testing of the application for business sign off. 

Once you merge the code into the Release Branch, you create a PR into the Develop Branch for merging the new code. When a PR is merged into a target branch, there may be conflicts. If there are conflicts during the merge, you need to resolve and fix it as a part of merge. These fixes must go through standard testing process ensure that no features are broken and no new bug is introduced.

The Defect in UAT Development flow is as follows:

  1. Create a Defect Branch from Release Branch
    1. Developer(s) work on their defect and pushes the tested code to the Defect Branch
  2. A PR is created with a reviewer to the Release Branch
  3. Reviewer reviews and accept the code and approves the merge and tag the Release Branch
    1. Release Branch Code built and deployed to Dev/QA Environment 
    2. The defect and application is tested with automated tests
  4. Once the QA approves the defect fixes, a PR is created for Develop Branch and the Develop Branch is tagged. 
  5. The PR is merged to the Develop Branch and tagged
    1. If there are issues while merging, the code needs to be fixed and while merging to the Develop Branch.
    2. The Develop Branch code is built and deployed to Dev/QA environment
  6. Once the UAT is complete and approved for the release into production,
    1. A PR is created to merge into Master.
    2. The release is deployed in production.
    3. The PR is merged into master at the same time when application is deployed into production so that the application matches with Master Branch code

Figure 6 captures the development flow for UAT defect fix.

Figure 6: An UAT Defect fix Development Flow II

Case 4 : Production Defect (HotFix) Development Flow

  • Found a bug in production that require immediate patching
  • New features may or may not be in Develop or Release Branch

A Defect is found in Production that requires to be fixed immediately. This is a patch fix that means that fix shall be very surgical that is the code change is small and localized. If the bug requires big changes, then it should go through a standard development cycle to mitigate risk of putting new bug into the Production. 

In this case where it is a surgical patch, we branch off from Master Branch to create a HotFix branch. You complete development and unit testing off of the HotFix Branch and pushes the code into the Branch. When the fixes are ready, then create a PR into the Develop Branch and select a reviewer. At this point, the develop branch may have newer version of feature so that merge may have conflicts. However, the purpose of this PR is for peer reviewing the code to ensure that someone other than the developer has check the code correctness. Thus, you may merge the code later that is once the fix is in production as you may need to focus on production release.

Once the review is complete, the code is build and deployed in QA/UAT environment for testing. QA shall run automated tests and test the fix to ensure that the fix is correct and no other major features are broken. Once QA approves, business shall validate and approve the changes for production release. 

Once all the validation and approval is complete, the fix should be deployed to production at which time, PR for Master and Release Branch are created. At the time of the deployment, the PR is merged into the Master Branch. The UAT merge should be scheduled to take the fix into UAT for the next Release. 

The HotFix Development flow is as follows:

  1. Create a HotFix Branch from Master Branch
    1. Developer(s) work on their defect and pushes the tested code to the Defect Branch
  2. A PR is created with a reviewer to the Develop Branch
  3. Reviewer reviews and accept the code and approves the merge and tag the Develop Branch – The merge into Develop Branch may happen later
    1. merge may have conflict and may require changes for the merge
  4. The fix is deployed in QA/UAT environment for testing.
  5. Once, the QA approves the defect fixes, a PR is created for Master Branch and the HotFix and Master Branch is tagged. 
    1. UAT is complete and approved for the release into production,
    2. A PR is merged into Master so that the application matches with Master Branch code
    3. The release is deployed in production
  6. The PR is created to Release Branch from HotFix Branch and
  7. Merge to the Release Branch and tagged
    1. If there are issues while merging, the code needs to be fixed and while merging to the Release Branch.
    2. The Release Branch code is built and deployed to UAT environment

Figure 7 captures the HotFix development flow.

Figure 7: A HotFix Development Flow

7. Conclusion

In conclusion, we have boiled code management and issues surrounding product release to four cases. These cases are geared towards keeping the code clean and traceable so that each change is easily verified. GitFlow allows to achieve these cases seamlessly into the development cycles. These flows not only mitigate risk of coding error but also improves the development team’s efficiency and their ability to put verifiable code into production. Therefore, we recommend to use the GitFlow as describe in this paper for all development teams.