Search code examples
pythongitsetuptools-scm

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

enter image description here

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

enter image description here

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

  • 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:

    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