I have been using Github for over 8 years and I finally figured out how to implement semantic versioning in a way that works for me.
In case you are unfamilar, semantic versioning is using
x.y.zas the release number.
xis a major release (non API compatible).
yis a new feature release (API backwards compatible).
zis a patch (for bug fixing).
This is how my Github workflow is:
- Manage changes in a
- Use main for the next feature release
- Create a branch for each feature release (e.g. v4.0.x)
- Create a tag for each patch release (e.g. v4.0.1)
- Minimize changes to bug fixing commits
git cherry-pickto apply bug fixes from main to feature branches
This approach allows users of the code to access stable releases without and without bug fixes. They also have the option to pull in new features without breaking their build.
My release branches look like this:
If you don’t have a stable release yet, you will say so in the
# Pre-Release This project is currently in a pre-release status. The API is subject to change.
Once you get a stable release, your
CHANGES.md file will look something like:
# Version v1.0 Initial stable release.
When you get to this point, you will create a branch in your repository called
v1.0 (or similar). You will also tag the new
v1.0 branch as
main branch changes
main branch is now the pre-release
v1.1 branch. So it will have feature updates and bug fixes. You will add them to your
Changes.md file at the top.
# Version v1.1.0 ## New Features - Description of new feature ## Bug Fixes - Description of bug fix # Version v1.0.0 Initial stable release.
v1.0 branch changes
CHANGES.md file will never get synced up with the
main branch. It will look like this:
# Version v1.0.1 ## Bug Fixes - Description of bug fix # Version v1.0.0 Initial stable release.
Once you are ready to release
v1.0.1, tag the branch using Github and create a new section at the top for
On the left is
CHANGES.md in the
v4.0 branch of Stratify OS while the right is the same file in the
main branch. These two files are always maintained separately. The
v4.0 branch is updated with patches (
v4.0.2, etc) so the changes only include bug fixes.
Bug Fixing Commits
Any commits that are dedicated to bug fixing need to have minimal changes. This will make it easier to merge the changes to other feature release branches. If a bug fix is too extensive and won’t easily merge, you should consider omitting it from previous releases.
When you commit bug fixes, you need to:
- Not make any feature changes or modification to
CHANGES.mdwithin the same commit
- Note that the commit needs to be cherry-picked. I usually add this to the commit message so I can see on Github which commits need to be applied retroactively.
Here is an example from Stratify OS. I made a commit to the
main branch that was a simple bug fix. In the Github commits, I can see that it needs to be applied to v4.0.
I can then use
git cherry-pick to apply the change:
git clone https://github.com/StratifyLabs/StratifyOS git checkout v4.0 git cherry-pick 1cb40bb86321773185ee23a067d96f5ea59e850b
Then I updated the
# Version 4.0.2 ## Bug Fixes - Emit a fatal event if system memory is too small (1cb40bb86321773185ee23a067d96f5ea59e850b) ...
I also like to note the git commit hash in the
CHANGES.md file so that it is easy to go and review the code if needed. Once
CHANGES.md is updated, I commit and push (using either git or Github desktop).
Using the Code
Now that the code has a nice release workflow, it is easy for anyone to use the code in their projects.
If I want to create a project using Stratify OS
v4.0.x. I use:
git clone --branch=v4.0 https://github.com/StratifyLabs/StratifyOS
Then whenever I do
git pull, it will apply patches that won’t break my code. When version
v4.1.0 is release, I can switch to that branch.
git checkout v4.1
If I just want to stick to a single patch release:
git clone --depth=1 --branch=v4.0.1 https://github.com/StratifyLabs/StratifyOS
--depth=1is optional and pulls just the tag rather than the repo history.
It only took me nine years to settle on an approach that works for me. Hopefully with this information, you can find a workflow that works for you.