in tools/release-notes-automator/generate_release_notes.py [0:0]
def get_closed_prs(repo, milestone_number):
"""
Retrieve all closed PRs for a given repo and milestone number,
filtered by the 'Release-Candidate' label. Handles pagination.
Only returns PRs that are:
- Closed and merged
- Not linked to any issue
- Belong to the current milestone
- Have the "Release-Candidate" label
"""
prs = []
page = 1
while True:
url = f"https://api.github.com/repos/{repo}/pulls"
params = {
"state": "closed",
"per_page": 100,
"page": page
}
response = safe_github_request(url, headers=HEADERS, params=params)
data = response.json()
if not data:
break
for pr in data:
# Only consider PRs that are closed and merged
if pr.get("state") != "closed" or not pr.get("merged_at"):
continue
# Must have milestone and match the current milestone number
pr_milestone = pr.get("milestone")
if not pr_milestone or pr_milestone.get("number") != milestone_number:
continue
# Must have the "Release-Candidate" label
pr_labels = [lbl["name"] for lbl in pr.get("labels", [])]
if "Release-Candidate" not in pr_labels:
continue
# Check for linked issues via timeline events
pr_number = pr["number"]
events_url = f"https://api.github.com/repos/{repo}/issues/{pr_number}/events"
events_resp = safe_github_request(events_url, headers=HEADERS)
events = events_resp.json()
linked_issue = any(
e["event"] == "connected" and e.get("commit_id") is None and e.get("source", {}).get("type") == "issue"
for e in events
)
if not linked_issue:
prs.append(pr)
page += 1
return prs