'how to use release branch to increment version using setuptools_scm?
I am looking at https://github.com/pypa/setuptools_scm
and I read this part https://github.com/pypa/setuptools_scm#version-number-construction
and i quote
Semantic versioning for projects with release branches. The same as guess-next-dev (incrementing the pre-release or micro segment) if on a release branch: a branch whose name (ignoring namespace) parses as a version that matches the most recent tag up to the minor segment. Otherwise if on a non-release branch, increments the minor segment and sets the micro segment to zero, then appends .devN.
How does this work?
Assuming my setup is at this commit https://github.com/simkimsia/test-setup-py/commit/5ebab14b16b63090ad0554ad8f9a77a28b047323
and the same repo, how do i increment the version by branching?
What i tried on 2022-03-15
I updated some files on main branch.
Then i did the following
python -m pip install --upgrade "pip ~= 21.3"
pip install pip-tools "pip-tools ~= 6.5"
git init .
git add .
git commit -m '♻️ REFACTOR'
git tag -a v0.0.0 -m '🔖 First tag v0.0.0'
pip-compile
pip-sync
pip install -e .
Then i push my changes including the tag
So this commit is https://github.com/simkimsia/test-setup-py/commit/75838db70747fd06cc190218562d0548baa16e9d
When I run python -m demopublicpythonproject the version that appears is correct
The version number that appears here is based on https://github.com/simkimsia/test-setup-py/blob/75838db70747fd06cc190218562d0548baa16e9d/demopublicpythonproject/framework/__init__.py#L14
Then i branch off
git checkout -b v0.0.1
Then i added a pyproject.toml and set to release-branch
# pyproject.toml
[build-system]
requires = ["setuptools>=45", "setuptools_scm[toml]>=6.2"]
version_scheme = "release-branch-semver"
see https://github.com/simkimsia/test-setup-py/blob/v0.0.1/pyproject.toml
Then i run
python -m setuptools_scm
I get
/Users/kimsia/.venv/test-setup-py-py3812/bin/python: No module named setuptools_scm
In any case i run the following
pip-compile
pip-sync
pip install -e .
git commit -m 'Attempt to do branch semver'
then i have this commit as a result https://github.com/simkimsia/test-setup-py/commit/527885531afe37014dc66432a43a402ec0808caa
When I run python -m demopublicpythonproject I get this image
The version appears to follow based on the branch number but i might be wrong because the latest tag is v0.0.0
so i
git checkout -b main
git checkout -b v0.1.0
pip-sync
pip install -e .
python -m demopublicpythonproject
i get a different version number
0.0.1.dev1+g45f5696 but not 0.1.0
Solution 1:[1]
Branches main and v0.1.0 don't have pyproject.toml, so you need to add that file.
version_scheme should be under [tool.setuptools_scm] instead of [build-system]:
# pyproject.toml
[build-system]
requires = ["setuptools>=45", "setuptools_scm[toml]>=6.2"]
[tool.setuptools_scm]
version_scheme = "release-branch-semver"
This will give you 0.1.0.dev1+g45f5696.
You can check the version number locally:
python setup.py --version
Release branches
git checkout -b main git checkout -b v0.1.0
If you're on a release branch (e.g. v0.1, release-0.1), then the patch version is bumped.
If you're on main or a feature branch, then the minor version is bumped.
Tag names and branch names should not be exactly the same.
Release branch names usually only contain up to the minor version:
git checkout -b v0.1
pip-tools + setuptools_scm
Since setup.cfg only has setuptools_scm in setup_requires and not install_requires, pip-compile (without options) does not compile it into requirements.txt and pip-sync will uninstall setuptools-scm, so you have to pip install setuptools_scm after pip-sync.
Alternatively, you can add setup = setuptools_scm to [options.extras_require]:
# setup.cfg
...
[options]
setup_requires = setuptools_scm
...
[options.extras_require]
setup = setuptools_scm
Usage:
pip-compile --extra setup -o setup-requirements.txt
pip-sync setup-requirements.txt
References:
- https://github.com/jazzband/pip-tools/issues/825
- https://github.com/jazzband/pip-tools#workflow-for-layered-requirements
- How to use setup.py and setup.cfg and pip-tools to obtain layered requirements.txt under different environment of a Django project?
Release versions
setuptools_scm mainly generates development and post-release versions.
To generate a release version like 0.1.0, you can pass a callable into use_scm_version:
# content of setup.py
def myversion():
from setuptools_scm.version import SEMVER_MINOR, guess_next_simple_semver, release_branch_semver_version
def my_release_branch_semver_version(version):
v = release_branch_semver_version(version)
if v == version.format_next_version(guess_next_simple_semver, retain=SEMVER_MINOR):
return version.format_next_version(guess_next_simple_semver, fmt="{guessed}", retain=SEMVER_MINOR)
return v
return {
'version_scheme': my_release_branch_semver_version,
'local_scheme': 'no-local-version',
}
setup(use_scm_version=myversion)
Reference: https://github.com/pypa/setuptools_scm#importing-in-setuppy
Solution 2:[2]
You can change the version scheme by setting the corresponding variable in pyproject.toml:
[tool.setuptools_scm]
version_scheme = "release-branch-semver"
Then you can create branches with SemVer names to increment the version number. For example:
$ git tag
v1.0.0
$ git checkout main
Already on 'main'
$ python -m setuptools_scm
1.1.0.dev1+gdaf07ef
$ git checkout -b 1.0.1
Switched to a new branch '1.0.1'
$ python -m setuptools_scm
1.0.1.dev1+gdaf07ef
If you are using setup.py you can configure it in the following way:
setup(
use_scm_version={
'version_scheme': 'release-branch-semver',
},
)
Solution 3:[3]
If I'm reading the docs correctly, this likely means you are supposed to create branches like so (assuming your current version is 0.x):
main (main development branch)
1.0 (release branch for 1.0)
2.0 (development branch for 2.0)
My understanding is this is parsed like so:
The docs say
Semantic versioning for projects with release branches. The same as guess-next-dev (incrementing the pre-release or micro segment) if on a release branch: a branch whose name (ignoring namespace) parses as a version that matches the most recent tag up to the minor segment. Otherwise if on a non-release branch, increments the minor segment and sets the micro segment to zero, then appends .devN.
So my understanding of this is:
You want to make a new version. So you put it on a branch called 2.0. Since the program knows your last version was 2.0.0, your new one will be called 2.0.1.
Basically, it auto-increments the micro version on your version tag.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | a_guest |
| Solution 3 | zurgeg |


