feat(ack): add one-off delivery routing

This commit is contained in:
2026-08-01 15:25:15 +08:00
parent f8d03fad4d
commit a0f1c15b85
21 changed files with 871 additions and 58 deletions
+58 -1
View File
@@ -128,8 +128,15 @@ DISPATCH_FIELDS = {
"worker",
"developer",
"test",
"operator",
"rounds",
}
DELIVERY_OPERATION_FIELDS = {"skill", "request"}
DELIVERY_OPERATION_SKILLS = {
"manage-release",
"deb-publisher",
"publish-docker-image",
}
KNOWLEDGE_CANDIDATE_REQUIRED_FIELDS = {
"kind",
"title",
@@ -432,11 +439,14 @@ def validate_delivery_runs(
value: object,
task_statuses: dict[str, object],
errors: list[str],
*,
delivery_operation_ids: set[str] | None = None,
) -> None:
if not isinstance(value, list):
errors.append("deliveryRuns 必须是列表")
return
excluded_task_ids = delivery_operation_ids or set()
seen_run_ids: set[str] = set()
for index, run in enumerate(value):
where = f"deliveryRuns[{index}]"
@@ -476,6 +486,11 @@ def validate_delivery_runs(
for task_id in task_ids:
if task_id not in task_statuses:
errors.append(f"{where}.taskIds: 未知任务 {task_id!r}")
elif task_id in excluded_task_ids:
errors.append(
f"{where}.taskIds: deliveryRuns 不能引用 delivery-operation "
f"{task_id!r}"
)
elif task_statuses[task_id] != "verified":
errors.append(
f"{where}: delivery run 只能引用 verified 任务,"
@@ -807,6 +822,30 @@ def validate_builtin(data: dict) -> list[str]:
if not _nonempty_string(source.get("updatedAt")):
errors.append(f"{where}.source.updatedAt: 必须是非空字符串")
operation = task.get("operation")
if operation is not None:
if not isinstance(operation, dict):
errors.append(f"{where}.operation: 必须是对象")
else:
reject_unknown_fields(
operation,
DELIVERY_OPERATION_FIELDS,
f"{where}.operation",
errors,
)
skill = operation.get("skill")
if skill not in DELIVERY_OPERATION_SKILLS:
errors.append(
f"{where}.operation.skill: 必须是 "
"manage-release/deb-publisher/publish-docker-image"
)
if not _nonempty_string(operation.get("request")):
errors.append(f"{where}.operation.request: 必须保留非空用户请求")
if task.get("type") == "delivery-operation":
if not isinstance(operation, dict):
errors.append(f"{where}: delivery-operation 必须声明 operation")
validate_knowledge_fields(task, where, status, errors)
if "dispatch" not in task:
@@ -829,6 +868,12 @@ def validate_builtin(data: dict) -> list[str]:
nullable=True,
)
if task.get("type") == "delivery-operation" and (
not isinstance(dispatch, dict)
or not isinstance(dispatch.get("operator"), dict)
):
errors.append(f"{where}: delivery-operation 必须声明 dispatch.operator")
rounds = dispatch.get("rounds", [])
if not isinstance(rounds, list):
errors.append(f"{where}.dispatch.rounds: 必须是列表")
@@ -929,7 +974,19 @@ def validate_builtin(data: dict) -> list[str]:
for task in tasks
if isinstance(task, dict) and _nonempty_string(task.get("id"))
}
validate_delivery_runs(data["deliveryRuns"], task_statuses, errors)
delivery_operation_ids = {
task["id"]
for task in tasks
if isinstance(task, dict)
and _nonempty_string(task.get("id"))
and task.get("type") == "delivery-operation"
}
validate_delivery_runs(
data["deliveryRuns"],
task_statuses,
errors,
delivery_operation_ids=delivery_operation_ids,
)
return errors