fix(awooop): 等待 source correlation review 回寫
Some checks failed
Code Review / ai-code-review (push) Successful in 14s
CD Pipeline / tests (push) Successful in 1m31s
CD Pipeline / build-and-deploy (push) Successful in 3m57s
CD Pipeline / post-deploy-checks (push) Failing after 15s

This commit is contained in:
Your Name
2026-06-15 12:42:37 +08:00
parent 2f559e8881
commit 802c4e5ab2
2 changed files with 259 additions and 1 deletions

View File

@@ -301,6 +301,88 @@ def _refresh_candidate_result(item: dict[str, Any]) -> dict[str, Any]:
}
def _failed_check_summary(payload: dict[str, Any]) -> str:
checks = payload.get("checks")
if not isinstance(checks, list):
return "-"
failed: list[str] = []
for check in checks:
if not isinstance(check, dict) or check.get("passed") is True:
continue
name = str(check.get("name") or "unknown").strip() or "unknown"
detail = str(check.get("detail") or "failed").strip() or "failed"
failed.append(f"{name}={detail}")
return ", ".join(failed) if failed else "-"
def _source_review_readback_state(
recurrence: dict[str, Any],
*,
work_item_id: str,
) -> dict[str, Any]:
items = recurrence.get("items")
if not isinstance(items, list):
return {"found": False, "decision": "missing_items", "review_id": None}
for item in items:
if not isinstance(item, dict):
continue
work_item = item.get("work_item")
if not isinstance(work_item, dict):
continue
source_review = (
item.get("source_correlation_review")
if isinstance(item.get("source_correlation_review"), dict)
else {}
)
candidate_ids = {
_source_review_work_item_id(item),
str(work_item.get("work_item_id") or "").strip(),
str(source_review.get("work_item_id") or "").strip(),
}
if work_item_id not in candidate_ids:
continue
return {
"found": True,
"decision": str(source_review.get("decision") or "missing").strip()
or "missing",
"review_id": source_review.get("review_id"),
}
return {"found": False, "decision": "not_found", "review_id": None}
def _wait_for_review_readback(
*,
args: argparse.Namespace,
work_item_id: str,
) -> dict[str, Any]:
recurrence_url = _url(
args.api_url,
"/api/v1/platform/events/dossier/recurrence",
{
"project_id": args.project_id,
"provider": args.provider,
"limit": args.limit,
},
)
last_state: dict[str, Any] = {}
attempts = max(int(args.review_readback_attempts or 1), 1)
for attempt in range(attempts):
recurrence = _http_json(recurrence_url)
last_state = _source_review_readback_state(
recurrence,
work_item_id=work_item_id,
)
if last_state.get("found") and last_state.get("decision") == "accepted":
return last_state
if attempt + 1 < attempts:
time.sleep(max(float(args.review_readback_interval_seconds or 0), 0.0))
raise SmokeError(
"accepted review did not appear in recurrence read model: "
f"work_item_id={work_item_id} found={last_state.get('found')} "
f"decision={last_state.get('decision')}"
)
def _apply_source_correlation_item(
*,
args: argparse.Namespace,
@@ -332,6 +414,7 @@ def _apply_source_correlation_item(
"accepted review was not recorded: "
f"status={review.get('review_record_status')} allowed={review.get('allowed')}"
)
_wait_for_review_readback(args=args, work_item_id=work_item_id)
apply_url = _url(
args.api_url,
@@ -352,7 +435,9 @@ def _apply_source_correlation_item(
if apply_result.get("apply_status") != "applied":
raise SmokeError(
"source correlation apply did not complete: "
f"status={apply_result.get('apply_status')} allowed={apply_result.get('allowed')}"
f"status={apply_result.get('apply_status')} "
f"allowed={apply_result.get('allowed')} "
f"failed_checks={_failed_check_summary(apply_result)}"
)
if apply_result.get("writes_incident_state") is not False:
raise SmokeError("apply unexpectedly wrote Incident state")
@@ -536,6 +621,8 @@ def parse_args(argv: list[str]) -> argparse.Namespace:
parser.add_argument("--min-applied", type=int, default=1)
parser.add_argument("--status-attempts", type=int, default=8)
parser.add_argument("--status-interval-seconds", type=float, default=2.0)
parser.add_argument("--review-readback-attempts", type=int, default=8)
parser.add_argument("--review-readback-interval-seconds", type=float, default=2.0)
parser.add_argument("--allow-non-canary", action="store_true")
parser.add_argument("--allow-existing-apply", action="store_true")
parser.add_argument(