6

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

Kim Stacks
  • 10,202
  • 35
  • 151
  • 282

3 Answers3

3

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

aaron
  • 39,695
  • 6
  • 46
  • 102
  • *setuptools_scm mainly generates development and post-release versions.*: You sure about that? If repo is clean and the the current branch HEAD is pointing to is tagged then it will generate version like `0.1.0`. Check [this](https://github.com/pypa/setuptools_scm/issues/528) out! – haccks Oct 03 '22 at 02:07
1

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',
    },
)
a_guest
  • 34,165
  • 12
  • 64
  • 118
0

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.

zurgeg
  • 510
  • 6
  • 18