-
Notifications
You must be signed in to change notification settings - Fork 203
Expand file tree
/
Copy pathrelease.py
More file actions
76 lines (58 loc) · 1.81 KB
/
Copy pathrelease.py
File metadata and controls
76 lines (58 loc) · 1.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
"""Release helper: bump version in pyproject.toml, tag, build and publish via uv."""
from __future__ import annotations
import re
import shutil
import subprocess
import sys
import tomllib
from pathlib import Path
PYPROJECT = Path("pyproject.toml")
def read_version() -> str:
with PYPROJECT.open("rb") as f:
return tomllib.load(f)["project"]["version"]
def write_version(new: str) -> None:
text = PYPROJECT.read_text()
new_text, n = re.subn(
r'^(version\s*=\s*")[^"]+(")',
rf"\g<1>{new}\g<2>",
text,
count=1,
flags=re.MULTILINE,
)
if n != 1:
sys.exit("could not locate version line in pyproject.toml")
PYPROJECT.write_text(new_text)
def bump_version() -> str:
old = read_version()
parts = old.split(".")
if len(parts) != 3 or not parts[-1].isdigit():
sys.exit(f"non-trivial version {old!r}; bump manually")
suggested = f"{parts[0]}.{parts[1]}.{int(parts[-1]) + 1}"
print(f"Current version: {old}")
ans = input(f"new version [{suggested}]: ").strip()
new = ans or suggested
write_version(new)
return new
def ask(prompt: str) -> bool:
return input(f"{prompt} (Y/n) ").strip().lower() in ("", "y", "yes")
def run(*cmd: str) -> None:
print("$", " ".join(cmd))
subprocess.run(cmd, check=True)
def release() -> None:
v = bump_version()
if not ask("commit and tag?"):
return
run("git", "add", "pyproject.toml")
run("git", "commit", "-m", "new release")
run("git", "tag", v)
if ask("push to remote?"):
run("git", "push")
run("git", "push", "--tags")
if ask("publish to PyPI?"):
dist = Path("dist")
if dist.exists():
shutil.rmtree(dist)
run("uv", "build")
run("uv", "publish")
if __name__ == "__main__":
release()