fix: address PR #43 review feedback (M1-M3, S1)
M1: git pull in dev dir + rsync to install dir (install dir has no .git) M2: use asyncio.create_subprocess_exec instead of subprocess.run M3: add repo whitelist (only sanguo/sanguo_moziplus_v2 triggers auto-deploy) S1: notify jiangwei-infra on rsync/pm2 restart failure
This commit is contained in:
+55
-25
@@ -481,40 +481,70 @@ async def _handle_pr_closed(payload: Dict[str, Any]) -> None:
|
||||
title = f"PR 已合并: {pr_title} ({repo}#{pr_number})"
|
||||
_send_mail(pr_author, title, text)
|
||||
|
||||
# 自动部署:git pull + 按需 pm2 restart
|
||||
# 自动部署:git pull + rsync + 按需 pm2 restart(仅 sanguo/sanguo_moziplus_v2)
|
||||
try:
|
||||
import subprocess
|
||||
import os
|
||||
if repo != "sanguo/sanguo_moziplus_v2":
|
||||
return
|
||||
|
||||
dev_dir = os.path.expanduser("~/.openclaw/sanguo_projects/sanguo_moziplus_v2")
|
||||
install_dir = os.environ.get("SANGUO_PROJECTS_DIR", os.path.expanduser("~/.sanguo_projects"))
|
||||
repo_dir = os.path.join(install_dir, "sanguo_moziplus_v2")
|
||||
install_repo_dir = os.path.join(install_dir, "sanguo_moziplus_v2")
|
||||
|
||||
# git pull
|
||||
pull_result = subprocess.run(
|
||||
["git", "pull", "origin", "main"],
|
||||
cwd=repo_dir, capture_output=True, text=True, timeout=30
|
||||
# Step 1: git pull in dev dir
|
||||
proc = await asyncio.create_subprocess_exec(
|
||||
"git", "pull", "origin", "main",
|
||||
cwd=dev_dir,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
)
|
||||
if pull_result.returncode == 0:
|
||||
logger.info("Auto-deploy: git pull success for %s", repo)
|
||||
stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=30)
|
||||
|
||||
# 判断是否需要重启:获取 PR 变更文件列表
|
||||
files = await _fetch_pr_files(repo, pr_number)
|
||||
needs_restart = any(
|
||||
f.startswith("src/") or f.startswith("templates/") or f.startswith("frontend/") or f.endswith(".py")
|
||||
for f in files[0]
|
||||
if proc.returncode != 0:
|
||||
logger.warning("Auto-deploy: git pull failed: %s", stderr.decode())
|
||||
return
|
||||
|
||||
logger.info("Auto-deploy: git pull success for %s", repo)
|
||||
|
||||
# Step 2: rsync to install dir
|
||||
rsync_proc = await asyncio.create_subprocess_exec(
|
||||
"rsync", "-a", "--exclude=.git", "--exclude=node_modules", "--exclude=__pycache__",
|
||||
f"{dev_dir}/", f"{install_repo_dir}/",
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
)
|
||||
_, rsync_err = await asyncio.wait_for(rsync_proc.communicate(), timeout=60)
|
||||
|
||||
if rsync_proc.returncode != 0:
|
||||
logger.error("Auto-deploy: rsync failed: %s", rsync_err.decode())
|
||||
_send_mail("jiangwei-infra", f"[Auto-Deploy] rsync 失败 ({repo}#{pr_number})",
|
||||
f"PR {pr_title} 合并后自动部署 rsync 失败。\n\nstderr: {rsync_err.decode()}")
|
||||
return
|
||||
|
||||
# Step 3: 判断是否需要重启
|
||||
files = await _fetch_pr_files(repo, pr_number)
|
||||
needs_restart = any(
|
||||
f.startswith("src/") or f.startswith("templates/") or f.startswith("frontend/") or f.endswith(".py")
|
||||
for f in files[0]
|
||||
)
|
||||
|
||||
if needs_restart:
|
||||
restart_proc = await asyncio.create_subprocess_exec(
|
||||
"pm2", "restart", "sanguo-moziplus-v2",
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
)
|
||||
_, restart_err = await asyncio.wait_for(restart_proc.communicate(), timeout=15)
|
||||
|
||||
if needs_restart:
|
||||
restart_result = subprocess.run(
|
||||
["pm2", "restart", "sanguo-moziplus-v2"],
|
||||
capture_output=True, text=True, timeout=15
|
||||
)
|
||||
if restart_result.returncode == 0:
|
||||
logger.info("Auto-deploy: pm2 restart triggered (files: %s)", ", ".join(files[0][:5]))
|
||||
else:
|
||||
logger.error("Auto-deploy: pm2 restart failed: %s", restart_result.stderr)
|
||||
if restart_proc.returncode == 0:
|
||||
logger.info("Auto-deploy: pm2 restart triggered (files: %s)", ", ".join(files[0][:5]))
|
||||
else:
|
||||
logger.error("Auto-deploy: pm2 restart failed: %s", restart_err.decode())
|
||||
_send_mail("jiangwei-infra", f"[Auto-Deploy] pm2 restart 失败 ({repo}#{pr_number})",
|
||||
f"PR {pr_title} 合并后 pm2 restart 失败。\n\nstderr: {restart_err.decode()}")
|
||||
else:
|
||||
logger.warning("Auto-deploy: git pull failed: %s", pull_result.stderr)
|
||||
logger.info("Auto-deploy: docs-only change, skip restart")
|
||||
except asyncio.TimeoutError:
|
||||
logger.error("Auto-deploy: timeout")
|
||||
except Exception as e:
|
||||
logger.error("Auto-deploy: unexpected error: %s", e)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user