fix(webhook): re-read PR labels at review start so a late AI-USAGE counts #10

Merged
gitea_admin merged 3 commits from fix/ai-usage-label-reread into main 2026-08-20 23:42:37 +00:00
2 changed files with 24 additions and 1 deletions
Showing only changes of commit aedea973ab - Show all commits
+3 -1
View File
@@ -186,7 +186,9 @@ def _fetch_current_labels(repo: str, index: str) -> list:
opt-in is lost — the review posts without its usage block. Reading the opt-in is lost — the review posts without its usage block. Reading the
labels again at review start closes that window. labels again at review start closes that window.
""" """
url = f"{GITEA_API}/repos/{repo}/issues/{index}/labels" # GITEA_API is the bare host (no /api/v1) — every caller appends the
# version prefix itself; see ai_review._get / _post.
url = f"{GITEA_API}/api/v1/repos/{repo}/issues/{index}/labels"
req = urllib.request.Request(url, headers={ req = urllib.request.Request(url, headers={
"Authorization": f"token {BOT_TOKEN}", "Authorization": f"token {BOT_TOKEN}",
"Accept": "application/json", "Accept": "application/json",
+21
View File
@@ -162,6 +162,27 @@ def test_run_review_keeps_usage_off_when_label_absent(monkeypatch):
assert seen["report_usage"] is False assert seen["report_usage"] is False
def test_fetch_current_labels_hits_the_versioned_api_path(monkeypatch):
# GITEA_API is the bare host; the /api/v1 prefix is the caller's job.
# Getting this wrong 404s silently and the opt-in is lost — which is
# exactly what shipped the first time.
seen = {}
class _Resp:
def read(self): return b'[{"name": "AI-USAGE"}]'
def __enter__(self): return self
def __exit__(self, *a): return False
def _urlopen(req, timeout=None):
seen["url"] = req.full_url
return _Resp()
monkeypatch.setattr(ws.urllib.request, "urlopen", _urlopen)
out = ws._fetch_current_labels("o/r", "9")
assert out == [{"name": "AI-USAGE"}]
assert seen["url"] == f"{ws.GITEA_API}/api/v1/repos/o/r/issues/9/labels"
def test_label_reread_failure_is_not_fatal(monkeypatch): def test_label_reread_failure_is_not_fatal(monkeypatch):
# A dead API must not take the review down with it — the re-read is a # A dead API must not take the review down with it — the re-read is a
# best-effort upgrade of an opt-in flag, nothing more. # best-effort upgrade of an opt-in flag, nothing more.