[META]: Generate package metadata dynamically for PyPI#95
Conversation
| "evaluators/prompts/*.yaml", | ||
| ] | ||
| [tool.hatch.version] | ||
| source = "vcs" |
There was a problem hiding this comment.
AI find
Deriving the version from VCS assumes a release tag is reachable from the branch being built. Our release process puts vX.Y.Z on a releases/vX.Y branch and doesn't merge it to main, so that assumption doesn't hold here:
git merge-base --is-ancestor v0.1.0 origin/main→ fails (tag isn't an ancestor of main)git describe --tags HEAD→ "No tags can describe HEAD"uv build --wheel→rampart-0.1.dev75, andgit rev-list --count HEADis also75→ counting from repo root, no tag foundpackaging.Version("0.1.dev75") < Version("0.1.0")→True
So main builds sort before the shipped 0.1.0, and stay in 0.1.devN even after future releases. Note fallback_version won't help — it only applies when there's no .git at all (e.g. building from an sdist); a main checkout has git metadata but no reachable tag, so setuptools-scm uses its no-tag counting instead.
Fix: make release tags reachable from main — either tag a commit that's on main, or add a release step that merges the tagged release commit back into main (a real merge, not cherry-pick). I tested this: with the tag reachable, git describe → v0.1.0-35-g… and the build produces 0.1.1.dev35, which correctly sorts after 0.1.0. Please confirm the intended flow lands the tag on main before this merges.
|
|
||
| The `no-local-version` setting omits local version suffixes such as `+g<sha>` because PyPI does not support them for upstream releases. See the [setuptools-scm local scheme documentation](https://setuptools-scm.readthedocs.io/en/latest/extending/#setuptools_scmlocal_scheme) for details. | ||
|
|
||
| For development builds on `main`, the release tag must be reachable from `main` history for Hatch VCS to infer the next development version from that tag. If the release branch contains commits beyond `main`, merge or cherry-pick those release commits back to `main` after publishing. |
There was a problem hiding this comment.
AI find
"merge or cherry-pick those release commits back to main" — cherry-pick creates new commits with new SHAs, so the tagged commit stays unreachable and git describe still won't find it. Only merging the tagged commit (or tagging something already on main) satisfies setuptools-scm. This is the same root cause as the version blocker above.
Also, this guidance sits in §4 (before the tag is even created in §5), and neither §5 nor §6 adds a step that brings the tag onto main — which is why v0.1.0 isn't on main today. Please add an explicit "merge the release tag into main" step and drop the cherry-pick wording.
| ) | ||
|
|
||
|
|
||
| def _readme_ref(version: str) -> str: |
There was a problem hiding this comment.
Consider adding unit tests for these:
_readme_ref, _raw_image_url, and _render_readme are pure and deterministic but untested, and a regex regression (an image silently not rewritten, or a mangled README) would ship without a signal. They're trivially importable — worth a small tests/ module covering: dev version → main ref; release version → vX.Y.Z ref; HTML src="docs/images/…" and ./docs/images/…; markdown ; the already-absolute main URL patterns; and no-image passthrough.
|
|
||
| from hatchling.metadata.plugin.interface import MetadataHookInterface | ||
|
|
||
| _GITHUB_IMAGE_URL_PATTERNS = ( |
There was a problem hiding this comment.
nit:
Only docs/images/… paths are rewritten, so a relative image elsewhere (e.g. assets/…) would pass through and 404 on PyPI. The markdown pattern (docs/images/[^)]+) would also pull an optional title into the URL for . Neither bites the current README — just flagging in case image usage grows. A one-line comment pinning the docs/images/ assumption would be enough.
nina-msft
left a comment
There was a problem hiding this comment.
Overall, this deviates from our alignment with PyRIT's release process. Do we think if it is sucessful with RAMPART we will also update PyRIT's process to automate these parts?
Description
Move RAMPART package metadata generation to Hatchling so release artifacts can produce PyPI-safe metadata without requiring manual README or version edits.
Dynamic README metadata
The source
README.mdnow keeps repository image links relative, while package builds generate PyPI README metadata with raw GitHub image URLs. This keeps the README readable in GitHub and makes images render reliably on PyPI. The build-time README generation uses Hatch’s dynamic metadata hook pattern (Hatch dynamic metadata, custom metadata hooks).Dynamic version metadata
Package versions are now derived from Git tags through Hatch VCS instead of a static
project.versionfield. Release builds get their version from tags likevX.Y.Z; development builds after a tag infer a development version. Local version suffixes such as+g<sha>are omitted for public-package compatibility vialocal_scheme = "no-local-version"(hatch-vcs version source, setuptools-scm local schemes).The release process docs were updated to describe tag-derived versions, relative README image links, and the requirement that release tags be reachable from
mainhistory for expected development-version inference.Package data inclusion
The setuptools-specific prompt inclusion configuration was removed as part of the Hatchling migration:
Hatchling does not use
tool.setuptools.package-data. Instead, it uses Hatch’s file-selection model. With:the wheel target explicitly selects the
rampart/package directory. Hatch documentspackagesas semantically equivalent toonly-include, with package paths rewritten as needed. Selected directories are traversed by default, subject to normal VCS ignore andexcludebehavior.I verified the built wheel directly and confirmed the prompt YAML files are still present:
This preserves the previous package data behavior while removing configuration that only applied to the old setuptools backend. References: Hatch file selection, Hatch
packages, and wheel default file selection.Breaking changes
None. This changes package build metadata generation only; runtime APIs and package contents are unchanged.
Checklist
pre-commit run --all-filespassesVerification
uv lock --check: passesuv run ruff check scripts/hatch_build.py: passesuv run --with build python -m build: passesuv run pytest tests/unit -q: 489 passed+g<sha>suffix, instead.dev{commits_since_tag}