diff --git a/scripts/agent_poller.py b/scripts/agent_poller.py index b5e6529..717896f 100644 --- a/scripts/agent_poller.py +++ b/scripts/agent_poller.py @@ -74,11 +74,34 @@ def list_issues(labels: list[str] | None = None): return issues +def _get_blocking_refs(issue_num: int) -> set[int]: + """Extract all issue references from an issue body + comments. + + Scans both the issue body and all comments for #N patterns, + returning a set of referenced issue numbers. + """ + refs: set[int] = set() + # Body + issue = _req("GET", f"/issues/{issue_num}") + body = issue.get("body", "") or "" + refs.update(int(m.group(1)) for m in re.finditer(r'#(\d+)', body)) + # Comments + try: + comments = _req("GET", f"/issues/{issue_num}/comments") + for c in comments: + cbody = c.get("body", "") or "" + refs.update(int(m.group(1)) for m in re.finditer(r'#(\d+)', cbody)) + except SystemExit: + pass + return refs + + def blocked_check(): """Check all blocked issues: if blocking issues are now closed, unblock. - Used by agents during polling to ensure blocked label doesn't persist - after blocking issues are resolved. + Scans issue body + comments for blocking references. + If no references found or all referenced issues are closed, + removes the 'blocked' label. """ try: all_blocked = _req("GET", "/issues?state=open&labels=blocked") @@ -92,13 +115,7 @@ def blocked_check(): unblocked_count = 0 for issue in all_blocked: - body = issue.get("body", "") - if not body: - continue - - blocking_nums = {int(m.group(1)) for m in re.finditer(r'#(\d+)', body)} - if not blocking_nums: - continue + blocking_nums = _get_blocking_refs(issue["number"]) all_resolved = True for blk in blocking_nums: @@ -115,9 +132,9 @@ def blocked_check(): new_label_names = [l for l in current_label_names if l != "blocked"] new_label_ids = _label_names_to_ids(new_label_names) _req("PUT", f"/issues/{issue['number']}/labels", {"labels": new_label_ids}) + reason = "所有阻塞 Issue 均已关闭" if blocking_nums else "无阻塞引用,移除残留 blocked 标签" print(f"Unblocked #{issue['number']}: {issue['title']}") - comment_issue(issue["number"], - f"阻塞已解除:所有阻塞 Issue 均已关闭。") + comment_issue(issue["number"], f"阻塞已解除:{reason}。") unblocked_count += 1 if unblocked_count == 0: @@ -158,8 +175,8 @@ def close_issue(num, body=None): def _unblock_issues_blocked_by(closed_num): """Check issues blocked by *closed_num* and unblock if all blockers resolved. - Finds open issues with 'blocked' label whose body references *closed_num* - via a '阻塞: #N' pattern. If all referenced blocking issues are now closed, + Scans both body and comments for #N references. If *closed_num* appears + in any blocked issue and all referenced issues are now closed, removes the 'blocked' label and comments on the unblocked issue. """ try: @@ -170,12 +187,7 @@ def _unblock_issues_blocked_by(closed_num): return for issue in all_blocked: - body = issue.get("body", "") - if not body: - continue - - # Extract all issue numbers from the body (e.g. #21, #40) - blocking_nums = {int(m.group(1)) for m in re.finditer(r'#(\d+)', body)} + blocking_nums = _get_blocking_refs(issue["number"]) if closed_num not in blocking_nums: continue