How I use Gitflow in real-life projects with GitlabCI

In the article of today, I’m gonna explain the usage of Gitflow in real-life projects. What adaptations I’ve made and how do I use it in my projects. I will also show how I’ve implemented Gitflow in my GitlabCI platform.

Gitflow is a framework to associate your Git repository with your CI/CD pipelines and environments. Gitflow allows to easily separate different stages of the code, from unstable to stable and production.

One branch per environment

In the core Gitlflow definition, there is no information about how to associate a branch to an environment. To have a healthy development environment, we need 3 deployment environments (4 or even 5 are the best).

  • Development environment: where the developers push their work and test the integration. this environment may not be stable;
  • Release environment: where the client or the Product Owner test all the developed features. This must be a stable environment, it’s the version ready to use in production;
  • Production environment: where the end users navigate and the real data is;
  • Pre-production environment (optional): where we test the deployment strategy, from version N-1 to version N. This environment is only used once per deployment cycle. I only use it to validate the rollout procedure, to check that I didn’t forget any database operation or external configuration;
  • Production N-1 environment (optional): where we maintain an old version of the production environment. This environment is only used when a production problem occurs, and I want to check if the problem is old or is due to a recent feature. With the production-1, I have the previously released version, so I can check if the problem is recent or not. If it’s recent, I have to check and correct the newer features. If the problem is also in the N-1 version, it means that’s an old problem and the customers already faced it.

A common strategy now, is to plug each branch to each environment in the CI/CD platform. This way, every time I push something on a branch, I have an automatic deployment in the associated environment. What are the associations:

  • develop to the development environment;
  • release to the release environment;
  • hotfix to the pre-production environment;
  • master to the production environment;
  • master-2 to the production N-1 environment.

How do I configure this in Gitlab CI?

.deploy_template: &deploy_definition
   stage: deploy
   script:
     - # your command goes here

deploy_develop:
<<: *deploy_definition
only:
- develop
variables:
PLATFORM_DESTINATION: "develop"

deploy_release:
<<: *deploy_definition
only:
- release
variables:
PLATFORM_DESTINATION: "release"

deploy_production:
<<: *deploy_definition
only:
- master
variables:
PLATFORM_DESTINATION: "production"

..

What’s on the deploy_definition function? The commands necessary to deploy your application in your platform. Check the following articles about how to deploy to EC2 or ECS.

PR to develop branch

Now that each branch will trigger an automatic deploy, do I need to review all the Pull Request on all the branches?

No.

Here comes the real system management of Gitflow. Each branch has its own significance. And the develop branch is the only one which should be unstable. Here is where come all the new code, all the PR.

I create all the PR to develop. Once validated, the validator merges the feature branch into the develop branch. Then it’s time for the developer to test the feature in a real environment (it’s working on my machine is not a real environment). If the feature isn’t stable, another PR may be necessary. Over and over again until the feature is stable.

Ok, but where do I start my feature branche? From develop.

git switch develop && git pull origin develop
git switch -c feat/my-feature-branch
git push origin feat/my-feature-branch

I do this with all the features of the Agile Sprint. When they are all developed and merged into the develop branch, we start the release rollout.

Now it’s time to present all the features developed to the client or product owner. The client or the product owner will only make their tests on the release environment. He tests in the release environment only once all the features are finished.

To put all the features in the release environment, I need to merge the develop branch into the release branch with this command:

git switch release && git pull origin release
git merge --no-ff origin/develop
git push origin release

This merges the complete develop branch into the release branch and triggers the deployment in the release environment.

What if the client or product owner has some feedback? And I need to do some corrections?

I generally create a fix branch directly from the release branch. Once fixed, I create the PR to the release branch. Once validated and merged, I must merge it back to develop. But that’s an automatic task I’ll explain later.

Let’s see what happens in the next step.

Hotfixes on hotfix branch

The hotfix branch is one of the branches that has the less action. Once validated by the client or product owner, I test my rollout strategy from release to hotfix, make a quick test, and that’s it. My application is ready to go to production.

To merge from release to hotfix, here are the simple commands:

git switch hotfix && git pull origin hotfix
git merge --no-ff origin/release
git push origin hotfix

Nothing new.

But what happens when we discover a bug in production? Which needs a quick fix and don’t wait for the complete Agile Sprint cycle to finish?

I create fix branch from the hotfix branch. Once the fix is done, I create a PR to the hotfix branch. This is the same as done with fixes in the release environment.

Once the fix branch merged on hotfix, I can test the quick fix on the pre-production environment. If it’s all good, I can merge the hotfix branch into the master branch.

These kind of fixes don’t impact the lifecycle of the develop and release branch.

Rollouts and tags on master branch

Everything is working perfectly in the pre-production environment. It’s time to push all this into production.

git switch master && git pull origin master
git merge --no-ff origin/hotfix
git push origin master

This will trigger the deployment in the production environment. I must also repeat any additional step that I’ve found while deploying in the pre-production environment (as some database migrations data or external configurations which are not included in Git).

But when deploying in production, I must also freeze the deployed version. I must use a static name or number, to associate the Agile Sprint or release notes. That’s why I tag my master branch.

git tag v1234
git push origin v1234

Which tag to use? It depends.

It can be the sprint number. It can be an incremental number. It can be the date.

After the production rollout, the development team starts again developing new features on develop. As I’ve started merging from develop to release, then to hotfix, and finally to master, there is no need to merge master again to develop. Master should be a copy of develop.

But one last question remains. What happens with the PR I’ve done directly on release? Or what happens with those made directly on hotfix?

Automatic Merge Back

After I’ve deployed to the production environment, I should merge master to develop. This way, I’m sure develop is a copy of the production code. Only then, the development team can start developing the new features.

For small teams of 1 and 2 developers, this can work. As they are busy deploying the production environment and can’t start developing new features.

But for larger teams, I can’t block 5 developers to wait until the production rollout is finished.

That’s why I’ve included an automatic step in my CI/CD pipeline. Every time a new commit is pushed on release, hotfix or master, the pipeline tries to merge those branches back to ensure all the changes are also included in the develop branch.

This means that any feedback from the client or product owner while testing on the release environment will trigger a merge back step. A new commit came to release, then a new merge is done from release to develop.

What if I have a quick fix to do on hotfix to solve a production bug? Each new commit on hotfix is automatically merged on release. And each new commit on release, triggers a merge to develop.

You can check more about the merge back step in the following article.

Conclusion

As said at the beginning, Gitflow is a framework. It has even some commands to do all those operations. But I haven’t found a single project where this framework matches perfectly.

That’s why I’ve adapted Gitlfow to my real-life projects.

What about the production N-1? It’s easy to figure out that I need to include a merge from master to master-2 just before the production rollout procedure.

git switch master-2 && git pull origin master-2
git merge --no-ff origin/master
git push origin master-2
git switch master && git pull origin master
git merge --no-ff origin/hotfix
git push origin master

I must do it before the production rollout, otherwise the version in master will have the latest version and not the N-1.


Never Miss Another Tech Innovation

Concrete insights and actionable resources delivered straight to your inbox to boost your developer career.

My New ebook, Best Practices To Create A Backend With Spring Boot 3, is available now.

Best practices to create a backend with Spring Boot 3

One response to “How I use Gitflow in real-life projects with GitlabCI”

  1. […] use a Git system like Gitflow as I’ve explained in a previous article. The current article starts with this […]

    Like

Leave a comment

Discover more from The Dev World - Sergio Lema

Subscribe now to keep reading and get access to the full archive.

Continue reading