diff --git a/build.py b/build.py index 45c3c78..45ef504 100644 --- a/build.py +++ b/build.py @@ -8,11 +8,16 @@ Usage: python build.py --clean # clean build artifacts first """ +import base64 +import json import os import re import sys import shutil import platform +import subprocess +import urllib.error +import urllib.request # Add project root PROJECT_DIR = os.path.dirname(os.path.abspath(__file__)) @@ -164,6 +169,84 @@ def build(): # Auto-deploy: sync shared files so Claude Code always has the latest deploy_shared_files() + # Publish release to Gitea + publish_gitea_release(dst) + + +def _get_gitea_auth() -> dict: + """Get Gitea auth headers from git remote 'sensey'.""" + try: + _flags = subprocess.CREATE_NO_WINDOW if sys.platform == "win32" else 0 + r = subprocess.run( + ["git", "remote", "get-url", "sensey"], + capture_output=True, text=True, cwd=PROJECT_DIR, creationflags=_flags, + ) + m = re.match(r"https://([^:]+):([^@]+)@", r.stdout.strip()) + if m: + user, pw = m.groups() + token = base64.b64encode(f"{user}:{pw}".encode()).decode() + return {"Authorization": f"Basic {token}"} + except Exception: + pass + return {} + + +_GITEA_API = "https://git.sensey24.ru/api/v1/repos/aibot777/server-manager" + + +def publish_gitea_release(exe_path: str): + """Create a Gitea release and upload the exe as asset.""" + auth = _get_gitea_auth() + if not auth: + print("Gitea publish skipped: no auth (git remote 'sensey' not found)") + return + + tag = f"v{__version__}" + filename = os.path.basename(exe_path) + + # Create release + try: + data = json.dumps({ + "tag_name": tag, + "name": tag, + "body": f"Release {tag}", + }).encode() + req = urllib.request.Request( + f"{_GITEA_API}/releases", + data=data, + headers={**auth, "Content-Type": "application/json"}, + method="POST", + ) + resp = urllib.request.urlopen(req, timeout=30) + release = json.loads(resp.read()) + release_id = release["id"] + except urllib.error.HTTPError as e: + if e.code == 409: + print(f"Gitea release {tag} already exists, skipping") + else: + print(f"Gitea release creation failed: {e}") + return + except Exception as e: + print(f"Gitea release creation failed: {e}") + return + + # Upload asset + try: + with open(exe_path, "rb") as f: + file_data = f.read() + req = urllib.request.Request( + f"{_GITEA_API}/releases/{release_id}/assets?name={filename}", + data=file_data, + headers={**auth, "Content-Type": "application/octet-stream"}, + method="POST", + ) + resp = urllib.request.urlopen(req, timeout=180) + asset = json.loads(resp.read()) + size_mb = asset["size"] / (1024 * 1024) + print(f"Gitea release published: {tag} ({filename}, {size_mb:.1f} MB)") + except Exception as e: + print(f"Gitea asset upload failed: {e}") + def cleanup_old_releases(): """Keep the first release (v1.0.0) and the last 5 releases, delete the rest.""" diff --git a/releases/ServerManager-v1.8.85-win-x64.exe b/releases/ServerManager-v1.8.85-win-x64.exe new file mode 100644 index 0000000..30af598 Binary files /dev/null and b/releases/ServerManager-v1.8.85-win-x64.exe differ diff --git a/version.py b/version.py index 8cd9287..fefe4d5 100755 --- a/version.py +++ b/version.py @@ -1,6 +1,6 @@ """Version info for ServerManager.""" -__version__ = "1.8.84" +__version__ = "1.8.85" __app_name__ = "ServerManager" __author__ = "aibot777" __description__ = "Desktop GUI for managing remote servers"