Add a dynamic-versioning mode to the bump machinery - #30
Merged
Conversation
Projects that derive their version from git tags (e.g. hatch-vcs) have no version to edit, so the bump machinery now takes the base version from the latest reachable v* tag and releases by tagging alone. The new version is computed by applying bump-rule to a scratch project with uv, so the rules are exactly the static mode's rather than a second implementation.
The dynamic base version came from `git describe --tags --abbrev=0`, which returns the closest tag rather than the highest. A repo carrying moving aliases such as `v1.5` alongside `v1.5.1` bumped from `1.5`, then failed to tag `v1.5.1` because that tag already existed. Sorting with git does not fix it either. Both `git describe` and `git tag --sort=v:refname` rank `v1.6.0rc1` above `v1.6.0`, and neither skips a tag like `vendor-3` that merely starts with `v`. Tags are now parsed with `packaging`, which this file already uses for pre-release detection, so the ordering cannot drift from the rest of the bump logic. Adds unit tests for the ranking rules and integration tests against a real repo, covering pre-release and post-release ordering, epochs, unparseable tags, an untagged repo, and a tag on another branch. Also folds in a few cleanups: - Renames the scratch bump builder so it cannot be confused with `bump_command`, which rewrites the repo's own manifest. - Drops the unused `check` argument on `run` and the dead `name` attribute on `DynamicBackend`. - Rewraps the new prose on semantic line breaks.
Verified the multi-package case against a real uv workspace with two hatch-vcs members. The action itself behaves as documented: it reads the base from the tag, skips the manifest and the lockfile, ignores `workspace-packages`, and tags `HEAD` without landing a commit. What bites is everything around it, so those four traps are written down: - Two release tags on one commit make hatch-vcs build the lower one. A commit carrying `v1.3.0` and `v1.4.0` builds `1.3.0` even though the action just tagged `v1.4.0`. Tagging `HEAD` without a commit makes this easy to reach. - Every member shares one version, so nothing can be released on its own. - `uv build` against a virtual workspace root produces `unknown-0.0.0`, which `release-files: dist/*` would attach to the release. `--all-packages` is the working form. - A member in a subdirectory needs `search_parent_directories`, or hatch-vcs cannot find the repository. Also strips trailing whitespace from the bump workflow's comments.
Dynamic mode tags `HEAD` without landing a commit, so releasing twice with nothing merged in between puts both tags on one commit. hatch-vcs then reads the lower one, and the artefacts come out with the previous version while the GitHub release claims the new one. The check runs immediately before the tag rather than at the start, so a changelog or `pre-commit-command` commit that moves `HEAD` still releases normally. Only a commit that would genuinely build the wrong version is refused. This also rules out repos that publish moving aliases such as `v1`, since an alias on the release commit is what hatch-vcs would build.
Building a virtual workspace root produces junk artefacts whatever the version source is, so the note was not about dynamic versioning. `build-command` is an input to the reusable workflow rather than to this action, so the note was also in the wrong file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a
dynamic-versioninginput to thebump-versionaction and thebump.yamlreusable workflow, for projects whose version is derived from git tags (e.g. hatch-vcs). Those projects have no version to edit, so the release is the tag.In dynamic mode:
v*tag with thevstripped, falling back to0.0.0when there is no such tag.bump-ruleapplied to that base, computed by runninguv version --bumpagainst a scratch project seeded with the base version. This borrows uv's rules rather than reimplementing PEP 440, sopatch,minor,major,stableand the pre-release segments all mean exactly what they mean in static mode, and an unsupported combination fails with uv's own message.workspace-packagesandlockdo not apply.pre-release-bumpandpre-release-baseare ignored anddev-versionstays empty.HEADrather than on an empty commit.update-changelogandpre-commit-commandbehave as they do in static mode.Static mode is untouched: every existing input and output keeps its name, default and meaning. Only
project-type: uvsupports dynamic versioning, and pairing it with a Node project type fails with a clear message.The phases now call
backend.apply_bump, which the manifest-backed backends implement as "run the bump command, then read the version back". This is what lets the dynamic backend compute the version without a file to read.Tests cover the scratch-project command assembly, the bump rules end to end against uv, and the input handling. Verified by hand against throwaway repos in both modes.