#!/usr/bin/env python3 """Bump recipe version and create an annotated git tag. Reads the current version from compose.yml, bumps it, updates the version label, commits, and creates an annotated tag. Usage: python3 scripts/new_tag.py --recipe hedgedoc --bump patch python3 scripts/new_tag.py --recipe hedgedoc --bump minor --upstream 2.0.0 """ import argparse import os import subprocess import sys sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from lib.recipe import ( RecipeVersion, read_compose_version, write_compose_version, recipe_dir, has_local_changes, ) from lib.log import SkillLogger def main(): parser = argparse.ArgumentParser( description="Bump recipe version and create git tag" ) parser.add_argument("--recipe", required=True, help="Recipe name") parser.add_argument("--bump", required=True, choices=["patch", "minor", "major"], help="Version bump level") parser.add_argument("--upstream", default=None, help="New upstream version (default: keep current)") parser.add_argument("--dry-run", action="store_true", help="Show what would happen without making changes") args = parser.parse_args() log = SkillLogger("new-tag", args.recipe) rdir = recipe_dir(args.recipe) if not rdir.exists(): log.error(f"Recipe directory not found: {rdir}") log.save() sys.exit(1) # Read current version current = read_compose_version(args.recipe) if current is None: log.error("Could not read version from compose.yml") log.save() sys.exit(1) log.info(f"Current version: {current}") # Compute new version new = current.bump(args.bump) if args.upstream: new = new.with_upstream(args.upstream) log.info(f"New version: {new}") if args.dry_run: print(f"DRY RUN: Would bump {current} -> {new}") return # Check for existing uncommitted changes if has_local_changes(args.recipe): log.step("Stage existing changes") subprocess.run(["git", "-C", str(rdir), "add", "-A"], check=True, timeout=10) # Update compose.yml log.step("Update compose.yml") write_compose_version(args.recipe, new) log.info(f"Updated version label to {new}") # Commit and tag log.step("Commit and tag") subprocess.run( ["git", "-C", str(rdir), "add", "compose.yml"], check=True, timeout=10, ) subprocess.run( ["git", "-C", str(rdir), "commit", "-m", f"chore: upgrade to {new}"], check=True, timeout=10, ) subprocess.run( ["git", "-C", str(rdir), "tag", "-a", str(new), "-m", f"chore: publish {new} release"], check=True, timeout=10, ) log.info(f"Committed and tagged as {new}") log.info(f"Push when ready: cd {rdir} && git push && git push --tags") log.save() print(f"\nTagged: {new}", flush=True) print(f"Push: cd {rdir} && git push && git push --tags", flush=True) if __name__ == "__main__": main()