@@ -16,11 +16,14 @@ def make_headers(self) -> dict:
1616 'content-type' : 'application/vnd.github.v3+json' ,
1717 }
1818
19+ def get_paginated_branches_url (self , page : int = 0 ) -> str :
20+ return f'{ GH_BASE_URL } /repos/{ self .github_repo } /branches?protected=false&per_page=30&page={ page } '
21+
1922 def get_deletable_branches (self , last_commit_age_days : int , ignore_branches : list ) -> list :
2023 # Default branch might not be protected
2124 default_branch = self .get_default_branch ()
2225
23- url = f' { GH_BASE_URL } /repos/ { self .github_repo } /branches'
26+ url = self .get_paginated_branches_url ()
2427 headers = self .make_headers ()
2528
2629 response = requests .get (url = url , headers = headers )
@@ -29,44 +32,59 @@ def get_deletable_branches(self, last_commit_age_days: int, ignore_branches: lis
2932
3033 deletable_branches = []
3134 branch : dict
32- for branch in response .json ():
33- branch_name = branch .get ('name' )
35+ branches : list = response .json ()
36+ current_page = 0
37+
38+ while len (branches ) > 0 :
39+ for branch in branches :
40+ branch_name = branch .get ('name' )
41+
42+ commit_hash = branch .get ('commit' , {}).get ('sha' )
43+ commit_url = branch .get ('commit' , {}).get ('url' )
44+
45+ print (f'Analyzing branch `{ branch_name } `...' )
46+
47+ # Immediately discard protected branches, default branch and ignored branches
48+ if branch_name == default_branch :
49+ print (f'Ignoring `{ branch_name } ` because it is the default branch' )
50+ continue
3451
35- commit_hash = branch .get ('commit' , {}).get ('sha' )
36- commit_url = branch .get ('commit' , {}).get ('url' )
52+ # We're already retrieving non-protected branches from the API, but it pays being careful when dealing
53+ # with third party apis
54+ if branch .get ('protected' ) is True :
55+ print (f'Ignoring `{ branch_name } ` because it is protected' )
56+ continue
3757
38- print (f'Analyzing branch `{ branch_name } `...' )
58+ if branch_name in ignore_branches :
59+ print (f'Ignoring `{ branch_name } ` because it is on the list of ignored branches' )
60+ continue
3961
40- # Immediately discard protected branches, default branch and ignored branches
41- if branch_name == default_branch :
42- print (f'Ignoring branch `{ branch_name } ` because it is the default branch ' )
43- continue
62+ # Move on if commit is in an open pull request
63+ if self . has_open_pulls ( commit_hash = commit_hash ) :
64+ print (f'Ignoring `{ branch_name } ` because it has open pulls ' )
65+ continue
4466
45- if branch .get ('protected' ) is True :
46- print (f'Ignoring branch `{ branch_name } ` because it is protected' )
47- continue
67+ # Move on if branch is base for a pull request
68+ if self .is_pull_request_base (branch = branch_name ):
69+ print (f'Ignoring `{ branch_name } ` because it is the base for a pull request of another branch' )
70+ continue
4871
49- if branch_name in ignore_branches :
50- print (f'Ignoring branch `{ branch_name } ` because it is on the list of ignored branches' )
51- continue
72+ # Move on if last commit is newer than last_commit_age_days
73+ if self .is_commit_older_than (commit_url = commit_url , older_than_days = last_commit_age_days ) is False :
74+ print (f'Ignoring `{ branch_name } ` because last commit is newer than { last_commit_age_days } days' )
75+ continue
5276
53- # Move on if commit is in an open pull request
54- if self .has_open_pulls (commit_hash = commit_hash ):
55- print (f'Ignoring branch `{ branch_name } ` because it has open pulls' )
56- continue
77+ print (f'Branch `{ branch_name } ` meets the criteria for deletion' )
78+ deletable_branches .append (branch_name )
5779
58- # Move on if branch is base for a pull request
59- if self .is_pull_request_base (branch = branch_name ):
60- print (f'Ignoring branch `{ branch_name } ` because it is the base for a pull request of another branch' )
61- continue
80+ # Re-request next page
81+ current_page += 1
6282
63- # Move on if last commit is newer than last_commit_age_days
64- if self .is_commit_older_than (commit_url = commit_url , older_than_days = last_commit_age_days ) is False :
65- print (f'Ignoring branch `{ branch_name } ` because last commit is newer than { last_commit_age_days } days' )
66- continue
83+ response = requests .get (url = self .get_paginated_branches_url (page = current_page ), headers = headers )
84+ if response .status_code != 200 :
85+ raise RuntimeError (f'Failed to make request to { url } . { response } { response .json ()} ' )
6786
68- print (f'Branch `{ branch_name } ` meets the criteria for deletion' )
69- deletable_branches .append (branch_name )
87+ branches : list = response .json ()
7088
7189 return deletable_branches
7290
0 commit comments