Files

65 lines
2.7 KiB
Python

"""Print compact release notes from the preceding stable tag to a tested commit."""
import argparse
import os
import re
import subprocess
import tomllib
def git(*args):
return subprocess.check_output([os.environ.get("GIT_BINARY", "git"), *args], text=True).strip()
def version(tag):
match = re.fullmatch(r"v(\d+)\.(\d+)\.(\d+)", tag)
return tuple(map(int, match.groups())) if match else None
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("tag")
parser.add_argument("ref", help="Exact tested release commit; the new tag need not exist yet")
parser.add_argument("--repo", default="ArchiveBox/ArchiveBox")
args = parser.parse_args()
current = version(args.tag)
if current is None:
parser.error("a stable vMAJOR.MINOR.PATCH tag is required")
previous = max(
(tag for tag in git("tag", "--merged", args.ref).splitlines() if version(tag) and version(tag) < current),
key=version,
)
root = f"https://github.com/{args.repo}"
# Use reviewed, user-facing copy only when this release introduces it.
# Unchanged notes belong to an earlier release and must not be repeated.
notes_path = "docs/Release-Notes.md"
notes_changed = git("diff", "--name-only", f"{previous}..{args.ref}", "--", notes_path)
notes_at_ref = git("ls-tree", "--name-only", args.ref, "--", notes_path)
if notes_changed and notes_at_ref == notes_path:
print(git("show", f"{args.ref}:{notes_path}"))
print(f"\n[Full changelog]({root}/compare/{previous}...{args.tag}) · [0.9 announcement]({root}/releases/tag/v0.9.36)")
return
print(f"## Changes since {previous}\n")
seen = set()
for line in git("log", "--reverse", "--no-merges", "--format=%H%x09%s", f"{previous}..{args.ref}").splitlines():
sha, subject = line.split("\t", 1)
if re.match(
r"(?:Bump release version|Bump for |chore\(release\)|chore\(deps\)|Update .* dependencies|Pin .* release)",
subject,
re.I,
):
continue
if subject not in seen:
print(f"- {subject} ([{sha[:8]}]({root}/commit/{sha})).")
seen.add(subject)
old = tomllib.loads(git("show", f"{previous}:pyproject.toml"))["project"]["dependencies"]
new = tomllib.loads(git("show", f"{args.ref}:pyproject.toml"))["project"]["dependencies"]
updates = [dependency for dependency in new if dependency not in old]
if updates:
print("- ⬆️ Updated dependencies: " + ", ".join(f"`{dependency}`" for dependency in updates) + ".")
print(f"\n[Full changelog]({root}/compare/{previous}...{args.tag}) · [0.9 announcement]({root}/releases/tag/v0.9.36)")
if __name__ == "__main__":
main()