Skip to content

build: derive version from git tags via hatch-vcs#20

Merged
hallerite merged 2 commits into
mainfrom
feat/hatch-vcs-dynamic-version
May 12, 2026
Merged

build: derive version from git tags via hatch-vcs#20
hallerite merged 2 commits into
mainfrom
feat/hatch-vcs-dynamic-version

Conversation

@hallerite
Copy link
Copy Markdown
Member

Summary

Stop hand-editing `project.version` for every release. hatch-vcs reads the version from the latest `renderers-v*` tag at build time, so:

  • Tagged commits get clean releases: `renderers-v0.1.8` → `0.1.8`
  • Untagged commits get unique PEP 440 dev versions: e.g. `0.1.8.dev3+g4c877be4` so any commit is uniquely installable (useful for downstream end-to-end testing without burning a real release)

Workflow change

before after
1 edit `pyproject.toml` version
2 commit bump
3 tag `renderers-vX.Y.Z` tag `renderers-vX.Y.Z`
4 push tag push tag
5 CI publishes CI publishes

Removes step 1–2 entirely. Version field becomes derived, never edited by hand.

What changes

  • `pyproject.toml`: add `hatch-vcs` to `build-system.requires`, swap `version = "0.1.7"` for `dynamic = ["version"]`, add `[tool.hatch.version]` block with `source = "vcs"` and a `tag_regex` that strips the `renderers-v` prefix
  • `renderers/_version.py`: generated at build time via `[tool.hatch.build.hooks.vcs]`; re-exported as `renderers.version` (with a fallback for editable installs before the first build)
  • `.gitignore`: ignore the generated `_version.py`
  • `publish.yml`: drop the version-mismatch check — pyproject's version is now derived from the same tag the workflow gates on, so the check is trivially-true

Verified locally

```text
$ uv build
Successfully built dist/renderers-0.1.8.dev0+gf7a8a5635.d20260512.tar.gz

$ uv run python -c "import renderers; print(renderers.version)"
0.1.8.dev0+gf7a8a5635.d20260512
```

(The `.d20260512` suffix is setuptools-scm's dirty-tree marker; a clean tagged commit produces just `0.1.8`.)

Full test suite: 939 passed, 49 skipped, 1 xfailed.

Test plan

  • `uv build` produces a PEP 440-valid version from git state
  • `renderers.version` exposes the same version at runtime
  • Full test suite passes
  • Tag a release (e.g. `renderers-v0.1.8`) and confirm `publish.yml` produces a clean `0.1.8` artifact (smoke after merge)

hallerite and others added 2 commits May 12, 2026 17:08
Stop hand-editing ``project.version`` for every release. Hatch-vcs
reads the version from the latest ``renderers-v*`` tag at build time,
so:

- Tagged commits get clean releases: ``renderers-v0.1.8`` → ``0.1.8``.
- Untagged commits get unique PEP 440 dev versions like
  ``0.1.8.dev3+g4c877be4`` so any commit is uniquely installable
  (useful for downstream end-to-end testing without burning a real
  release).

Workflow change:
  before: edit pyproject version → commit → tag → push → publish
  after:  tag → push → publish

Adds:
- ``hatch-vcs`` to build-system requires
- ``dynamic = ["version"]`` + ``[tool.hatch.version] source = "vcs"``
- ``tag_regex`` strips the ``renderers-v`` prefix (publish.yml release contract)
- generates ``renderers/_version.py`` at build time; re-exported as
  ``renderers.__version__``
- ``.gitignore`` entry for the generated file

Drops the now-trivial version-mismatch check in ``publish.yml``
(pyproject's version is derived from the same tag).

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Move ``tag_regex`` from ``raw-options`` (setuptools-scm passthrough)
to the top-level ``tag-pattern`` key — both work, but ``tag-pattern``
is the canonical hatch-vcs option per the project's README. Loosens
the version-capture group to ``.+`` so we can tag pre-releases like
``renderers-v0.2.0rc1`` without re-touching the regex.

Add ``fallback-version = "0.0.0"`` for the (rare) case of building
from a context without VCS metadata, e.g. a downstream sdist consumer
that doesn't ship ``.git``. Real builds resolve from the tag history.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@hallerite hallerite merged commit 187f9d8 into main May 12, 2026
6 checks passed
@hallerite hallerite deleted the feat/hatch-vcs-dynamic-version branch May 12, 2026 17:19
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