11from os import getenv
2+ from typing import Optional
23
34import requests
45
56
67def get_github_prs (token : str , owner : str , repo : str , label : str = "" , state : str = "all" ) -> list [dict ]:
78 """
8- Fetches pull requests from a GitHub repository that match a given milestone and label .
9+ Fetches pull requests from a GitHub repository that match a given label and state .
910
1011 Args:
1112 token (str): GitHub token.
@@ -23,39 +24,10 @@ def get_github_prs(token: str, owner: str, repo: str, label: str = "", state: st
2324 "Accept" : "application/vnd.github.v3+json" ,
2425 }
2526
26- milestone_id = None
27- milestone_url = f"https://api.github.com/repos/{ owner } /{ repo } /milestones"
28- params = {"state" : "open" }
29-
30- try :
31- response = requests .get (milestone_url , headers = headers , params = params )
32- response .raise_for_status ()
33- milestones = response .json ()
34-
35- if len (milestones ) > 2 :
36- print ("More than two milestones found, unable to determine the milestone required." )
37- exit (1 )
38-
39- # milestones.pop()
40- for ms in milestones :
41- if ms ["title" ] != "Future" :
42- milestone_id = ms ["number" ]
43- print (f"Gathering PRs with milestone { ms ['title' ]} ..." )
44- break
45-
46- if not milestone_id :
47- print (f"No suitable milestone found in repository '{ owner } /{ repo } '." )
48- exit (1 )
49-
50- except requests .exceptions .RequestException as e :
51- print (f"Error fetching milestones: { e } " )
52- exit (1 )
53-
54- # This endpoint allows filtering by milestone and label. A PR in GH's perspective is a type of issue.
27+ # This endpoint allows filtering by label(and milestone). A PR in GH's perspective is a type of issue.
5528 prs_url = f"https://api.github.com/repos/{ owner } /{ repo } /issues"
5629 params = {
5730 "state" : state ,
58- "milestone" : milestone_id ,
5931 "labels" : label ,
6032 "per_page" : 100 ,
6133 }
@@ -83,14 +55,15 @@ def get_github_prs(token: str, owner: str, repo: str, label: str = "", state: st
8355 return all_prs
8456
8557
86- def get_prs (pull_request_items : list [dict ], label : str = "" , state : str = "all" ) -> list [dict ]:
58+ def get_prs (pull_request_items : list [dict ], label : str = "" , state : str = "all" , milestone_number : Optional [ int ] = None ) -> list [dict ]:
8759 """
8860 Returns a list of pull requests after applying the label and state filters.
8961
9062 Args:
9163 pull_request_items (list[dict]): List of PR items.
9264 label (str): The label name. Filter is not applied when empty string.
9365 state (str): State of PR, e.g. open, closed, all
66+ milestone_number (Optional[int]): The milestone number to filter by. If None, no milestone filtering is applied.
9467
9568 Returns:
9669 list: A list of dictionaries, where each dictionary represents a pull request.
@@ -99,11 +72,20 @@ def get_prs(pull_request_items: list[dict], label: str = "", state: str = "all")
9972 pr_list = []
10073 count = 0
10174 for pr in pull_request_items :
102- if state in [pr ["state" ], "all" ] and (not label or [item for item in pr ["labels" ] if item ["name" ] == label ]):
103- pr_list .append (pr )
104- count += 1
75+ if state not in [pr ["state" ], "all" ]:
76+ continue
77+
78+ if label and not [item for item in pr ["labels" ] if item ["name" ] == label ]:
79+ continue
80+
81+ if milestone_number :
82+ if not pr .get ("milestone" ) or pr ["milestone" ]["number" ] != milestone_number :
83+ continue
84+
85+ pr_list .append (pr )
86+ count += 1
10587
106- print (f"Found { count } PRs with { label if label else 'no filter on' } label and state as { state } " )
88+ print (f"Found { count } PRs with { label if label else 'no filter on' } label, state as { state } , and milestone { pr . get ( "milestone" ,{}). get ( "number" , "None" ) } " )
10789
10890 return pr_list
10991
@@ -204,24 +186,33 @@ def update_pull_request_description(token: str, owner: str, repo: str, pr_number
204186
205187 print (f"Fetching { state } PRs for { repository_owner } /{ repository_name } ..." )
206188
207- pull_requests = get_github_prs (github_token , repository_owner , repository_name )
189+ # First, get all PRs to find the release PR and determine the milestone
190+ all_pull_requests = get_github_prs (github_token , repository_owner , repository_name )
208191
209- if not pull_requests :
210- print ("No matching pull requests found" )
192+ if not all_pull_requests :
193+ print ("No pull requests found" )
211194 exit (1 )
212195
213- print (f"\n Found total of { len (pull_requests )} pull requests" )
196+ print (f"\n Found total of { len (all_pull_requests )} pull requests" )
214197
215- release_pr = get_prs (pull_requests , "release" , "open" )
198+ release_pr = get_prs (all_pull_requests , "release" , "open" )
216199
217200 if len (release_pr ) != 1 :
218201 print (f"Unable to find the exact release PR. Returned result: { release_pr } " )
219202 exit (1 )
220203
221204 print (f"Found release PR: { release_pr [0 ]['title' ]} " )
222205
223- enhancement_prs = get_prs (pull_requests , "enhancement" , "closed" )
224- bug_fix_prs = get_prs (pull_requests , "bug" , "closed" )
206+ release_milestone_number = release_pr [0 ].get ("milestone" ,{}).get ("number" ,None )
207+
208+ if not release_milestone_number :
209+ print ("Release PR does not have a milestone assigned." )
210+ exit (1 )
211+
212+ print (f"Using milestone number: { release_milestone_number } " )
213+
214+ enhancement_prs = get_prs (all_pull_requests , "enhancement" , "closed" , release_milestone_number )
215+ bug_fix_prs = get_prs (all_pull_requests , "bug" , "closed" , release_milestone_number )
225216
226217 description_content = "# Release notes\n "
227218 description_content += f"## Features\n { get_pr_descriptions (enhancement_prs )} " if enhancement_prs else ""
0 commit comments