Some checks failed
Publish Python Package to Gitea / publish (push) Failing after 59s
70 lines
2.0 KiB
Python
70 lines
2.0 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""技能健康检查。
|
||
|
||
检查项:
|
||
1. SKILL.md 成功解析,含 slug / version。
|
||
2. ``python scripts/main.py health`` 命令退出码为 0(每个 skill 都约定实现)。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
import logging
|
||
import os
|
||
import subprocess
|
||
import sys
|
||
|
||
from .config import SkillInfo
|
||
|
||
logger = logging.getLogger("jiangchang_desktop_sdk.testing.healthcheck")
|
||
|
||
|
||
class HealthCheckError(RuntimeError):
|
||
"""健康检查失败。"""
|
||
|
||
|
||
def skill_healthcheck(
|
||
skill_info: SkillInfo,
|
||
*,
|
||
run_cli: bool = True,
|
||
timeout_s: float = 15.0,
|
||
) -> None:
|
||
"""对一个 skill 跑本地健康检查。失败抛 ``HealthCheckError``。"""
|
||
if not skill_info.slug:
|
||
raise HealthCheckError(f"SKILL.md 未定义 openclaw.slug:{skill_info.root}")
|
||
if not skill_info.version or skill_info.version == "0.0.0":
|
||
raise HealthCheckError(f"SKILL.md 未定义 version:{skill_info.root}")
|
||
|
||
if not run_cli:
|
||
return
|
||
|
||
main_py = os.path.join(skill_info.root, "scripts", "main.py")
|
||
if not os.path.isfile(main_py):
|
||
logger.warning("skill_healthcheck: %s 不存在,跳过 CLI health 检查", main_py)
|
||
return
|
||
|
||
cmd = [sys.executable, main_py, "health"]
|
||
logger.debug("skill_healthcheck: 运行 %s (cwd=%s)", cmd, skill_info.root)
|
||
try:
|
||
proc = subprocess.run(
|
||
cmd,
|
||
capture_output=True,
|
||
text=True,
|
||
timeout=timeout_s,
|
||
cwd=skill_info.root,
|
||
encoding="utf-8",
|
||
errors="replace",
|
||
)
|
||
except subprocess.TimeoutExpired as exc:
|
||
raise HealthCheckError(
|
||
f"skill_healthcheck: '{' '.join(cmd)}' 超时 {timeout_s}s"
|
||
) from exc
|
||
|
||
if proc.returncode != 0:
|
||
raise HealthCheckError(
|
||
f"skill_healthcheck: '{' '.join(cmd)}' 退出码 {proc.returncode}\n"
|
||
f"stdout: {proc.stdout[:600]}\n"
|
||
f"stderr: {proc.stderr[:600]}"
|
||
)
|
||
logger.info(
|
||
"skill_healthcheck: %s v%s OK", skill_info.slug, skill_info.version
|
||
)
|