Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to setup a right GIT flow for a huge company with many releases

We need to improve our Git flow setup as we face several problems currently in our company.

Our current lifecycle:

  • We code a white-labeled product for multiple companies from one repo
  • 20+ devs code ~30 pull requests (we use Github) every day
  • We push all our code to master branch
  • Each 2nd week we create release/2018-xx from master
  • This release is tested and used by five companies
  • All of them report us bugs the following weeks
  • We merge those bugs into master and cherrypick them into release/xx
  • Whenever each company decides, they put release/xx into production
  • When they deploy we destroy


Problems we face:

1) Even we have a "stable" release in which we put only bugfixes, we still do this for all five companies and sometimes a bugfix of one of them destroys functionality of another (=> creating four release branches and cherrypicking all fixed into all five would be extremely time consuming)

2) We have to cherry pick more than 20 fixes from master into release/2018-xx every single day and fix a lot of conflicts (alternative is to branch a bugfix from the release branch, but we would face conflicts then into master)



Is there any approach how to handle such a heavy flow?

like image 857
Samuel Ondrek Avatar asked Sep 08 '25 02:09

Samuel Ondrek


1 Answers

High Level Considerations

There are a couple dimensions to this problem that need to be considered:

  • The customer's expectations.
  • The stability of the product's feature set.

Given these two things you need to establish:

  • A release cycle.
  • A versioning scheme.
  • A branching strategy.

The main tradeoffs that you're dealing with when choosing a release cycle are and versioning scheme are:

  • Delivering new features to customers quickly at the rate they expect. VS. Releasing features slowly enough so that your head doesn't explode.
  • Providing a stable feature set. VS. Breaking backward compatibility to make significant technical improvements to the product.
  • Supporting a particular version for a Customer for a significant duration of time. VS. Minimizing the number of versions that you have to support.

Let's dive into a versioning scheme first because that is the simplest. After that is defined, we can discuss a complimentary branching strategy, and finally a release cycle that suites your needs.

Versioning Scheme

There is a well defined way of versioning software called semantic versioning. The main idea behind semantic versioning is that a software version is composed of three parts:

  • Major Version
  • Minor Version
  • Patch Version

These three versions are numbers and combined with dots. {Major Version}.{Minor Version}.{Path Version}.

Examples of valid semantic versions are: 1.0.0, 2.1.0, 11.1.133

Major Version

A major version change indicates a backward incompatible change has taken place. Specifically let's say your product is currently version 1.0.0 . And you decide to make a bunch of changes that remove features or change the way existing features work, and you want to release this new version. Since you've made changes that could break existing users of the software you need to increase the major version, so that the new version of the product is 2.0.0 . Similarly if your changes don't break old features then you can keep the same major version when you release the next version of the software.

Minor Version

A minor version change indicates that new features have been added, and that everything is still backward compatible with the previous version. So let's say you have a 1.0.0 product, and you add a new button that does something cool, but everything else works exactly the same. Then the next version of the product should 1.1.0 .

Patch Version

A patch version change indicates that one or more bugs have been fixed. No new features were added and no existing features were changed.

How User's Interpret Versions

These are the possible motivations for users picking a version:

  • A user wants the latest greatest version to start something new: Then the user would pick the released version that has the highest major version, minor version, and patch version.
  • A user wants some new features, but they don't want anything they are currently using in the product to change: Then the user picks the release that has the same major version as the version they are using now, but they look for the highest minor and patch version.
  • A user wants bug fixes and doesn't want to risk doing a major upgrade: In this case users look for releases with the same major and minor versions as what they are currently using, but they pick the release with the highest patch version.

Branching Strategy

There is a pretty common branching strategy that complements semantic versioning. The general idea is that for each unique major and minor version pair you create a release branch. For example if you have the following versions:

  • 1.0.0
  • 1.0.1
  • 1.1.0
  • 1.1.1
  • 1.1.2
  • 1.1.3
  • 1.2.0

You will maintain the following git branches:

  • release-1.0
  • release-1.1
  • release-1.2

Each of these release branches essentially has the code corresponding to the latest patch version:

  • release-1.0: has the code for 1.0.1
  • release-1.1: has the code for 1.1.2
  • release-1.2: has the code for 1.2.0

You also have a master branch which has the latest code under development.

Note: There is no destruction of branches. These branches stick around as you keep on adding bug fixes to them.

Doing A Patch Release

Now that we have our branches, let's say there is a bug in 1.1.2 . You will put the fix into the release-1.1 branch. Increment the version to 1.1.3 in the release-1.1 branch and release 1.1.3 of the product. If users want the latest bug fixes for version 1.1.2, they will have to upgrade to 1.1.3. Note: You do NOT create a new branch in this case.

Doing A Minor Feature Release

Let's say you are working on adding some new features and you are not breaking backward compatibility. Until your features are ready push your commits to your master branch. Once your features are done in the master branch, do the following:

  • Create a branch off of master and call it release-1.3 (remember our last version was 1.2).
  • Do QA on the branch and fix bugs. Commit the fixes to release-1.3 and cherry-pick them to master if still applicable.
  • Once QA is done release version 1.3.0 to customers.

Doing A Major Feature Release

Let's say you are working on big changes that are backward incompatible (remove old features and changing how existing features work). Push your commits to master until you think everything is done.

  • When everything is ready create a new branch off of master called release-2.0.
  • Do QA on the branch and fix bugs. Commit the fixes to release-2.0 and cherry-pick them to master if still applicable.
  • Once QA is done release version 2.0.0 to customers.

Release Cycle

The above is all well and good, but how often do you release features? And how long do you support them for? This depends on your customers.

Some ideas for some normalish release schedules are the following:

  • Patch releases can be done as frequently as needed to fix bugs for customers. Ex. daily.
  • Minor releases can be done every 1 - 4 months
  • Major version releases can be done every 1 - 2 years

How long you support a particular major and minor version pair depends on your customer. Are they a slow moving enterprise which needs support for at least 4 years for a particular version? If so you could slow down your Minor and Major releases to reduce the number of versions you have to maintain.

Are they fast moving startups? If so maybe you only support a particular major and minor version pair for 6 months or a year, and require the users to upgrade to a later version for support.

Conclusion

There are a lot more corner cases and things to consider, but this is a good overview of things to think about. Hope it helps.

like image 172
ilooner Avatar answered Sep 10 '25 00:09

ilooner