Originally published on Medium.
Developers should focus on solving problems by writing code. They don’t need to be concerned about how, why, or where their solutions are deployed. The ecosystem should take responsibility of the technical complexity.
One of the benefits of this model is that it works quite very well with SemVer² by allowing for patches, release preparation, and feature development.
It also provides a framework for seamless integration with a continuous deployment model.
Before reading this article you should familiarise yourself with the core concepts of SemVer² and determine whether it is applicable.
My opinion is that you should only consider this model if your application can be live in different states. In essence, it means that deployments are controlled by multiple environments.
Stop reading if
- your application has a single “live” state, all clients on the most stable version
- you are bored
Keep reading if
- your application has multiple “live” states, client A on v.1.0.1, client B on v.1.0.12 and client C on v.1.3.1
- you are bored
The flow is simple to understand, but challenging to explain as a single concept. Diving into a practical overview of each stream should hopefully provide more clarity.
develop— latest unstable version
master— latest stable version
tag— snapshot of version
hotfix— temporary branch to fix something on a version
release— temporary branch to prepare a new version
feature— temporary branch to develop a new feature
Master and develop
These two branches are long-lived and should always exist. They each represent a history of the project; in different states.
master branch represents the official release history. Each new release will be merged into
master. This branch is the latest official published state of the project.
develop branch serves as an integration point for features and contains a full history of the project. New
release branches should be created from the
develop branch. These
release branches would be used as a temporary branch to prepare a new version.
Tags are always merged into
master should be merged into
feature should live in its own branch, isolated until it is complete. When a
feature is complete it is merged into
develop, ready to be part of the next
release branch. The
feature branches should never interact with
A new feature is requested and the story reads…
As a user I would like to have a view of the amount of beers in my fridge so that I can manage my bar’s stock.
The developer creates a new
feature branch by branching off of the
git checkout develop git pull origin develop git checkout -b feature-beer-grid
The developer implements the solution in the
feature-beer-grid branch and sends it for testing. By doing a push to origin it can be picked up in pipelines and deployed to the staging environments.
git checkout feature-beer-grid git commit -am "VA-125: Implemented the new beer grid in the backend" git push origin feature-beer-grid
The solution is now tested and the developer gets notified that it failed QA. The developer returns to the
feature-beer-grid branch to resolve the problem. Once the issue has been resolved, the developer commits the changes and pushes the branch to origin for another round of testing.
git checkout feature-beer-grid git commit -am "VA-125: Fixed bug with editing a beer record" git push origin feature-beer-grid
Once the issue passes testing and is ready to become part of the next release phase the developer is responsible for merging the
feature-beer-grid branch into
git checkout develop git pull origin develop git merge --no-ff feature-beer-grid git push origin develop
hotfix branches are reserved for patch production releases. These patches should be done with caution and the responsibility is on the developer and the testing team to ensure that there won’t be a negative impact on the production environments.
This allows the development team to iterate on releases without interrupting the rest of the workflow or waiting for the next release cycle.
An issue is reported to the support team and a bug is logged.
VA-124: Importing beer records from a CSV with semicolon delimiters does not work since version 1.0.0.
The developer assigned to this issue needs to attempt to resolve it in the appropriate minor version. The developer updates his local git repo with the latest tags in order to find the latest tag in the 1.0.X range from which the
hotfix branch should be created.
git fetch origin --tags git tag -ln git checkout 1.0.1 git checkout -b hotfix-1.0.1-VA-124
The developer implements the solution in the
hotfix-1.0.1-VA-124 branch and sends it for testing. By doing a push to origin it will be picked up in pipelines and deployed to the staging environments.
git checkout hotfix-1.0.1-VA-124 git commit -am "VA-124: Found and resolved an issue with the import mechanism. The import mechanism will now dynamically determine the delimiter." git push origin hotfix-1.0.1-VA-124
The issue passes the QA phase and is now ready to go straight into production. It is the developer’s responsibility to create a new
tag for this issue. Creating this
tag will publish the release and deploy it in the production environments. The developer also needs to merge this tag forward into
git checkout hotfix-1.0.1-VA-124 git fetch origin --tags git tag -ln git tag -a 1.0.2 -m "Deployed as 1.0.2"# Update master and develop git checkout master git merge --no-ff 1.1.0 git push origin master git checkout develop git merge --no-ff master git push origin develop
The development team will continuously iterate on the
develop branch until it has acquired enough features for a new release (or a predetermined release date is approaching). A new
release branch is created to allow stabilisation in preparation for the new version.
release branch is created no new features should be introduced and the only changes in the form of bug fixes, minor improvements, documentation and other release-oriented tasks are allowed.
The development team works closely with the support team to iterate on issues in the
release branch and polish it until it is considered to be production ready.
The development team is nearing a release cycle and committed releasing the new version 1.1 soon.
The developer should create a new
release branch from
develop and push it to origin to deploy it into the staging environments.
git checkout develop git pull origin develop git checkout -b release-1.1
The QA team finds an issue in the release and logs it as:
VA-126: Cannot edit a beer record in the new backend beer grid since version 1.1.X
The developer should now create a new branch off of the
release-1.1 branch as
release-1.1-VA-126 to solve the issue.
The support team tests the
release-1.1-VA-126 branch in the staging environment and finally sign it off as flawless.
Now the developer merges the
release-1.1-VA-126 branch back into the original
release-1.1 preparation branch.
git checkout release-1.1 git pull origin release-1.1 git merge --no-ff release-1.1-VA-126
Once the development team has resolved all (or most of) the issues reported in the
release-1.1 range and determines that it is production ready it can be tagged and bagged. The developer also needs to update the
develop branches accordingly, to ensure that they are up to date with the latest changes.
git checkout release-1.1 git tag -a 1.1.0 -m "Deployed as 1.1.0"# Update master and develop git checkout master git merge --no-ff 1.1.0 git push origin master git checkout develop git merge --no-ff master git push origin develop