#!/usr/bin/env python3 """Use VERSION as the single source for frontend release metadata.""" import argparse from pathlib import Path import re VERSION_FILE = Path("VERSION") CHART_FILE = Path("deploy/helm/ai-spel-frontend/Chart.yaml") SEMVER = re.compile(r"^(\d+)\.(\d+)\.(\d+)$") def read_version() -> str: version = VERSION_FILE.read_text().strip() if not SEMVER.fullmatch(version): raise SystemExit(f"Invalid semantic version in {VERSION_FILE}: {version}") return version def update_one(contents: str, pattern: str, replacement: str, description: str) -> str: updated, count = re.subn(pattern, replacement, contents, count=1, flags=re.MULTILINE) if count != 1: raise SystemExit(f"Expected one {description} in {CHART_FILE}, found {count}") return updated def check(version: str) -> str: chart = CHART_FILE.read_text() chart_version = re.findall(r"(?m)^version:\s*(\S+)\s*$", chart) app_version = re.findall(r'(?m)^appVersion:\s*"(\S+)"\s*$', chart) if chart_version != [version] or app_version != [version]: raise SystemExit( f"Version drift: VERSION={version}, chart version={chart_version}, " f"appVersion={app_version}" ) return version def main() -> None: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--check", action="store_true", help="verify metadata without editing") args = parser.parse_args() current = check(read_version()) if args.check: print(current) return major, minor, patch = map(int, current.split(".")) next_version = f"{major}.{minor}.{patch + 1}" chart = CHART_FILE.read_text() chart = update_one( chart, r"(?m)^version:\s*" + re.escape(current) + r"\s*$", f"version: {next_version}", "chart version", ) chart = update_one( chart, r'(?m)^appVersion:\s*"' + re.escape(current) + r'"\s*$', f'appVersion: "{next_version}"', "chart appVersion", ) VERSION_FILE.write_text(f"{next_version}\n") CHART_FILE.write_text(chart) print(next_version) if __name__ == "__main__": main()