feat(gitea): add package release promotion receipts

This commit is contained in:
ogt
2026-07-10 12:29:56 +08:00
parent ee7701f813
commit ec9478235d
5 changed files with 150 additions and 17 deletions

View File

@@ -196,6 +196,12 @@ def build_gitea_workflow_source_inventory(repo_root: Path) -> dict[str, Any]:
or "harbor" in lowered_text
or "/packages/" in lowered_text
),
"uses_package_release_promotion_contract": (
"package-release-promotion" in lowered_text
or "package_release_promotion" in lowered_text
or "release_channel_contract" in lowered_text
or "rollback_artifact_pattern" in lowered_text
),
"uses_argocd_gitops": "argocd" in lowered_text,
"uses_notification_or_webhook": (
"telegram" in lowered_text or "webhook" in lowered_text
@@ -292,6 +298,9 @@ def build_gitea_workflow_source_inventory(repo_root: Path) -> dict[str, Any]:
"registry_or_package_channel_workflow_count": _count_where(
rows, "uses_registry_or_package_channel"
),
"package_release_promotion_workflow_count": _count_where(
rows, "uses_package_release_promotion_contract"
),
"argocd_gitops_workflow_count": _count_where(rows, "uses_argocd_gitops"),
"notification_or_webhook_workflow_count": _count_where(
rows, "uses_notification_or_webhook"
@@ -342,6 +351,10 @@ def build_gitea_capability_ci_cd_optimization_readback(
professional_feature_rollups = _dict(
workflow_source_inventory.get("professional_feature_rollups")
)
package_release_contract_count = _int(
professional_feature_rollups.get("package_release_promotion_workflow_count")
)
package_release_contract_ready = package_release_contract_count > 0
full_dr_non_restore_gap_ids = [
gap for gap in full_dr_gap_ids if gap != "restore_drill_approval_gate"
]
@@ -497,19 +510,39 @@ def build_gitea_capability_ci_cd_optimization_readback(
"releases_tags",
"release_management",
"Releases and tags",
"controlled_apply_candidate",
"release/tag convention is not yet enforced across all products",
["GET /api/v1/agents/p0-cicd-baseline-source-readiness"],
"source_ready"
if package_release_contract_ready
else "controlled_apply_candidate",
"package/release promotion source contract is present"
if package_release_contract_ready
else "release/tag convention is not yet enforced across all products",
[
".gitea/workflows/cd.yaml",
"GET /api/v1/agents/p0-cicd-baseline-source-readiness",
],
"add release train tags, changelog receipt, and deploy marker correlation",
{
"package_release_promotion_workflow_count": package_release_contract_count
},
),
_capability(
"packages_registry",
"artifact_management",
"Packages / container and build artifacts",
"controlled_apply_candidate",
"package registry policy needs product-by-product adoption",
["GET /api/v1/agents/package-supply-chain-inventory"],
"source_ready"
if package_release_contract_ready
else "controlled_apply_candidate",
"package registry promotion source contract includes SBOM/provenance/rollback refs"
if package_release_contract_ready
else "package registry policy needs product-by-product adoption",
[
".gitea/workflows/cd.yaml",
"GET /api/v1/agents/package-supply-chain-inventory",
],
"promote build artifacts through Gitea Packages or internal registry with SBOM refs",
{
"package_release_promotion_workflow_count": package_release_contract_count
},
),
_capability(
"gitea_actions_workflows",
@@ -832,11 +865,21 @@ def build_gitea_capability_ci_cd_optimization_readback(
),
_optimization(
"package_registry_release_promotion",
"controlled_apply_candidate",
"source_ready"
if package_release_contract_ready
else "controlled_apply_candidate",
"Promote release artifacts through package/release channels",
"artifact channel is not yet standardized for every product",
["GET /api/v1/agents/package-supply-chain-inventory"],
"package/release promotion contract is wired into CI artifact receipts"
if package_release_contract_ready
else "artifact channel is not yet standardized for every product",
[
".gitea/workflows/cd.yaml",
"GET /api/v1/agents/package-supply-chain-inventory",
],
"add package registry, release tag, changelog, and rollback artifact receipts",
{
"package_release_promotion_workflow_count": package_release_contract_count
},
),
_optimization(
"branch_protection_required_checks",
@@ -1033,7 +1076,9 @@ def build_gitea_capability_ci_cd_optimization_readback(
_professional_practice(
"gitea_125_packages_release_registry",
"Gitea 1.25 Packages",
"controlled_apply_candidate"
"source_ready"
if package_release_contract_ready
else "controlled_apply_candidate"
if _int(
professional_feature_rollups.get(
"registry_or_package_channel_workflow_count"
@@ -1042,7 +1087,9 @@ def build_gitea_capability_ci_cd_optimization_readback(
> 0
else "action_required",
"Package registry, release artifacts, and rollback artifacts",
"registry channel is present, but Gitea package/release promotion is not standardized"
"Gitea package/release promotion source contract is wired into CI receipts"
if package_release_contract_ready
else "registry channel is present, but Gitea package/release promotion is not standardized"
if _int(
professional_feature_rollups.get(
"registry_or_package_channel_workflow_count"
@@ -1061,7 +1108,8 @@ def build_gitea_capability_ci_cd_optimization_readback(
professional_feature_rollups.get(
"registry_or_package_channel_workflow_count"
)
)
),
"package_release_promotion_workflow_count": package_release_contract_count,
},
),
_professional_practice(

View File

@@ -159,6 +159,7 @@ def test_gitea_capability_readback_rolls_up_complete_feature_surface() -> None:
assert (
professional_feature_rollups["registry_or_package_channel_workflow_count"] == 4
)
assert professional_feature_rollups["package_release_promotion_workflow_count"] == 1
assert professional_feature_rollups["sbom_or_provenance_workflow_count"] == 1
assert professional_feature_rollups["artifact_transfer_workflow_count"] == 1
assert (
@@ -272,11 +273,9 @@ def test_gitea_capability_readback_prioritizes_professional_cicd_gaps() -> None:
payload["professional_ci_cd_practice_rows"]
)
assert payload["rollups"]["p0_professional_ci_cd_practice_gap_count"] == 0
assert payload["rollups"]["market_professional_ci_cd_gap_count"] == 1
assert payload["rollups"]["market_professional_ci_cd_gap_count"] == 0
assert payload["rollups"]["all_gitea_features_fully_utilized"] is False
assert payload["rollups"]["professional_ci_cd_practice_gap_ids"] == [
"gitea_125_packages_release_registry",
]
assert payload["rollups"]["professional_ci_cd_practice_gap_ids"] == []
practice_by_id = {
row["id"]: row for row in payload["professional_ci_cd_practice_rows"]
@@ -288,6 +287,10 @@ def test_gitea_capability_readback_prioritizes_professional_cicd_gaps() -> None:
practice_by_id["gitea_125_secret_variable_redaction"]["status"]
== "source_ready"
)
assert (
practice_by_id["gitea_125_packages_release_registry"]["status"]
== "source_ready"
)
assert (
practice_by_id["gitea_125_actions_compatibility_gap_guard"]["status"]
== "source_ready"