更新: 21 个文件 - 2026-03-17 00:00:00
这个提交包含在:
@@ -1,10 +1,12 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
from typing import Any, Dict, List
|
||||
|
||||
from lab.compose import compose_payload
|
||||
from lab.config import ENV_CATALOG_DIR, REPRO_MAP_PATH, REPRO_PROFILES_DIR
|
||||
from lab.utils import read_yaml
|
||||
from lab.utils import command_available, read_yaml, run, write_yaml
|
||||
|
||||
|
||||
def validate_assets() -> List[str]:
|
||||
@@ -32,4 +34,21 @@ def validate_assets() -> List[str]:
|
||||
]:
|
||||
if field not in content:
|
||||
errors.append(f"repro profile missing {field}: {path}")
|
||||
docker_available = command_available("docker")
|
||||
profile_roots = sorted((ENV_CATALOG_DIR.parent.parent / "profiles").rglob("*.yaml"))
|
||||
for path in profile_roots:
|
||||
content = read_yaml(path, default=None)
|
||||
if not isinstance(content, dict):
|
||||
errors.append(f"invalid environment profile yaml: {path}")
|
||||
continue
|
||||
for field in ["profile_id", "system_id", "services", "cleanup_policy"]:
|
||||
if field not in content:
|
||||
errors.append(f"environment profile missing {field}: {path}")
|
||||
if docker_available:
|
||||
with TemporaryDirectory() as temp_dir:
|
||||
compose_path = Path(temp_dir) / "compose.yaml"
|
||||
write_yaml(compose_path, compose_payload(content))
|
||||
result = run(["docker", "compose", "-f", str(compose_path), "config"], cwd=compose_path.parent)
|
||||
if result.returncode != 0:
|
||||
errors.append(f"docker compose config failed for {path}: {result.stderr.strip() or result.stdout.strip()}")
|
||||
return errors
|
||||
|
||||
在新工单中引用
屏蔽一个用户