Sam Hooke

Poetry: Automatically generate package version from git commit

When building a Python package that is stored in git, it can be convenient to automatically generate the package version from the git commit and/or tag. That way there is no need to manually “bump” the version number in your Python code. Instead, each commit in git automatically generates a version such as:

1.2.3.dev45+g23b6cfd

And each tag generates a version such as:

1.2.3

Using setup.py build, this could be done using setuptools_scm, but using setup.py in this manner is deprecated.

Instead, we can perform our build using Poetry, and use the poetry-dynamic-versioning plugin to replace setuptools_scm.

Steps §

  1. Run poetry self add "poetry-dynamic-versioning[plugin]" to install the poetry-dynamic-versioning plugin.
  2. Add the following to your pyproject.toml:1
[tool.poetry-dynamic-versioning]
enable = true
vcs = "git"
pattern  = "^(?P<base>\\d+\\.\\d+\\.\\d+)(-?((?P<stage>[a-zA-Z]+)\\.?(?P<revision>\\d+)?))?"
format-jinja = """
    {%- if distance == 0 -%}
        {{- base -}}
    {%- else -%}
        {{- base }}.dev{{ distance }}+g{{commit}}
    {%- endif -%}
"""
  1. Then just run poetry build and check the output:
$ ls dist/
my_package-1.2.3.dev45+g23b6cfd-py3-none-any.whl

Bonus: Python imports §

If you want to have some fun, you can use Python imports within format-jinja if you first specify them within format-jinja-imports.

For example, this:

format-jinja-imports = [
    { module = "pathlib", item = "Path" },
    { module = "platform" },
]

Is equivalent to:

from pathlib import Path
import platform

Then you could, e.g. read the version string from file at /tmp/version_string.txt if building on Linux:

format-jinja = """
    {%- if platform.system() == "Linux" and Path("/tmp/version_string.txt").exists() -%}
        {{ Path("/tmp/version_string.txt").read_text().strip() }}
    {%- else -%}
        {{- base }}.dev{{ distance }}+g{{commit}}
    {%- endif -%}
"""

Using poetry-dynamic-versioning with GitLab §

If using poetry-dynamic-versioning with GitLab, you may find these notes helpful.

These are rough notes that vary greatly in quality and length, but prove useful to me, and hopefully to you too!

← Previous: Poetry: build.py example
Next: Shipping e-bike batteries from the USA to the UK →