GitFlow versioning workflow
git-flow is a versioning workflow that allows you to maintain clean separation between development and production code.
It allows you to have a stable development branch (develop) and a production-ready
branch (main), while providing dedicated branches for feature development,
release preparation, and hotfixes.
Branch structure
develop- Development branch where features are integratedmain- Production-ready code, always stable and tagged with releasesfeature/*- Individual feature development branchesrelease/*- Release preparation branches (e.g.,release/25.1.0)hotfix/*- Emergency fixes for production (e.g.,hotfix/25.1.1)
production branch
Most hosting providers support deploying specific git tags directly. In this
case, no separate production branch is needed - you simply tag releases on
main and deploy those tags.
Some hosting providers (like Lagoon) require a git branch to deploy from,
so tag-based deployments are not supported. In this case, you must create a
production branch and sync code from main to production after each
release.
While it's possible to automate copying main to production on tag creation
via CI/CD, this automation was conceptually avoided to prevent accidental
deployments to production without human oversight.
Release operations
Below are the typical steps to perform a release using git-flow. See cheat sheet for a quick reference on git-flow commands.
-
Start Release
git flow release start X.Y.ZCreates a
release/X.Y.Zbranch fromdevelop. It is recommended to push the branch to remote. -
Release Preparation
- Final bug fixes
- Documentation updates
- Release notes preparation
-
Finish Release
git flow release finish X.Y.Z- Merges release branch to
main - Tags the release
- Merges back to
develop - Deletes the release branch
- Merges release branch to
-
Deploy to Production
-
Tag-based hosting: Deploy the tag directly
-
Branch-based hosting (e.g., Lagoon): Manually sync to
productionbranchgit push origin main:production
-
Expected release outcome
A successful release should meet these criteria:
- Release branch exists as
release/X.Y.Zin GitHub repository - Release tag exists as
X.Y.Zin GitHub repository - The
HEADof themainbranch hasX.Y.Ztag - The hash of the
HEADof themainbranch exists in thedevelopbranch- This ensures everything pushed to
mainexists indevelop - Important if
mainhad any hotfixes not yet merged todevelop
- This ensures everything pushed to
- There are no open PRs in GitHub related to the release