new python build-deploy chain

This commit is contained in:
Mikkeli Matlock
2026-01-25 00:34:01 +09:00
parent 42e2094635
commit 754cecffd4
8 changed files with 532 additions and 24 deletions

97
scripts/deploy.py Normal file
View File

@@ -0,0 +1,97 @@
#!/usr/bin/env python3
"""Deploy script for Smart Serow Flutter UI.
Pushes build bundle to Pi and optionally restarts service.
"""
import argparse
import json
import subprocess
import sys
import time
from pathlib import Path
SCRIPT_DIR = Path(__file__).parent.resolve()
PROJECT_ROOT = SCRIPT_DIR.parent
CONFIG_FILE = SCRIPT_DIR / "deploy_target.json"
BUILD_DIR = PROJECT_ROOT / "pi" / "ui" / "build" / "elinux" / "arm64" / "release" / "bundle"
def run(cmd: list[str], check: bool = True, **kwargs) -> subprocess.CompletedProcess:
"""Run a command."""
print(f"{' '.join(cmd)}")
return subprocess.run(cmd, check=check, **kwargs)
def load_config() -> dict:
"""Load deploy target configuration."""
if not CONFIG_FILE.exists():
print(f"ERROR: Config file not found: {CONFIG_FILE}")
print("Create it based on deploy_target.sample.json")
sys.exit(1)
with open(CONFIG_FILE) as f:
return json.load(f)
def deploy(restart: bool = False) -> bool:
"""Deploy to Pi. Returns True on success."""
config = load_config()
pi_user = config["user"]
pi_host = config["host"]
remote_path = config["remote_path"]
service_name = config["service_name"]
ssh_target = f"{pi_user}@{pi_host}"
print("=== Smart Serow Deploy ===")
print(f"Target: {ssh_target}:{remote_path}")
print(f"Source: {BUILD_DIR}")
if not BUILD_DIR.exists():
print("ERROR: Build directory not found. Run build.py first.")
return False
# Sync build to Pi
print()
print("Syncing files...")
run([
"rsync", "-avz", "--delete",
f"{BUILD_DIR}/",
f"{ssh_target}:{remote_path}/bundle/",
])
# Restart service if requested
if restart:
print()
print(f"Restarting service: {service_name}")
run(["ssh", ssh_target, f"sudo systemctl restart {service_name}"])
time.sleep(2)
run(["ssh", ssh_target, f"systemctl status {service_name} --no-pager"], check=False)
else:
print()
print("Deploy complete. To restart service, run:")
print(f" ssh {ssh_target} 'sudo systemctl restart {service_name}'")
print()
print("Or run this script with --restart flag")
return True
def main():
parser = argparse.ArgumentParser(description="Deploy Smart Serow to Pi")
parser.add_argument(
"--restart", "-r",
action="store_true",
help="Restart the systemd service after deploy",
)
args = parser.parse_args()
success = deploy(restart=args.restart)
sys.exit(0 if success else 1)
if __name__ == "__main__":
main()