Skip to main content
Version: v2

GitFlow versioning workflow

This page is for the developer or lead who releases a project built from Vortex. It explains the git-flow branching model and walks you through a release from start to production, so you can run one and check that it worked.

git-flow is a versioning workflow, first described in A successful Git branching model: a branching model that keeps development code and production code apart. Work lands on develop, main holds only production-ready code, and a short-lived branch carries each feature, release, and hotfix. Vortex builds its defaults around these branch names: the CI triggers, the deployment branch patterns, and the release notes workflow all expect them.

The following diagram shows a release from start to deployment:

develop ──► git flow release start X.Y.Z
│
▼
release/X.Y.Z
(final fixes, release notes)
│
▼
git flow release finish X.Y.Z
│
├──► merges into `main` and tags `X.Y.Z`
├──► merges back into `develop`
│
▼
deploy the `X.Y.Z` tag
(or push `main` to `production` for branch-based hosting)

Branch structure​

git-flow uses the following branches:

  • develop - the development branch, where features are integrated
  • main - production-ready code, always stable and tagged with releases
  • feature/* - a branch for each feature in development
  • release/* - release preparation branches (for example, release/25.1.0)
  • hotfix/* - emergency fixes for production (for example, hotfix/25.1.1)
production branch

When your hosting can deploy a specific Git tag, you need no separate production branch: you tag releases on main and deploy those tags.

Some providers, Lagoon among them, deploy only from a Git branch, and the Vortex Lagoon deployment skips tags. On those, you must create a production branch and sync code from main to production after each release.

CI could copy main to production whenever a release is tagged, but Vortex deliberately leaves that step to a person. That way, nothing reaches production without someone deciding it should.

Before you begin​

Make sure you have the following:

  • The git-flow command-line extension, which provides the git flow commands
  • A clone of the project's repository set up with git flow init, with main as the branch for production releases, develop as the development branch, and no version tag prefix, so tags read X.Y.Z
  • Permission to push branches and tags to the project's repository

The git-flow cheat sheet covers how to install the extension, and gives a quick reference on its commands.

Release operations​

In each of the following commands, replace X.Y.Z with the release version in your version scheme. To run a release:

  1. Start the release:

    git flow release start X.Y.Z

    This creates a release/X.Y.Z branch from develop.

  2. Push the release branch to the remote, with git push origin release/X.Y.Z. CI builds and deploys release/* branches, so the release gets its own build and deployment for final testing.

  3. Prepare the release:

    1. Commit the final bug fixes and documentation updates to the release branch.
    2. Review the draft release notes on GitHub (see Release notes publishing).
  4. Finish the release:

    git flow release finish X.Y.Z

    The command makes these changes in your clone:

    • Merges the release branch to main
    • Tags the release
    • Merges back to develop
    • Deletes the local release branch, and leaves the pushed one in place
  5. Push main, develop, and the new tag, with git push origin main develop X.Y.Z. CI builds and deploys the pushed branches and the tag.

  6. Deploy to production:

    • Tag-based hosting: deploy the tag to your production environment directly

    • Branch-based hosting (for example, Lagoon): manually sync main to the production branch:

      git push origin main:production

      The first push creates the production branch on the remote.

Expected release outcome​

Confirm that the release meets these criteria, which also ship in your project's docs/releasing.md:

  • The release branch exists as release/X.Y.Z in the GitHub repository.
  • The release tag exists as X.Y.Z in the GitHub repository.
  • The HEAD of the main branch has the X.Y.Z tag.
  • The hash of the HEAD of the main branch exists in the develop branch, so everything pushed to main also exists in develop. This matters when main had hotfixes not yet merged to develop.
  • GitHub has no open pull requests related to the release.
  • On branch-based hosting, the hash of the HEAD of the production branch matches the hash of the HEAD of the main branch.

What's next​