#!/usr/bin/env python3 """部署单日课程(每天 14:00)""" import argparse import os import shutil import subprocess import sys from pathlib import Path import yaml PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent.parent def load_config() -> dict: """加载配置""" config_path = PROJECT_ROOT / "skills" / "mathlab" / "config.yaml" with open(config_path, "r", encoding="utf-8") as f: return yaml.safe_load(f) def move_files(day: int, config: dict) -> bool: """从 staging 移动到正式目录""" staging_dir = PROJECT_ROOT / config["output"]["staging"] courseware_dir = PROJECT_ROOT / config["output"]["courseware"] exercises_dir = PROJECT_ROOT / config["output"]["exercises"] tests_dir = PROJECT_ROOT / config["output"]["tests"] # 确保目标目录存在 for dir_path in [courseware_dir, exercises_dir, tests_dir]: dir_path.mkdir(parents=True, exist_ok=True) # 检查是否已部署 html_dst = courseware_dir / f"course_day{day}.html" exercise_dst = exercises_dir / f"day{day}_task.py" test_dst = tests_dir / f"test_day{day}.py" if html_dst.exists() and exercise_dst.exists() and test_dst.exists(): print(f"⚠️ Day {day} 已部署,跳过") return True # 已部署,返回成功 # 移动 HTML html_src = staging_dir / f"course_day{day}.html" if html_src.exists(): shutil.copy2(html_src, html_dst) print(f"✅ 移动课程 HTML: {html_dst}") else: print(f"❌ 课程 HTML 不存在:{html_src}") return False # 移动练习题 exercise_src = staging_dir / "exercises" / f"day{day}_task.py" if exercise_src.exists(): shutil.copy2(exercise_src, exercise_dst) print(f"✅ 移动练习题:{exercise_dst}") else: print(f"❌ 练习题不存在:{exercise_src}") return False # 移动测试 test_src = staging_dir / "tests" / f"test_day{day}.py" if test_src.exists(): shutil.copy2(test_src, test_dst) print(f"✅ 移动测试用例:{test_dst}") else: print(f"❌ 测试用例不存在:{test_src}") return False return True def git_commit(day: int, topic: str) -> bool: """Git 提交""" try: # 检查是否已有 tag tag_name = f"v_day{day}_{topic.replace(' ', '_')}" result = subprocess.run( ["git", "tag", "-l", tag_name], capture_output=True, text=True, cwd=PROJECT_ROOT ) if result.returncode == 0 and result.stdout.strip(): print(f"⚠️ Tag {tag_name} 已存在,跳过提交") return True # 已部署,返回成功 # git add result = subprocess.run( ["git", "add", "."], capture_output=True, text=True, cwd=PROJECT_ROOT ) if result.returncode != 0: print(f"❌ git add 失败:{result.stderr}") return False # git commit commit_msg = f"Deploy Day {day}: {topic}" result = subprocess.run( ["git", "commit", "-m", commit_msg], capture_output=True, text=True, cwd=PROJECT_ROOT ) if result.returncode != 0: print(f"❌ git commit 失败:{result.stderr}") return False print(f"✅ Git commit: {commit_msg}") # git tag result = subprocess.run( ["git", "tag", tag_name], capture_output=True, text=True, cwd=PROJECT_ROOT ) if result.returncode != 0: print(f"❌ git tag 失败:{result.stderr}") return False print(f"✅ Git tag: {tag_name}") return True except Exception as e: print(f"❌ Git 操作异常:{e}") return False def git_push(config: dict) -> bool: """Git 推送""" try: branch = config.get("git_branch", "master") result = subprocess.run( ["git", "push", "origin", branch, "--tags"], capture_output=True, text=True, cwd=PROJECT_ROOT ) if result.returncode != 0: print(f"❌ git push 失败:{result.stderr}") return False print("✅ Git push 成功") return True except Exception as e: print(f"❌ Git push 异常:{e}") return False def send_notification(day: int, topic: str, config: dict) -> bool: """发送通知(通过 OpenClaw message 工具)""" if not config.get("notification", {}).get("enabled", False): print("⚠️ 通知已禁用") return True template = config["notification"]["template"] message = template.format(topic=topic) print(f"\n📱 通知消息:\n{message}") # TODO: 调用 OpenClaw message 工具发送 # 这里需要集成 OpenClaw 的 message 工具 # 目前先打印消息,用户手动发送 return True def main(): parser = argparse.ArgumentParser(description="部署单日课程") parser.add_argument("--day", type=int, required=True, help="天数") parser.add_argument("--topic", type=str, required=True, help="主题名称") args = parser.parse_args() config = load_config() print("=" * 50) print(f"🚀 部署 Day {args.day}: {args.topic}") print("=" * 50) # 移动文件 if not move_files(args.day, config): print("❌ 文件移动失败") sys.exit(1) # Git 提交 if not git_commit(args.day, args.topic): print("❌ Git 提交失败") sys.exit(1) # Git 推送 if not git_push(config): print("❌ Git 推送失败") sys.exit(1) # 发送通知 send_notification(args.day, args.topic, config) print("\n🎉 部署完成!") if __name__ == "__main__": main()