feat(repair-agent): Scheduler 从 API 动态获取项目列表,移除硬编码
Some checks failed
Build and Deploy Log Center / build-and-deploy (push) Failing after 1m10s

- _fetch_projects_from_api() 调用 GET /api/v1/projects 获取所有已注册项目
- API 失败时回退到本地 .env 配置
- 每次扫描时动态获取(新注册项目无需重启 Scheduler)
- 移除 _tick() 中的 get_project_path 阻断检查(由 fix_project 处理)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
zyc 2026-02-26 10:29:00 +08:00
parent 874c873de9
commit 46c52a795f

View File

@ -7,6 +7,7 @@ import time
from datetime import datetime from datetime import datetime
from typing import Optional from typing import Optional
import httpx
from loguru import logger from loguru import logger
from ..config import settings from ..config import settings
@ -29,18 +30,32 @@ class RepairScheduler:
interval: 扫描间隔默认 36001 小时 interval: 扫描间隔默认 36001 小时
run_tests: 修复后是否运行测试 run_tests: 修复后是否运行测试
auto_commit: 是否自动提交代码 auto_commit: 是否自动提交代码
projects: 要监控的项目列表None 表示所有已配置项目 projects: 要监控的项目列表None 表示API 动态获取
""" """
self.interval = interval self.interval = interval
self.run_tests = run_tests self.run_tests = run_tests
self.auto_commit = auto_commit self.auto_commit = auto_commit
self.projects = projects or self._get_configured_projects() self.projects = projects # None 表示每次扫描时动态获取
self._stop_event = threading.Event() self._stop_event = threading.Event()
self._repairing = False self._repairing = False
@staticmethod @staticmethod
def _get_configured_projects() -> list[str]: def _fetch_projects_from_api() -> list[str]:
"""获取所有有路径配置的项目""" """从 Log Center API 动态获取所有已注册项目"""
try:
resp = httpx.get(f"{settings.log_center_url}/api/v1/projects", timeout=10)
resp.raise_for_status()
projects = resp.json().get("projects", [])
project_ids = [p["project_id"] for p in projects]
logger.info(f"从 API 获取到 {len(project_ids)} 个项目: {', '.join(project_ids)}")
return project_ids
except Exception as e:
logger.warning(f"从 API 获取项目列表失败: {e},回退到本地配置")
return RepairScheduler._get_local_projects()
@staticmethod
def _get_local_projects() -> list[str]:
"""回退:从本地 .env 配置获取有路径的项目"""
candidates = ["rtc_backend", "rtc_web", "airhub_app"] candidates = ["rtc_backend", "rtc_web", "airhub_app"]
return [p for p in candidates if settings.get_project_path(p)] return [p for p in candidates if settings.get_project_path(p)]
@ -52,7 +67,10 @@ class RepairScheduler:
logger.info("=" * 60) logger.info("=" * 60)
logger.info("Repair Scheduler 启动") logger.info("Repair Scheduler 启动")
logger.info(f" 扫描间隔: {self.interval}s ({self.interval // 60} min)") logger.info(f" 扫描间隔: {self.interval}s ({self.interval // 60} min)")
logger.info(f" 监控项目: {', '.join(self.projects)}") if self.projects:
logger.info(f" 监控项目: {', '.join(self.projects)} (指定)")
else:
logger.info(" 监控项目: 从 API 动态获取")
logger.info(f" 运行测试: {self.run_tests}") logger.info(f" 运行测试: {self.run_tests}")
logger.info(f" 自动提交: {self.auto_commit}") logger.info(f" 自动提交: {self.auto_commit}")
logger.info("=" * 60) logger.info("=" * 60)
@ -81,12 +99,15 @@ class RepairScheduler:
ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S") ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
logger.info(f"[{ts}] 开始扫描...") logger.info(f"[{ts}] 开始扫描...")
# 每次扫描时动态获取项目列表(除非启动时指定了固定列表)
projects = self.projects or self._fetch_projects_from_api()
task_manager = TaskManager() task_manager = TaskManager()
total_found = 0 total_found = 0
total_fixed = 0 total_fixed = 0
try: try:
for project_id in self.projects: for project_id in projects:
bugs = task_manager.fetch_pending_bugs(project_id) bugs = task_manager.fetch_pending_bugs(project_id)
if not bugs: if not bugs:
@ -97,13 +118,7 @@ class RepairScheduler:
total_found += count total_found += count
logger.info(f" [{project_id}] 发现 {count} 个待修复 Bug") logger.info(f" [{project_id}] 发现 {count} 个待修复 Bug")
# 检查项目路径是否存在 # 项目路径由 fix_project() 从 API 动态获取,此处不再阻断
project_path = settings.get_project_path(project_id)
if not project_path:
logger.warning(f" [{project_id}] 未配置项目路径,跳过")
continue
# 执行修复
fixed = self._run_repair(project_id) fixed = self._run_repair(project_id)
total_fixed += fixed total_fixed += fixed