-
Notifications
You must be signed in to change notification settings - Fork 55
[META]: Generate package metadata dynamically for PyPI #95
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Spencer Schoenberg (spencrr)
merged 11 commits into
microsoft:main
from
spencrr:dev/spencrr/dynamic-readme-image-permalink-and-version
Jul 16, 2026
Merged
Changes from 7 commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
72ffac7
[META]: Generate README dynamically for functional image permalinks o…
spencrr db83f3e
[META]: Derive package version from Git tags
spencrr 53ed5b8
fixup quotes
spencrr 986fe34
[DOCS]: Land release tag on main so dev versions sort correctly
spencrr 881bcd3
[FIX]: Preserve Markdown image titles when rewriting README image URLs
spencrr 02eff4b
[TEST]: Cover the README metadata build hook
spencrr ebb0dac
[CI]: Run script tests when scripts change
spencrr 5bf8c13
[DOCS]: Clarify release metadata preparation steps
spencrr 2dd8b4c
[META]: Use branch-aware semantic development versions
spencrr 9d1a2e7
[DOCS]: Validate releases before pushing refs
spencrr 88f721d
[DOCS]: Complete the patch release workflow
spencrr File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| name: Scripts | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| paths: | ||
| - "scripts/**" | ||
| - "tests/scripts/**" | ||
| - ".github/workflows/scripts.yml" | ||
| pull_request: | ||
| branches: [main] | ||
| paths: | ||
| - "scripts/**" | ||
| - "tests/scripts/**" | ||
| - ".github/workflows/scripts.yml" | ||
|
|
||
| concurrency: | ||
| group: scripts-${{ github.ref }} | ||
| cancel-in-progress: true | ||
|
|
||
| permissions: {} | ||
|
|
||
| jobs: | ||
| test: | ||
| name: Test scripts | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 10 | ||
| permissions: | ||
| contents: read | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | ||
| with: | ||
| persist-credentials: false | ||
|
|
||
| - name: Set up Python | ||
| uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 | ||
| with: | ||
| python-version: "3.12" | ||
|
|
||
| - name: Set up uv | ||
| uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 | ||
| with: | ||
| enable-cache: true | ||
|
|
||
| - name: Install dependencies | ||
| run: uv sync --all-extras --frozen | ||
|
|
||
| - name: Run script tests | ||
| run: uv run pytest tests/scripts |
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
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| # Copyright (c) Microsoft Corporation. | ||
| # Licensed under the MIT license. | ||
| """Hatchling metadata hooks for RAMPART package builds.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import re | ||
| from pathlib import Path | ||
|
|
||
| from hatchling.metadata.plugin.interface import MetadataHookInterface | ||
|
|
||
| # These patterns only rewrite ``docs/images/`` paths; images stored elsewhere | ||
| # (for example ``assets/``) pass through unchanged and must already use an | ||
| # absolute URL to render on PyPI. | ||
| _GITHUB_IMAGE_URL_PATTERNS = ( | ||
|
nina-msft marked this conversation as resolved.
|
||
| re.compile(r"(https://github\.com/microsoft/RAMPART/raw/)main(/docs/images/)"), | ||
| re.compile( | ||
| r"(https://raw\.githubusercontent\.com/microsoft/RAMPART/)main(/docs/images/)", | ||
| ), | ||
| ) | ||
| _RELATIVE_HTML_IMAGE_URL_PATTERNS = ( | ||
| re.compile(r'(<img\b[^>]*\bsrc=")(?:\./)?(docs/images/[^"]+)(")'), | ||
| re.compile(r"(<img\b[^>]*\bsrc=')(?:\./)?(docs/images/[^']+)(')"), | ||
| ) | ||
| # The URL group stops at whitespace so an optional Markdown title, as in | ||
| # ````, is preserved in group 3 instead of | ||
| # being folded into the rewritten image URL. | ||
| _RELATIVE_MARKDOWN_IMAGE_URL_PATTERN = re.compile( | ||
| r"(!\[[^\]]*\]\()(?:\./)?(docs/images/[^)\s]+)([^)]*\))", | ||
| ) | ||
|
|
||
|
|
||
| def _readme_ref(version: str) -> str: | ||
|
nina-msft marked this conversation as resolved.
|
||
| """Return the Git ref to use for README image URLs.""" | ||
| if ".dev" in version or "+" in version: | ||
| return "main" | ||
|
|
||
| return f"v{version}" | ||
|
|
||
|
|
||
| def _raw_image_url(*, readme_ref: str, image_path: str) -> str: | ||
| """Return an absolute GitHub raw URL for a README image.""" | ||
| return ( | ||
| f"https://raw.githubusercontent.com/microsoft/RAMPART/{readme_ref}/{image_path}" | ||
| ) | ||
|
|
||
|
|
||
| def _render_readme(*, root: Path, version: str) -> str: | ||
| """Return README content rendered for package metadata.""" | ||
| readme = (root / "README.md").read_text(encoding="utf-8") | ||
| readme_ref = _readme_ref(version) | ||
|
|
||
| for pattern in _GITHUB_IMAGE_URL_PATTERNS: | ||
| readme = pattern.sub(rf"\g<1>{readme_ref}\g<2>", readme) | ||
|
|
||
| for pattern in _RELATIVE_HTML_IMAGE_URL_PATTERNS: | ||
| readme = pattern.sub( | ||
| lambda match: ( | ||
| f"{match.group(1)}" | ||
| f"{_raw_image_url(readme_ref=readme_ref, image_path=match.group(2))}" | ||
| f"{match.group(3)}" | ||
| ), | ||
| readme, | ||
| ) | ||
|
|
||
| return _RELATIVE_MARKDOWN_IMAGE_URL_PATTERN.sub( | ||
| lambda match: ( | ||
| f"{match.group(1)}" | ||
| f"{_raw_image_url(readme_ref=readme_ref, image_path=match.group(2))}" | ||
| f"{match.group(3)}" | ||
| ), | ||
| readme, | ||
| ) | ||
|
|
||
|
|
||
| class ReadmeMetadataHook(MetadataHookInterface): | ||
| """Generate PyPI README metadata with release-pinned image URLs.""" | ||
|
|
||
| def update(self, metadata: dict[str, object]) -> None: | ||
| """Update project metadata in-place.""" | ||
| metadata["readme"] = { | ||
| "content-type": "text/markdown", | ||
| "text": _render_readme( | ||
| root=Path(self.root), | ||
| version=str(metadata["version"]), | ||
| ), | ||
| } | ||
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| # Copyright (c) Microsoft Corporation. | ||
| # Licensed under the MIT license. |
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.