Slice 3: the PR flow
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+50
-3
@@ -218,13 +218,28 @@ async def refresh_rfc_repo(config: Config, gitea: Gitea, slug: str) -> None:
|
||||
pull["number"],
|
||||
pull.get("body") or "",
|
||||
)
|
||||
# §10.8: distinguish "user withdrew" from "Gitea closed for any
|
||||
# other reason." The bot's withdraw action lands in the actions
|
||||
# log; if we see it, surface state='withdrawn'.
|
||||
if state == "closed":
|
||||
withdrew = db.conn().execute(
|
||||
"""
|
||||
SELECT 1 FROM actions
|
||||
WHERE action_kind = 'withdraw_branch_pr'
|
||||
AND rfc_slug = ? AND pr_number = ? LIMIT 1
|
||||
""",
|
||||
(slug, pull["number"]),
|
||||
).fetchone()
|
||||
if withdrew:
|
||||
state = "withdrawn"
|
||||
merge_commit_sha = pull.get("merge_commit_sha")
|
||||
db.conn().execute(
|
||||
"""
|
||||
INSERT INTO cached_prs
|
||||
(rfc_slug, pr_kind, repo, pr_number, title, description, state,
|
||||
opened_by, opened_at, merged_at, closed_at,
|
||||
head_branch, base_branch, head_sha)
|
||||
VALUES (?, 'rfc_branch', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
head_branch, base_branch, head_sha, merge_commit_sha)
|
||||
VALUES (?, 'rfc_branch', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT(repo, pr_number) DO UPDATE SET
|
||||
title = excluded.title,
|
||||
description = excluded.description,
|
||||
@@ -232,7 +247,8 @@ async def refresh_rfc_repo(config: Config, gitea: Gitea, slug: str) -> None:
|
||||
opened_by = excluded.opened_by,
|
||||
merged_at = excluded.merged_at,
|
||||
closed_at = excluded.closed_at,
|
||||
head_sha = excluded.head_sha
|
||||
head_sha = excluded.head_sha,
|
||||
merge_commit_sha = COALESCE(excluded.merge_commit_sha, cached_prs.merge_commit_sha)
|
||||
""",
|
||||
(
|
||||
slug,
|
||||
@@ -248,8 +264,26 @@ async def refresh_rfc_repo(config: Config, gitea: Gitea, slug: str) -> None:
|
||||
head_branch,
|
||||
(pull.get("base") or {}).get("ref") or "main",
|
||||
(pull.get("head") or {}).get("sha"),
|
||||
merge_commit_sha,
|
||||
),
|
||||
)
|
||||
# §10.9: an explicit `Supersedes: #N` trailer on a merged PR's
|
||||
# body bumps the predecessor's state to closed and records the
|
||||
# supersession. The cache propagates this whether the merge came
|
||||
# via webhook or reconciler.
|
||||
if state == "merged":
|
||||
superseded = _parse_supersedes(pull.get("body") or "")
|
||||
if superseded:
|
||||
db.conn().execute(
|
||||
"""
|
||||
UPDATE cached_prs
|
||||
SET state = 'closed',
|
||||
superseded_by_pr_number = ?,
|
||||
closed_at = COALESCE(closed_at, datetime('now'))
|
||||
WHERE repo = ? AND pr_number = ? AND state = 'open'
|
||||
""",
|
||||
(pull["number"], repo_full, superseded),
|
||||
)
|
||||
|
||||
|
||||
async def refresh_meta_pulls(config: Config, gitea: Gitea) -> None:
|
||||
@@ -385,6 +419,19 @@ def _kind_from_branch(head_branch: str) -> str:
|
||||
return "idea" # fallback
|
||||
|
||||
|
||||
_SUPERSEDES_RE = None
|
||||
|
||||
|
||||
def _parse_supersedes(body: str) -> int | None:
|
||||
"""Parse a `Supersedes: #N` trailer from a PR body per §10.9."""
|
||||
import re as _re
|
||||
global _SUPERSEDES_RE
|
||||
if _SUPERSEDES_RE is None:
|
||||
_SUPERSEDES_RE = _re.compile(r"^Supersedes:\s*#(\d+)", _re.MULTILINE)
|
||||
m = _SUPERSEDES_RE.search(body or "")
|
||||
return int(m.group(1)) if m else None
|
||||
|
||||
|
||||
def _state_from_pull(pull: dict) -> str:
|
||||
if pull.get("merged"):
|
||||
return "merged"
|
||||
|
||||
Reference in New Issue
Block a user