Skip to content

Derive package version from git tags via hatch-vcs#67

Merged
bdestombe merged 3 commits into
mainfrom
hatch-vcs-dynamic-versioning
Jul 18, 2026
Merged

Derive package version from git tags via hatch-vcs#67
bdestombe merged 3 commits into
mainfrom
hatch-vcs-dynamic-versioning

Conversation

@bdestombe

Copy link
Copy Markdown
Member

Why

The static version = "1.2.0" never changed while main moved, so pip users updating an existing environment silently kept stale code: pip treats a nhflodata @ git+...@main requirement as satisfied when the installed version equals the freshly resolved one — verified empirically that not even pip install -U picks up new commits; only --force-reinstall did. hatch+uv setups were unaffected, but plain pip needs the version to actually increase.

What

  • hatch-vcs (setuptools-scm) derives the version from git tags at build time: a tagged commit builds exactly as its tag, every commit after it as 1.2.1.devN+g<sha> — unique and strictly increasing per commit, so all installers pick up changes without manual bumps.
  • Anchor tag v1.2.0 pushed on the previous main tip (matches the old static version, no downgrade anywhere).
  • fetch-depth: 0 in the two workflows that install the package — a shallow tagless checkout otherwise derives a 0.1.devN fallback version (cosmetic; tests never asserted on it).
  • .git_archival.txt + .gitattributes (export-subst) so GitHub 'Download ZIP' archives of commits reachable from a tag still build correctly.

Verified

Installed from this branch with both pip 25 and uv 0.10: version resolves to 1.2.1.dev1+g096c3e784. With increasing versions, a plain pip install over an existing environment now upgrades when main moves (tested with a real stale-commit scenario).

Release process from now on

Cut a release by tagging: git tag -a v1.3.0 -m ... && git push origin v1.3.0. No version-bump commits needed; the version line in pyproject.toml is gone.

Replace the static version with git-tag-derived versioning (hatch-vcs /
setuptools-scm) so every commit builds with a unique, increasing version
such as 1.2.1.devN+g<sha>. Plain pip and uv installs from git then pick
up new commits even into an existing environment, without manual bumps.

- Anchored by tag v1.2.0 on main (matches the previous static version)
- fetch-depth: 0 in workflows that install the package, so CI derives
  the real version instead of a 0.1.devN shallow-clone fallback
- .git_archival.txt + .gitattributes so GitHub source archives
  (Download ZIP) of any commit reachable from a tag still build
fetch-depth: 0 on this ~360 MB repo downloads every historical blob just
to give hatch-vcs the tag topology; filter: blob:none keeps the version
derivation correct while fetching only checkout-reachable blobs.
Reads the installed distribution metadata (importlib.metadata), so it
reports the same git-tag-derived version hatch-vcs builds into the
package.
@bdestombe
bdestombe merged commit eed0541 into main Jul 18, 2026
1 check passed
@bdestombe
bdestombe deleted the hatch-vcs-dynamic-versioning branch July 18, 2026 11:31
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