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 typing import Optional
import httpx
from loguru import logger
from ..config import settings
@ -29,18 +30,32 @@ class RepairScheduler:
interval: 扫描间隔默认 36001 小时
run_tests: 修复后是否运行测试
auto_commit: 是否自动提交代码
projects: 要监控的项目列表None 表示所有已配置项目
projects: 要监控的项目列表None 表示API 动态获取
"""
self.interval = interval
self.run_tests = run_tests
self.auto_commit = auto_commit
self.projects = projects or self._get_configured_projects()
self.projects = projects # None 表示每次扫描时动态获取
self._stop_event = threading.Event()
self._repairing = False
@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"]
return [p for p in candidates if settings.get_project_path(p)]
@ -52,7 +67,10 @@ class RepairScheduler:
logger.info("=" * 60)
logger.info("Repair Scheduler 启动")
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.auto_commit}")
logger.info("=" * 60)
@ -81,12 +99,15 @@ class RepairScheduler:
ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
logger.info(f"[{ts}] 开始扫描...")
# 每次扫描时动态获取项目列表(除非启动时指定了固定列表)
projects = self.projects or self._fetch_projects_from_api()
task_manager = TaskManager()
total_found = 0
total_fixed = 0
try:
for project_id in self.projects:
for project_id in projects:
bugs = task_manager.fetch_pending_bugs(project_id)
if not bugs:
@ -97,13 +118,7 @@ class RepairScheduler:
total_found += count
logger.info(f" [{project_id}] 发现 {count} 个待修复 Bug")
# 检查项目路径是否存在
project_path = settings.get_project_path(project_id)
if not project_path:
logger.warning(f" [{project_id}] 未配置项目路径,跳过")
continue
# 执行修复
# 项目路径由 fix_project() 从 API 动态获取,此处不再阻断
fixed = self._run_repair(project_id)
total_fixed += fixed