Skip to content

chore: switch to hatch-vcs for tag-driven dynamic versioning#98

Merged
Faerkeren merged 1 commit into
mainfrom
chore/dynamic-versioning
May 27, 2026
Merged

chore: switch to hatch-vcs for tag-driven dynamic versioning#98
Faerkeren merged 1 commit into
mainfrom
chore/dynamic-versioning

Conversation

@Faerkeren
Copy link
Copy Markdown
Contributor

Summary

Replaces the hand-maintained [project].version in pyproject.toml with hatch-vcs so the package version is derived solely from git tags (v*).

Releases are now cut by tagging vX.Y.Z; untagged commits produce PEP 440 dev versions (e.g. 1.1.3.devN+g<sha>).

Changes

  • pyproject.toml
    • requires = ["hatchling", "hatch-vcs"]
    • dynamic = ["version"] (replaces version = "1.1.2")
    • [tool.hatch.version] source = "vcs"
    • [tool.hatch.build.hooks.vcs] version-file = "src/haclient/_version.py"
    • Exclude generated _version.py from ruff & mypy.
  • src/haclient/__init__.py — prefer from haclient._version import __version__ (build-time); fall back to importlib.metadata, then 0.0.0+unknown.
  • .gitignore — ignore generated src/haclient/_version.py.
  • CI workflows (python-ci, python-tests, python-lint, python-typecheck, python-release) — fetch-depth: 0 so hatch-vcs can read tags.
  • tests/test_packaging.py — replace static-equality assertion with invariants for dynamic versioning.

How releases work now

  1. git tag v1.1.3 && git push --tags
  2. CI build/release on the tag → wheel + _version.py carry exactly 1.1.3.
  3. Commits on main between tags → 1.1.3.devN+g<sha>.

Verification

  • ruff check, ruff format --check, mypy src — clean.
  • pytest --cov-fail-under=95329 passed, coverage 97.19%.
  • python -m build produced haclient-1.1.3.dev48+g40a987fca.d20260527.{tar.gz,whl} (derived from v1.1.2 + 48 commits + dirty).

Replace the hand-maintained '[project].version' in pyproject.toml with
hatch-vcs so the package version is derived solely from git tags (v*).

- pyproject.toml: declare 'dynamic = ["version"]', add hatch-vcs as a
  build requirement, configure '[tool.hatch.version]' with source = vcs,
  and emit 'src/haclient/_version.py' via the vcs build hook.
- haclient/__init__.py: prefer the generated '_version.py'; fall back to
  importlib.metadata, then '0.0.0+unknown' for source checkouts.
- .gitignore: ignore the generated 'src/haclient/_version.py'.
- CI workflows: set 'fetch-depth: 0' on checkout so hatch-vcs can read
  tags during install/build (lint, typecheck, tests, build, release).
- ruff/mypy: exclude the generated _version.py from formatting/typecheck.
- tests/test_packaging.py: replace the static-equality assertion with
  invariants for dynamic versioning (no literal release version in
  __init__.py, 'dynamic' declared in pyproject.toml, metadata present).

Releases are now cut by tagging 'vX.Y.Z'; untagged commits produce PEP
440 dev versions (e.g. 1.1.3.devN+g<sha>).
@Faerkeren Faerkeren merged commit c3eb86e into main May 27, 2026
12 checks passed
@Faerkeren Faerkeren deleted the chore/dynamic-versioning branch May 27, 2026 14:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant