Version 1.1.1
This commit is contained in:
117
release.py
117
release.py
@@ -11,6 +11,7 @@ Flow:
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
@@ -44,6 +45,15 @@ def ensure_tools() -> None:
|
||||
raise SystemExit(f"Error: '{tool}' is not available in PATH")
|
||||
|
||||
|
||||
def ensure_git_repo() -> None:
|
||||
try:
|
||||
out = subprocess.check_output(["git", "rev-parse", "--is-inside-work-tree"], text=True).strip()
|
||||
except subprocess.CalledProcessError:
|
||||
raise SystemExit("Error: not a git repository (run from within the repo)")
|
||||
if out.lower() != "true":
|
||||
raise SystemExit("Error: not a git work tree")
|
||||
|
||||
|
||||
def prompt_version() -> str:
|
||||
version = input("Enter version (e.g. 1.2.3): ").strip()
|
||||
if not version:
|
||||
@@ -81,11 +91,64 @@ def ensure_origin(config: Config) -> None:
|
||||
run(["git", "remote", "set-url", "origin", config.target_git_url])
|
||||
|
||||
|
||||
def parse_args(config: Config) -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(
|
||||
description=(
|
||||
"Commit+push to PsalmbordOnlineCE and build+push docker image (version + latest)."
|
||||
)
|
||||
)
|
||||
parser.add_argument(
|
||||
"--version",
|
||||
dest="version",
|
||||
help="Version string used for commit message (Version <version>) and Docker tag",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--yes",
|
||||
action="store_true",
|
||||
help="Skip confirmation prompts",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--dry-run",
|
||||
action="store_true",
|
||||
help="Print what would happen without committing/pushing/building/pushing docker",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--branch",
|
||||
default=config.branch,
|
||||
help=f"Branch to push (default: {config.branch})",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--remote-url",
|
||||
default=config.target_git_url,
|
||||
help=f"Remote URL to set for origin (default: {config.target_git_url})",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--docker-image",
|
||||
default=config.docker_image,
|
||||
help=f"Docker image name (default: {config.docker_image})",
|
||||
)
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def main() -> int:
|
||||
config = Config()
|
||||
args = parse_args(config)
|
||||
|
||||
ensure_tools()
|
||||
version = prompt_version()
|
||||
ensure_git_repo()
|
||||
|
||||
version = (args.version or "").strip() or prompt_version()
|
||||
if not VERSION_RE.match(version):
|
||||
raise SystemExit(
|
||||
"Error: invalid version. Use only letters/numbers and . _ - (max 128 chars)"
|
||||
)
|
||||
|
||||
config = Config(
|
||||
target_git_url=args.remote_url,
|
||||
docker_image=args.docker_image,
|
||||
branch=args.branch,
|
||||
)
|
||||
|
||||
commit_message = f"Version {version}"
|
||||
|
||||
# Branch warning
|
||||
@@ -97,7 +160,9 @@ def main() -> int:
|
||||
print(
|
||||
f"Warning: you are on branch '{current_branch}' (expected '{config.branch}')."
|
||||
)
|
||||
if not prompt_yes_no(f"Continue and push '{config.branch}' anyway?", default_no=True):
|
||||
if not args.yes and not prompt_yes_no(
|
||||
f"Continue and push '{config.branch}' anyway?", default_no=True
|
||||
):
|
||||
return 1
|
||||
|
||||
ensure_origin(config)
|
||||
@@ -105,7 +170,31 @@ def main() -> int:
|
||||
print("\n== Git: status ==")
|
||||
run(["git", "status", "-sb"], check=False)
|
||||
|
||||
if not prompt_yes_no("Proceed with commit+push and docker push?", default_no=True):
|
||||
if args.dry_run:
|
||||
print("\n== Dry run ==")
|
||||
print("Would run:")
|
||||
for c in (
|
||||
["git", "add", "-A"],
|
||||
["git", "commit", "-m", commit_message],
|
||||
["git", "push", "-u", "origin", config.branch],
|
||||
[
|
||||
"docker",
|
||||
"build",
|
||||
"-t",
|
||||
f"{config.docker_image}:{version}",
|
||||
"-t",
|
||||
f"{config.docker_image}:latest",
|
||||
".",
|
||||
],
|
||||
["docker", "push", f"{config.docker_image}:{version}"],
|
||||
["docker", "push", f"{config.docker_image}:latest"],
|
||||
):
|
||||
print(f" - {' '.join(c)}")
|
||||
return 0
|
||||
|
||||
if not args.yes and not prompt_yes_no(
|
||||
"Proceed with commit+push and docker push?", default_no=True
|
||||
):
|
||||
print("Aborted.")
|
||||
return 1
|
||||
|
||||
@@ -119,7 +208,16 @@ def main() -> int:
|
||||
except subprocess.CalledProcessError:
|
||||
print("No changes to commit (or commit failed). Continuing...")
|
||||
|
||||
run(["git", "push", "-u", "origin", config.branch])
|
||||
try:
|
||||
run(["git", "push", "-u", "origin", config.branch])
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(
|
||||
"\nGit push failed. If you're using Gitea over HTTPS, you likely need to authenticate with a Personal Access Token (PAT) instead of your password.\n"
|
||||
"- Ensure you can push: git remote -v\n"
|
||||
"- Configure credentials (Windows): Credential Manager / Git Credential Manager\n"
|
||||
"- Or switch to SSH remote and ensure your key is added on the server\n"
|
||||
)
|
||||
return int(getattr(e, "returncode", 1) or 1)
|
||||
|
||||
print("\n== Docker: build/tag/push ==")
|
||||
print(f"Docker image: {config.docker_image}")
|
||||
@@ -136,8 +234,15 @@ def main() -> int:
|
||||
".",
|
||||
]
|
||||
)
|
||||
run(["docker", "push", f"{config.docker_image}:{version}"])
|
||||
run(["docker", "push", f"{config.docker_image}:latest"])
|
||||
try:
|
||||
run(["docker", "push", f"{config.docker_image}:{version}"])
|
||||
run(["docker", "push", f"{config.docker_image}:latest"])
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(
|
||||
"\nDocker push failed. Make sure you're logged in:\n"
|
||||
" docker login git.alphen.cloud\n"
|
||||
)
|
||||
return int(getattr(e, "returncode", 1) or 1)
|
||||
|
||||
print("\nDone.")
|
||||
print("If docker push failed due to auth, run: docker login git.alphen.cloud")
|
||||
|
||||
Reference in New Issue
Block a user