105 lines
3.6 KiB
Python
105 lines
3.6 KiB
Python
import re
|
|
import subprocess
|
|
from pathlib import Path
|
|
from datetime import datetime
|
|
import typer
|
|
import os
|
|
|
|
app = typer.Typer()
|
|
|
|
CHANGELOG_FILE = Path("CHANGELOG.md")
|
|
VERSION_FILE = Path("__version__.py")
|
|
VERSION_PATTERN = r"## \[v?(\d+\.\d+\.\d+)\]"
|
|
|
|
def get_latest_version():
|
|
content = CHANGELOG_FILE.read_text(encoding="utf-8")
|
|
matches = re.findall(VERSION_PATTERN, content)
|
|
return matches[0] if matches else "0.0.0"
|
|
|
|
def bump_version(version: str, level: str = "patch") -> str:
|
|
major, minor, patch = map(int, version.split("."))
|
|
if level == "major":
|
|
return f"{major + 1}.0.0"
|
|
elif level == "minor":
|
|
return f"{major}.{minor + 1}.0"
|
|
return f"{major}.{minor}.{patch + 1}"
|
|
|
|
def write_version_file(version: str):
|
|
VERSION_FILE.write_text(f"VERSION = \"{version}\"\n", encoding="utf-8")
|
|
|
|
def update_changelog(version: str):
|
|
date = datetime.now().strftime("%Y-%m-%d")
|
|
new_entry = f"## [{version}] - {date}\n\n- Beschreibung...\n\n"
|
|
content = CHANGELOG_FILE.read_text(encoding="utf-8")
|
|
CHANGELOG_FILE.write_text(new_entry + content, encoding="utf-8")
|
|
|
|
def is_ssh_signing_available() -> bool:
|
|
return Path("~/.ssh/id_ed25519").expanduser().exists()
|
|
|
|
def is_gpg_available() -> bool:
|
|
try:
|
|
output = subprocess.check_output(["gpg", "--list-secret-keys"], stderr=subprocess.DEVNULL)
|
|
return bool(output.strip())
|
|
except Exception:
|
|
return False
|
|
|
|
def configure_signing(use_ssh: bool):
|
|
if use_ssh:
|
|
subprocess.run(["git", "config", "--global", "gpg.format", "ssh"], check=True)
|
|
subprocess.run(["git", "config", "--global", "user.signingkey", "~/.ssh/id_ed25519.pub"], check=True)
|
|
else:
|
|
subprocess.run(["git", "config", "--global", "gpg.format", "openpgp"], check=True)
|
|
subprocess.run(["git", "config", "--global", "commit.gpgsign", "true"], check=True)
|
|
|
|
def create_git_tag(version: str, sign: bool):
|
|
if sign:
|
|
subprocess.run(["git", "tag", "-s", f"v{version}", "-m", f"Release v{version}"], check=True)
|
|
else:
|
|
subprocess.run(["git", "tag", "-a", f"v{version}", "-m", f"Release v{version} (unsigned)"], check=True)
|
|
|
|
def push_git_tag(version: str):
|
|
subprocess.run(["git", "push"], check=True)
|
|
subprocess.run(["git", "push", "origin", f"v{version}"], check=True)
|
|
|
|
@app.command()
|
|
def create(level: str = "patch", push: bool = False, no_sign: bool = False):
|
|
current = get_latest_version()
|
|
new_version = bump_version(current, level)
|
|
write_version_file(new_version)
|
|
update_changelog(new_version)
|
|
subprocess.run(["git", "add", "."], check=True)
|
|
|
|
use_signing = False
|
|
signing_method = "none"
|
|
|
|
if not no_sign:
|
|
if is_ssh_signing_available():
|
|
configure_signing(use_ssh=True)
|
|
use_signing = True
|
|
signing_method = "ssh"
|
|
elif is_gpg_available():
|
|
configure_signing(use_ssh=False)
|
|
use_signing = True
|
|
signing_method = "gpg"
|
|
|
|
commit_cmd = ["git", "commit", "-m", f"Bump version to v{new_version}"]
|
|
if use_signing:
|
|
commit_cmd.append("-S")
|
|
subprocess.run(commit_cmd, check=True)
|
|
|
|
create_git_tag(new_version, sign=use_signing)
|
|
|
|
if push:
|
|
push_git_tag(new_version)
|
|
|
|
if use_signing:
|
|
if signing_method == "ssh":
|
|
typer.secho(f"✅ Version {new_version} erstellt und signiert mit SSH 🔐", fg=typer.colors.GREEN)
|
|
elif signing_method == "gpg":
|
|
typer.secho(f"✅ Version {new_version} erstellt und signiert mit GPG 🔏", fg=typer.colors.CYAN)
|
|
else:
|
|
typer.secho(f"⚠️ Version {new_version} wurde ohne Signatur erstellt", fg=typer.colors.YELLOW)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
app()
|