feat(ack): bind test env to deployer and add regression mode
ACK 0.19.0 hands test-environment deploys to the deployer skill, documents bug-fix as a first-class scenario, and adds docs/ack/regression.yaml harvest plus a /ack regression run.
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
#!/usr/bin/env python3
|
||||
"""选择 ACK 回归目录中的 active 用例。
|
||||
|
||||
默认返回 smoke 套件。本脚本只输出数据,不执行 steps 或 automationRef。
|
||||
|
||||
用法:
|
||||
python3 select_regression.py docs/ack/regression.yaml
|
||||
python3 select_regression.py docs/ack/regression.yaml --suite full
|
||||
python3 select_regression.py docs/ack/regression.yaml --case-id REG-login-001
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from validate_regression import ID_RE, load_yaml, validate_builtin
|
||||
|
||||
DEFAULT_LIMIT = 50
|
||||
MAX_LIMIT = 200
|
||||
|
||||
|
||||
def select_cases(
|
||||
data: dict[str, Any],
|
||||
*,
|
||||
suite: str,
|
||||
case_ids: list[str],
|
||||
limit: int,
|
||||
) -> list[dict[str, Any]]:
|
||||
cases = data.get("cases")
|
||||
if not isinstance(cases, list):
|
||||
raise ValueError("cases 必须是列表")
|
||||
|
||||
wanted = set(case_ids)
|
||||
selected: list[dict[str, Any]] = []
|
||||
for case in cases:
|
||||
if not isinstance(case, dict):
|
||||
continue
|
||||
if case.get("status") != "active":
|
||||
continue
|
||||
case_id = case.get("id")
|
||||
if wanted:
|
||||
if case_id not in wanted:
|
||||
continue
|
||||
elif suite == "smoke" and case.get("suite") != "smoke":
|
||||
continue
|
||||
selected.append(case)
|
||||
|
||||
missing = wanted - {
|
||||
case.get("id") for case in selected if isinstance(case.get("id"), str)
|
||||
}
|
||||
if missing:
|
||||
raise ValueError("找不到 active 用例: " + ", ".join(sorted(missing)))
|
||||
if len(selected) > limit:
|
||||
raise ValueError(
|
||||
f"命中 {len(selected)} 条,超过 --limit {limit};"
|
||||
"请用 --suite / --case-id 缩小范围"
|
||||
)
|
||||
return selected
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
parser = argparse.ArgumentParser(description="选择 ACK 回归用例")
|
||||
parser.add_argument(
|
||||
"regression", nargs="?", default="docs/ack/regression.yaml"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--suite",
|
||||
choices=("smoke", "full"),
|
||||
default="smoke",
|
||||
help="smoke 只返回 suite=smoke;full 返回全部 active 用例",
|
||||
)
|
||||
parser.add_argument("--case-id", action="append", default=[], dest="case_ids")
|
||||
parser.add_argument("--limit", type=int, default=DEFAULT_LIMIT)
|
||||
parser.add_argument(
|
||||
"--format", choices=("json", "ids"), default="json", dest="output_format"
|
||||
)
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
regression_path = Path(args.regression)
|
||||
if not regression_path.is_file():
|
||||
sys.stderr.write(f"找不到回归目录: {regression_path}\n")
|
||||
return 2
|
||||
if not 1 <= args.limit <= MAX_LIMIT:
|
||||
sys.stderr.write(f"--limit 必须在 1..{MAX_LIMIT} 之间\n")
|
||||
return 2
|
||||
for case_id in args.case_ids:
|
||||
if ID_RE.fullmatch(case_id) is None:
|
||||
sys.stderr.write(f"--case-id 必须使用 REG-<id> 格式: {case_id}\n")
|
||||
return 2
|
||||
|
||||
data = load_yaml(regression_path, "回归目录")
|
||||
errors = validate_builtin(data)
|
||||
if errors:
|
||||
sys.stderr.write(f"回归目录无效,拒绝选择,共 {len(errors)} 项:\n")
|
||||
for error in errors:
|
||||
sys.stderr.write(f" - {error}\n")
|
||||
return 1
|
||||
|
||||
try:
|
||||
selected = select_cases(
|
||||
data,
|
||||
suite=args.suite,
|
||||
case_ids=args.case_ids,
|
||||
limit=args.limit,
|
||||
)
|
||||
except ValueError as exc:
|
||||
sys.stderr.write(f"回归选择失败: {exc}\n")
|
||||
return 1
|
||||
|
||||
ids = [case.get("id") for case in selected]
|
||||
if args.output_format == "ids":
|
||||
if ids:
|
||||
sys.stdout.write("\n".join(str(item) for item in ids) + "\n")
|
||||
return 0
|
||||
|
||||
payload = {
|
||||
"count": len(selected),
|
||||
"limit": args.limit,
|
||||
"suite": args.suite,
|
||||
"ids": ids,
|
||||
"cases": selected,
|
||||
}
|
||||
sys.stdout.write(json.dumps(payload, ensure_ascii=False, indent=2) + "\n")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user