feat: track exact post-merge release progress (Closes #1092)
This commit is contained in:
1 parent
087300f9c3
commit
6db0802461
11 files changed
+374
-3
No files matched your search
@@ -25,7 +25,7 @@ FEATURE_SOURCES = {
|
||||
"issue-capture": (
|
||||
"static/voice-transcript-store.js", "static/voice-issue-capture.js", "static/create-issue-sheet.js", "static/mobile-create-issue-nav.js", "static/update-follow-up.js", "static/shared-image-capture.js",
|
||||
),
|
||||
"pull-workflow": ("static/pull-sheet.js", "static/review-sheet.js"),
|
||||
"pull-workflow": ("static/pull-sheet.js", "static/review-sheet.js", "static/release-receipt.js"),
|
||||
"push-notifications": ("static/push-notifications.js",),
|
||||
"device-setup": (
|
||||
"static/install-app.js", "static/private-data-inventory.js", "static/private-device-data.js",
|
||||
|
||||
+52
-1
@@ -2674,6 +2674,48 @@ async def pull_completion_review(repository: str, number: int) -> dict:
|
||||
}
|
||||
|
||||
|
||||
async def release_receipt_status(repository: str, commit_sha: str) -> dict:
|
||||
"""Return CI and release evidence for one exact merge commit."""
|
||||
status, releases = await asyncio.gather(
|
||||
fetch(f"repos/{repository}/commits/{commit_sha}/status"),
|
||||
fetch(f"repos/{repository}/releases?limit=20"),
|
||||
)
|
||||
normalized_checks = _normalize_commit_checks(status)
|
||||
checks = [
|
||||
{"name": check["name"], "state": check["state"], "url": check["url"]}
|
||||
for check in normalized_checks
|
||||
]
|
||||
matching = next(
|
||||
(
|
||||
release
|
||||
for release in (releases if isinstance(releases, list) else [])
|
||||
if isinstance(release, dict) and release.get("target_commitish") == commit_sha
|
||||
),
|
||||
None,
|
||||
)
|
||||
normalized_release = None
|
||||
if matching is not None:
|
||||
assets = matching.get("assets")
|
||||
normalized_release = {
|
||||
"tag": matching.get("tag_name") if isinstance(matching.get("tag_name"), str) else "",
|
||||
"url": _safe_gitea_web_url(matching.get("html_url")),
|
||||
"assets": [
|
||||
{
|
||||
"name": asset.get("name") if isinstance(asset.get("name"), str) else "",
|
||||
"url": _safe_gitea_web_url(asset.get("browser_download_url")),
|
||||
}
|
||||
for asset in (assets if isinstance(assets, list) else [])[:20]
|
||||
if isinstance(asset, dict)
|
||||
],
|
||||
}
|
||||
return {
|
||||
"commit_sha": commit_sha,
|
||||
"ci_state": status.get("state", "unknown") if isinstance(status, dict) else "unknown",
|
||||
"checks": checks,
|
||||
"release": normalized_release,
|
||||
}
|
||||
|
||||
|
||||
async def pull_check_status(repository: str, number: int) -> dict:
|
||||
"""Load only mutable pull and CI state, without immutable review data."""
|
||||
base = f"repos/{repository}/pulls/{number}"
|
||||
@@ -2741,7 +2783,16 @@ async def merge_assigned_pull(
|
||||
json={"Do": "merge", "head_commit_id": current_sha},
|
||||
)
|
||||
response.raise_for_status()
|
||||
return {"number": number, "merged": True, "state": "closed"}
|
||||
payload = response.json()
|
||||
merge_commit_sha = payload.get("sha") if isinstance(payload, dict) else None
|
||||
if not isinstance(merge_commit_sha, str) or not merge_commit_sha:
|
||||
raise ValueError("Gitea merge response did not include the merge commit")
|
||||
return {
|
||||
"number": number,
|
||||
"merged": True,
|
||||
"state": "closed",
|
||||
"merge_commit_sha": merge_commit_sha,
|
||||
}
|
||||
|
||||
|
||||
async def pull_review_detail(repository: str, number: int) -> dict:
|
||||
|
||||
@@ -6012,6 +6012,12 @@ async def merge_assigned_pull(
|
||||
)
|
||||
|
||||
|
||||
@app.get("/api/v1/repos/{owner}/{repo}/release-receipt/{commit_sha}")
|
||||
async def release_receipt(owner: str, repo: str, commit_sha: str):
|
||||
result = await gitea_proxy.release_receipt_status(f"{owner}/{repo}", commit_sha)
|
||||
return JSONResponse(result, headers={"Cache-Control": "no-store"})
|
||||
|
||||
|
||||
@app.post("/api/v1/repos/{owner}/{repo}/pulls/{number}/review", status_code=201)
|
||||
async def submit_review(
|
||||
submission: PullReviewSubmission,
|
||||
|
||||
Reference in new issue
Block a user