Skip to content

Commit 8290c3f

Browse files
committed
Update uv_build version automatically
In pypa#1880, the concern was raised that the uv_build upper bound in the docs will go stale. This PR adds a GitHub Actions workflow that automatically updates the version daily with the latest uv(-build) version. I tested this change on my fork, but I unfortunately can't test this in pypa/packaging.python.org itself.
1 parent 4cfc8b9 commit 8290c3f

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

.github/workflows/cron.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,36 @@ name: Cron
55
on:
66
schedule:
77
- cron: "0 6 * * *" # daily at 6am
8+
workflow_dispatch:
89

910
jobs:
1011
test:
1112
if: github.repository_owner == 'pypa' # suppress noise in forks
1213
uses: ./.github/workflows/test.yml
1314

15+
update-uv-build-version:
16+
runs-on: ubuntu-latest
17+
permissions:
18+
contents: write
19+
pull-requests: write
20+
steps:
21+
- uses: actions/checkout@v4
22+
- uses: astral-sh/setup-uv@v5
23+
- name: Update uv_build version
24+
id: update_script
25+
run: uv run scripts/update_uv_build_version.py
26+
- # If there are no changes, no pull request will be created and the action exits silently.
27+
name: Create Pull Request
28+
uses: peter-evans/create-pull-request@v7
29+
with:
30+
token: ${{ secrets.GITHUB_TOKEN }}
31+
commit-message: Update uv_build version to ${{ steps.update_script.outputs.version }}
32+
title: Update uv_build version to ${{ steps.update_script.outputs.version }}
33+
body: |
34+
Automated update of uv_build version bounds for uv ${{ steps.update_script.outputs.version }}.
35+
36+
This PR was created automatically by the cron workflow, ping `@konstin` for problems.
37+
branch: bot/update-uv-build-version
38+
delete-branch: true
39+
1440
...

scripts/update_uv_build_version.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# /// script
2+
# requires-python = ">=3.12"
3+
# dependencies = [
4+
# "httpx>=0.28.1,<0.29",
5+
# "packaging>=25.0",
6+
# ]
7+
# ///
8+
import re
9+
from pathlib import Path
10+
11+
import httpx
12+
from packaging.utils import parse_wheel_filename
13+
from packaging.version import Version
14+
15+
16+
def main():
17+
response = httpx.get(
18+
"https://pypi.org/simple/uv-build/",
19+
headers={"Accept": "application/vnd.pypi.simple.v1+json"},
20+
)
21+
response.raise_for_status()
22+
data = response.json()
23+
current_release = None
24+
for file in data["files"]:
25+
if not file["filename"].endswith(".whl"):
26+
continue
27+
_name, version, _build, _tags = parse_wheel_filename(file["filename"])
28+
if version.is_prerelease:
29+
continue
30+
if current_release is None or version > current_release:
31+
current_release = version
32+
33+
[major, minor, _patch] = current_release.release
34+
if major != 0:
35+
raise NotImplementedError("The script needs to be updated for uv 1.x")
36+
upper_bound = Version(f"{major}.{minor + 1}.{0}")
37+
38+
repository_root = Path(__file__).parent.parent
39+
existing = repository_root.joinpath("source/shared/build-backend-tabs.rst").read_text()
40+
replacement = f'requires = ["uv_build >= {current_release}, <{upper_bound}"]'
41+
searcher = re.compile(re.escape('requires = ["uv_build') + ".*" + re.escape('"]'))
42+
if not searcher.search(existing):
43+
raise RuntimeError("Could not `uv-build` entry")
44+
updated = searcher.sub(replacement, existing)
45+
46+
if existing != updated:
47+
print("Updating source/shared/build-backend-tabs.rst")
48+
Path("source/shared/build-backend-tabs.rst").write_text(updated)
49+
print(f"::set-output name=version::{current_release}")
50+
print(f"::set-output name=updated::true")
51+
else:
52+
print("Already up-to-date source/shared/build-backend-tabs.rst")
53+
print(f"::set-output name=updated::false")
54+
55+
if __name__ == '__main__':
56+
main()

0 commit comments

Comments
 (0)