Dynamic versioning based on VCS tags for uv/hatch project
Project description
uv-dynamic-versioning
poetry-dynamic-versioning influenced dynamic versioning tool for uv/hatch, powered by dunamai.
Installation
Update or add build-system
and tool.hatch.version
in your pyproject.toml
to use uv-dynamic-versioning
.
[build-system]
requires = ["hatchling", "uv-dynamic-versioning"]
build-backend = "hatchling.build"
[tool.hatch.version]
source = "uv-dynamic-versioning"
Also remove version
in project
and set dynamic
(dynamic = ["version"]
).
Before
[project]
name = "..."
version = "0.1.0"
After
[project]
name = "..."
dynamic = ["version"]
See Version Source for more details.
Also there is an example project demonstrates how to use uv-dynamic-versioning
.
Version Source
uv-dynamic-versioning
version source allows you to set a version based on VCS.
[tool.hatch.version]
source = "uv-dynamic-versioning"
Configuration
[!NOTE]
- Configuration is almost same to poetry-dynamic-versioning. But
format-jinja
,format-jinja-imports
are not supported.- The following descriptions are excerpts from poetry-dynamic-versioning.
In your pyproject.toml
, you may configure the following options:
-
[tool.uv-dynamic-versioning]
: General options.-
vcs
(string, default:any
): This is the version control system to check for a version. One of:any
,git
,mercurial
,darcs
,bazaar
,subversion
,fossil
,pijul
. -
metadata
(boolean, default: unset): If true, include the commit hash in the version, and also include a dirty flag ifdirty
is true. If unset, metadata will only be included if you are on a commit without a version tag. This is ignored whenformat
orformat-jinja
is used. -
tagged-metadata
(boolean, default: false): If true, include any tagged metadata discovered as the first part of the metadata segment. Has no effect whenmetadata
is set to false. This is ignored whenformat
orformat-jinja
is used. -
dirty
(boolean, default: false): If true, include a dirty flag in the metadata, indicating whether there are any uncommitted changes. Has no effect whenmetadata
is set to false. This is ignored whenformat
orformat-jinja
is used. -
pattern
(string): This is a regular expression which will be used to find a tag representing a version. When this is unset, Dunamai's default pattern is used.There must be a capture group named
base
with the main part of the version. Optionally, it may contain another two groups namedstage
andrevision
for prereleases, and it may contain a group namedtagged_metadata
to be used with thetagged-metadata
option. There may also be a group namedepoch
for the PEP 440 concept.If the
base
group is not included, then this will be interpreted as a named preset from the DunamaiPattern
class. This includes:default
,default-unprefixed
(makes thev
prefix optional).You can check the default for your installed version of Dunamai by running this command:
poetry run python -c "import dunamai; print(dunamai.Pattern.Default.regex())"
Remember that backslashes must be escaped in the TOML file.
# Regular expression: pattern = '(?P<base>\d+\.\d+\.\d+)' # Named preset: pattern = "default-unprefixed"
-
pattern-prefix
(string): This will be inserted after the pattern's start anchor (^
). For example, to match tags likesome-package-v1.2.3
, you can keep the default pattern and set the prefix tosome-package-
. -
format
(string, default: unset): This defines a custom output format for the version. Available substitutions:{base}
{stage}
{revision}
{distance}
{commit}
{dirty}
{tagged_metadata}
{branch}
{branch_escaped}
which omits any non-letter/number characters{timestamp}
of the current commit, which expands to YYYYmmddHHMMSS as UTC
Example:
v{base}+{distance}.{commit}
-
style
(string, default: unset): One of:pep440
,semver
,pvp
. These are preconfigured output formats. If you set both astyle
and aformat
, then the format will be validated against the style's rules. Ifstyle
is unset, the default output format will follow PEP 440, but a customformat
will only be validated ifstyle
is set explicitly. -
latest-tag
(boolean, default: false): If true, then only check the latest tag for a version, rather than looking through all the tags until a suitable one is found to match thepattern
. -
bump
(boolean, default: false): If true, then increment the last part of the versionbase
by 1, unless thestage
is set, in which case increment therevision
by 1 or set it to a default of 2 if there was norevision
. Does nothing when on a commit with a version tag.Example, if there have been 3 commits since the
v1.3.1
tag:- PEP 440 with
bump = false
:1.3.1.post3.dev0+28c1684
- PEP 440 with
bump = true
:1.3.2.dev3+28c1684
- PEP 440 with
-
tag-branch
(string, default: unset): Branch on which to find tags, if different than the current branch. This is only used for Git currently. -
full-commit
(boolean, default: false): If true, get the full commit hash instead of the short form. This is only used for Git and Mercurial. -
strict
(boolean, default: false): If true, then fail instead of falling back to 0.0.0 when there are no tags. -
ignore-untracked
(boolean, default: false): If true, ignore untracked files when determining whether the repository is dirty.
-
Simple example:
[tool.uv-dynamic-versioning]
vcs = "git"
style = "semver"
Environment variables
In addition to the project-specific configuration above, you can apply some global overrides via environment variables.
UV_DYNAMIC_VERSIONING_BYPASS
: Use this to bypass the VCS mechanisms and use a static version instead. The value of the environment variable will be used as the version for the active project and any path/SSH dependencies that also use the plugin. This is mainly for distro package maintainers who need to patch existing releases, without needing access to the original repository.
__version__
Attribute
You may want to set __version__
attribute in your library. There are two ways for that. Using importlib.metadata and using version build hook.
importlib.metadata
[!NOTE] This is very handy, but it's known that
importlib.metadata
is relatively slow. Don't use this method when performance is critical.
# __init__.py
import importlib.metadata
__version__ = importlib.metadata.version(__name__)
This trick may fail if a package is installed in development mode. Setting a fallback for importlib.metadata.PackageNotFoundError
may be a good workaround.
import importlib.metadata
try:
__version__ = importlib.metadata.version(__name__)
except importlib.metadata.PackageNotFoundError:
__version__ = "0.0.0"
Version Build Hook
You can write a version to a file when you run a build by using Hatch's official version build hook.
For example:
[tool.hatch.build.hooks.version]
path = "path/to/_version.py"
template = '''
version = "{version}"
'''
[!NOTE] A version file should not be included in VCS. It's better to ignore it in
.gitignore
..gitignore
path/to/_version.py
Alternatives
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file uv_dynamic_versioning-0.6.0.tar.gz
.
File metadata
- Download URL: uv_dynamic_versioning-0.6.0.tar.gz
- Upload date:
- Size: 30.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
43a2a18cd60fd7c24abe18a3a0573a9501de92f6267c54a6fa71851c01c3aa87
|
|
MD5 |
7cc41630694c7dda3dc0e618db97c976
|
|
BLAKE2b-256 |
fea32a639c01dbcd3b27726366a1ed7508bc797ceee7c5ba9aec41f3ff5b014f
|
Provenance
The following attestation bundles were made for uv_dynamic_versioning-0.6.0.tar.gz
:
Publisher:
publish.yml
on ninoseki/uv-dynamic-versioning
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1
-
Predicate type:
https://docs.pypi.org/attestations/publish/v1
-
Subject name:
uv_dynamic_versioning-0.6.0.tar.gz
-
Subject digest:
43a2a18cd60fd7c24abe18a3a0573a9501de92f6267c54a6fa71851c01c3aa87
- Sigstore transparency entry: 170141457
- Sigstore integration time:
-
Permalink:
ninoseki/uv-dynamic-versioning@97ec46401d3bf5c9c45a18456f7eac6e03a50936
-
Branch / Tag:
refs/tags/v0.6.0
- Owner: https://github.com/ninoseki
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com
-
Runner Environment:
github-hosted
-
Publication workflow:
publish.yml@97ec46401d3bf5c9c45a18456f7eac6e03a50936
-
Trigger Event:
release
-
Statement type:
File details
Details for the file uv_dynamic_versioning-0.6.0-py3-none-any.whl
.
File metadata
- Download URL: uv_dynamic_versioning-0.6.0-py3-none-any.whl
- Upload date:
- Size: 8.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
2671783473e50377ae800fb9253b5651af40d30300e1485ce1db23718b1e3196
|
|
MD5 |
5db99c8aca7f827ed9759d104bee10c1
|
|
BLAKE2b-256 |
fbf9015ec98f688603f18630d2c78101b9251273abf76ae36cccf041eb3fd5ec
|
Provenance
The following attestation bundles were made for uv_dynamic_versioning-0.6.0-py3-none-any.whl
:
Publisher:
publish.yml
on ninoseki/uv-dynamic-versioning
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1
-
Predicate type:
https://docs.pypi.org/attestations/publish/v1
-
Subject name:
uv_dynamic_versioning-0.6.0-py3-none-any.whl
-
Subject digest:
2671783473e50377ae800fb9253b5651af40d30300e1485ce1db23718b1e3196
- Sigstore transparency entry: 170141459
- Sigstore integration time:
-
Permalink:
ninoseki/uv-dynamic-versioning@97ec46401d3bf5c9c45a18456f7eac6e03a50936
-
Branch / Tag:
refs/tags/v0.6.0
- Owner: https://github.com/ninoseki
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com
-
Runner Environment:
github-hosted
-
Publication workflow:
publish.yml@97ec46401d3bf5c9c45a18456f7eac6e03a50936
-
Trigger Event:
release
-
Statement type: