fix(api): verify production deploy image readback
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Failing after 39s
CD Pipeline / build-and-deploy (push) Has been skipped
CD Pipeline / post-deploy-checks (push) Has been skipped

This commit is contained in:
Your Name
2026-06-30 08:25:39 +08:00
parent ff7febbf62
commit b3183582a6
7 changed files with 254 additions and 61 deletions

View File

@@ -118,29 +118,62 @@ def _enrich_runtime_build_readback(payload: dict[str, Any]) -> None:
else "runtime_build_diverges_from_committed_deploy_readback"
)
if source_matches_runtime and image_matches_runtime:
desired_tag = os.getenv("AWOOOI_DESIRED_API_IMAGE_TAG", "").strip().lower()
if not _SHA_RE.fullmatch(desired_tag):
readback["desired_main_api_image_tag_readback_status"] = "unavailable"
_mark_runtime_image_tag_blocked(
payload,
blocker="gitea_main_desired_api_image_tag_readback_unavailable",
next_action=(
"redeploy_with_awoooi_desired_api_image_tag_env_matching_gitops"
"_desired_api_tag"
),
)
return
# The runtime build SHA is evidence about the currently running image, not
# permission to rewrite source-control truth. If it diverges from the
# committed deploy snapshot, fail closed so Workbench cannot report a false
# "image tag matches main" closure while production routes are stale.
readback["desired_main_api_image_tag_source"] = "gitops_deployment_env"
readback["desired_main_api_image_tag_readback_status"] = "ok"
readback["desired_main_api_image_tag_sha"] = desired_tag
readback["desired_main_api_image_tag_short_sha"] = desired_tag[:10]
image_matches_main = build_sha == desired_tag
readback["production_image_tag_matches_main"] = image_matches_main
rollups["source_control_main_ready"] = True
rollups["production_image_tag_matches_main"] = image_matches_main
if image_matches_main:
return
_mark_runtime_image_tag_blocked(
payload,
blocker="production_runtime_image_tag_does_not_match_gitea_main_desired_tag",
next_action=(
"complete_cd_rollout_until_runtime_build_commit_matches_gitops"
"_desired_api_image_tag_env"
),
source_control_main_ready=True,
)
def _mark_runtime_image_tag_blocked(
payload: dict[str, Any],
*,
blocker: str,
next_action: str,
source_control_main_ready: bool = False,
) -> None:
payload["status"] = "blocked_production_runtime_image_tag_not_verified"
readback = _dict(payload.get("readback"))
readback["production_image_tag_matches_main"] = False
rollups["source_control_main_ready"] = False
blockers = _list(payload.setdefault("blockers", []))
if blocker not in blockers:
blockers.append(blocker)
next_actions = _list(payload.setdefault("next_actions", []))
if next_action not in next_actions:
next_actions.append(next_action)
rollups = _dict(payload.get("rollups"))
rollups["hard_blocker_count"] = len(blockers)
rollups["next_action_count"] = len(next_actions)
rollups["source_control_main_ready"] = source_control_main_ready
rollups["production_image_tag_matches_main"] = False
payload["status"] = "runtime_build_readback_stale"
_append_unique(
payload,
"blockers",
"runtime_build_commit_sha_does_not_match_committed_production_readback",
)
_append_unique(
payload,
"next_actions",
"refresh_production_deploy_readback_from_current_main_and_runtime_route_smoke",
)
rollups["hard_blocker_count"] = len(_list(payload.get("blockers")))
rollups["next_action_count"] = len(_list(payload.get("next_actions")))
def _require_no_internal_network_literals(value: Any, label: str) -> None:

View File

@@ -311,6 +311,18 @@ def build_delivery_closure_workbench(
)
is True
),
"desired_main_api_image_tag_short_sha": str(
production_deploy_readback.get(
"desired_main_api_image_tag_short_sha"
)
or ""
),
"desired_main_api_image_tag_readback_status": str(
production_deploy_readback.get(
"desired_main_api_image_tag_readback_status"
)
or ""
),
"production_image_tag_matches_main": production_deploy_readback.get(
"production_image_tag_matches_main"
)
@@ -1673,6 +1685,16 @@ def build_delivery_closure_workbench(
)
is True
),
"production_deploy_desired_main_api_image_tag_short_sha": str(
production_deploy_readback.get("desired_main_api_image_tag_short_sha")
or ""
),
"production_deploy_desired_main_api_image_tag_readback_status": str(
production_deploy_readback.get(
"desired_main_api_image_tag_readback_status"
)
or ""
),
"production_deploy_governance_fields_present": production_deploy_rollups.get(
"production_governance_fields_present"
)