Skip to content

Commit 29d09f4

Browse files
committed
refactor: make the release script create GitHub releases
1 parent 3ea7686 commit 29d09f4

2 files changed

Lines changed: 31 additions & 29 deletions

File tree

changelog.d/+626d22d0.changed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Make `scripts/release.py` create GitHub releases.

template/scripts/release.py.jinja

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,14 @@
1010
{%- endif %}
1111
# ]
1212
# ///
13-
"""Make a release."""
13+
"""Create a release."""
1414

1515
# ruff: noqa: T201
1616

1717
from __future__ import annotations
1818

1919
import argparse
2020
{%- if not dynamic_version %}
21-
import enum
2221
import json
2322
{%- endif %}
2423
import subprocess
@@ -40,21 +39,7 @@ run = partial(
4039
stderr=subprocess.DEVNULL,
4140
)
4241

43-
{% if not dynamic_version %}
44-
class Bump(enum.StrEnum):
45-
"""The enumeration of supported version bump semantics."""
46-
47-
MAJOR = enum.auto()
48-
MINOR = enum.auto()
49-
PATCH = enum.auto()
50-
STABLE = enum.auto()
51-
ALPHA = enum.auto()
52-
BETA = enum.auto()
53-
RC = enum.auto()
54-
POST = enum.auto()
55-
DEV = enum.auto()
5642

57-
{% endif %}
5843
def create_parser() -> argparse.ArgumentParser:
5944
"""Create the argument parser."""
6045
parser = argparse.ArgumentParser(description="make a release")
@@ -72,8 +57,6 @@ def create_parser() -> argparse.ArgumentParser:
7257
)
7358
mutex.add_argument(
7459
"--bump",
75-
type=Bump,
76-
choices=Bump,
7760
help="update the version using the given semantics",
7861
)
7962
{%- endif %}
@@ -156,10 +139,22 @@ def switch_to_branch(branch: str) -> Generator[None]:
156139
print(f"Removed branch {branch!r} and switched back to {base_branch!r}.")
157140

158141

159-
def build_changelog(version: str) -> None:
160-
"""Build the changelog."""
142+
def get_release_notes(version: str) -> str:
143+
"""Return the release notes."""
144+
release_notes = subprocess.check_output(
145+
("towncrier", "build", "--version", version, "--draft"),
146+
stderr=subprocess.DEVNULL,
147+
text=True,
148+
).rstrip()
149+
release_notes = "".join(release_notes.splitlines(keepends=True)[1:])
150+
release_notes = release_notes.strip()
151+
return f"## Release notes\n\n{release_notes}"
152+
153+
154+
def update_changelog(version: str) -> None:
155+
"""Update the changelog."""
161156
try:
162-
run(("towncrier", "build", "--yes", "--version", version))
157+
run(("towncrier", "build", "--version", version, "--yes"))
163158

164159
except subprocess.CalledProcessError:
165160
print_err("An error occurred while building the changelog.")
@@ -182,14 +177,13 @@ def create_release_tag(version: str) -> str:
182177
return release_tag
183178

184179

185-
def push_changes(branch: str, remote_branch: str = "main") -> None:
186-
"""Push the changes to the origin remote."""
187-
run(("git", "push", "origin", f"{branch}:{remote_branch}", "--follow-tags"))
188-
print(f"Pushed changes from {branch!r} to 'origin/{remote_branch}'.")
180+
def create_release(release_tag: str, release_notes: str) -> None:
181+
"""Create the GitHub release."""
182+
run(("gh", "release", "create", release_tag, "--notes", release_notes))
189183

190184

191185
def main(argv: Sequence[str] | None = None) -> int:
192-
"""Prepare a new release."""
186+
"""Create a release."""
193187
parser = create_parser()
194188
args = parser.parse_args(argv)
195189

@@ -202,13 +196,14 @@ def main(argv: Sequence[str] | None = None) -> int:
202196
release_branch = f"release/{version}"
203197

204198
with switch_to_branch(release_branch):
205-
build_changelog(version)
199+
release_notes = get_release_notes(version)
200+
update_changelog(version)
206201

207202
# Commit changes.
208203
{%- if not dynamic_version %}
209204
run(("git", "add", ":/pyproject.toml", ":/uv.lock"))
210205
{%- endif %}
211-
run(("git", "add", "-A", ":/changelog.d/*", ":/CHANGELOG.md"))
206+
run(("git", "add", "-A", ":/changelog.d", ":/CHANGELOG.md"))
212207
message = f"chore: prepare release {version}"
213208
run(("git", "commit", "--no-verify", "-m", message))
214209
print(f"Committed changes on branch {release_branch!r}.")
@@ -222,7 +217,13 @@ def main(argv: Sequence[str] | None = None) -> int:
222217
print(f"Removed release tag {release_tag!r}.")
223218
return 0
224219

225-
push_changes(release_branch, "main")
220+
run(
221+
("git", "push", "--atomic", "origin", f"{release_branch}:main", release_tag)
222+
)
223+
print(f"Pushed changes from branch {release_branch!r} to branch 'origin/main'.")
224+
print(f"Pushed release tag {release_tag!r} to the origin remote.")
225+
226+
create_release(release_tag, release_notes)
226227

227228
# Switch to the main branch.
228229
run(("git", "checkout", "main"))

0 commit comments

Comments
 (0)