#!/usr/bin/env python3 import argparse import time import re from subprocess import run def load_changelog(): with open("CHANGELOG.md") as f: return list(f) def extract_changes(lines): lines = iter(lines) changes = [] # Find "Unreleased" section for line in lines: if line.strip() == "## Unreleased": break next(lines) # Read all lines from that section for line in lines: if line.startswith("## "): # Found the beginning of the next section break elif line.startswith("### "): # Found a heading in the current section # Remove "#" symbols so git doesn't interpret the line as a comment later changes.append(line[4:]) else: changes.append(line) # Remove trailing empty lines while changes and not changes[-1].strip(): changes.pop() return changes def update_version(version): with open("PFERD/version.py") as f: text = f.read() text = re.sub(r'VERSION = ".*"', f'VERSION = "{version}"', text) with open("PFERD/version.py", "w") as f: f.write(text) def update_changelog(lines, version, date): lines = iter(lines) new_lines = [] # Find "Unreleased" section for line in lines: new_lines.append(line) if line.strip() == "## Unreleased": break # Add new heading below that new_lines.append("\n") new_lines.append(f"## {version} - {date}\n") # Add remaining lines for line in lines: new_lines.append(line) with open("CHANGELOG.md", "w") as f: f.write("".join(new_lines)) def commit_changes(version): run(["git", "add", "CHANGELOG.md", "PFERD/version.py"]) run(["git", "commit", "-m", f"Bump version to {version}"]) def create_tag(version, annotation): run(["git", "tag", "-am", annotation, f"v{version}"]) def fastforward_latest(): run(["git", "branch", "-f", "latest", "HEAD"]) def main(): parser = argparse.ArgumentParser() parser.add_argument("version") args = parser.parse_args() version = args.version date = time.strftime("%Y-%m-%d") changelog = load_changelog() changes = extract_changes(changelog) annotation = f"Version {version} - {date}\n\n{''.join(changes)}" update_version(version) update_changelog(changelog, version, date) commit_changes(version) create_tag(version, annotation) fastforward_latest() print() print("Now the only thing left is to publish the changes:") print(f" $ git push origin master latest v{version}") if __name__ == "__main__": main()