For versioning, we use Semantic Versioning (major.minor.patch)
We increment the patch version for bugs/fixes
We increment the minor version for new functionality
We increment the major version for breaking changes (or to communicate to the user “big changes”)
For branching, we follow Trunk-Based Development, with some additions:
the development branch contains the upcoming/next release, while we branch for releases as close to the end of development as possible (usually around/after code freeze)
the release/x.y.z branch contains the code for that specific release
the deploy/xyz branches deploy to specific environments (QA, ACC, and production).
This allows us to patch/hotfix previous releases quickly, while working on riskier changes in isolation for the upcoming/next release.
Workflow for Different Branches
If we’re almost done releasing the v1.0.0 version of ROF, and we have some future changes underway for v1.1.0, here’s how that looks:
development contains changes for the next/future release (v1.1.0), while release/v1.0.0 contains changes for v1.0.0
To test things for the current v1.0.0 release, we branch from release/1.0.0, merge into release/1.0.0, then deploy to acceptance (as the “release branch” environment)
To test things for the upcoming v1.1.0 release, we branch from development, merge into development, then deploy to qa (as the “development branch” environment)
The definition of done (QA testing on a non-development environment) is satisfied by either testing on acceptance (v1.0.0 changes) or qa (v1.1.0 changes).