From 95f07d93a9c95b7733ec6168f0095f1be25b98ee Mon Sep 17 00:00:00 2001 From: Greg Gauthier Date: Sat, 14 Feb 2026 22:39:12 +0000 Subject: [PATCH] add release script --- make-release.py | 113 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100755 make-release.py diff --git a/make-release.py b/make-release.py new file mode 100755 index 0000000..7345269 --- /dev/null +++ b/make-release.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 +""" +Release script for NotePad +Automates version bumping, committing, tagging, and pushing +""" + +import sys +import subprocess +import xml.etree.ElementTree as ET +from pathlib import Path + + +def run_command(cmd, description): + """Run a command and handle errors""" + print(f"\n→ {description}...") + result = subprocess.run(cmd, capture_output=True, text=True) + + if result.returncode != 0: + print(f"❌ ERROR: {description} failed!") + print(f" {result.stderr}") + sys.exit(1) + + if result.stdout.strip(): + print(f" {result.stdout.strip()}") + + return result + + +def update_version_in_csproj(version): + """Update the version in NotePad.csproj""" + csproj_path = Path("NotePad/NotePad.csproj") + + if not csproj_path.exists(): + print(f"❌ ERROR: {csproj_path} not found!") + sys.exit(1) + + print(f"\n→ Updating version to {version} in {csproj_path}...") + + try: + tree = ET.parse(csproj_path) + root = tree.getroot() + + version_elem = root.find(".//Version") + if version_elem is not None: + version_elem.text = version + else: + # Add Version element if it doesn't exist + property_group = root.find(".//PropertyGroup") + if property_group is not None: + version_elem = ET.SubElement(property_group, "Version") + version_elem.text = version + else: + print("❌ ERROR: Could not find PropertyGroup in .csproj") + sys.exit(1) + + tree.write(csproj_path, encoding='utf-8', xml_declaration=True) + print(f" ✅ Version updated to {version}") + + except Exception as e: + print(f"❌ ERROR: Failed to update .csproj: {e}") + sys.exit(1) + + +def main(): + if len(sys.argv) < 2: + print("Usage: python3 make-release.py [tag message]") + print("") + print("Examples:") + print(" python3 make-release.py v0.1.6") + print(" python3 make-release.py v0.1.6 'Added fireworks to launch animations'") + sys.exit(1) + + version_tag = sys.argv[1] + + # Remove 'v' prefix for .csproj version + version_num = version_tag.lstrip('v') + + # Get tag message from remaining arguments + tag_message = ' '.join(sys.argv[2:]) if len(sys.argv) > 2 else f"Release {version_tag}" + + print("=" * 60) + print(f"NotePad Release Script") + print("=" * 60) + print(f"Version: {version_tag}") + print(f"Tag message: {tag_message}") + print("=" * 60) + + # Step 1: Update version in .csproj + update_version_in_csproj(version_num) + + # Step 2: Commit the version update + commit_message = f"Incremented to version {version_tag}" + run_command(["git", "add", "NotePad/NotePad.csproj"], "Staging .csproj") + run_command(["git", "commit", "-m", commit_message], "Committing version update") + + # Step 3: Push to origin master + run_command(["git", "push", "origin", "master"], "Pushing to origin master") + + # Step 4: Create git tag + run_command(["git", "tag", "-a", version_tag, "-m", tag_message], f"Creating tag {version_tag}") + + # Step 5: Push tag to origin + run_command(["git", "push", "origin", version_tag], f"Pushing tag {version_tag}") + + print("\n" + "=" * 60) + print("✅ Release completed successfully!") + print("=" * 60) + print(f"\nThe CI/CD workflow should now build and publish {version_tag}") + print(f"Check your Gitea repository for the release.") + + +if __name__ == "__main__": + main()