16
16
17
17
18
18
class GithubClient :
19
+ DEFAULT_DAYS_OF_HISTORY : int = 30
20
+
19
21
@staticmethod
20
22
def get_access_token (
21
23
app_id : str , app_private_key : str , app_installation_id : str = "" , app_auth : bool = False
@@ -43,8 +45,6 @@ def get_access_token(
43
45
def __init__ (self , config , logger , token ):
44
46
self .config = config
45
47
self .logger = logger
46
- self .history_limit_timestamp = datetime .now () - timedelta (days = self .days_of_history )
47
- self .repo_activity_limit_timestamp = datetime .now () - timedelta (days = self .days_of_history * 3 )
48
48
49
49
self ._headers = {
50
50
"Authorization" : f"Bearer { token } " ,
@@ -54,6 +54,11 @@ def __init__(self, config, logger, token):
54
54
self ._session : ClientSession | None = None
55
55
self ._retry_policy = RetryPolicy (logger = self .logger )
56
56
57
+ self ._days_of_history : int | None = None
58
+
59
+ self .history_limit_timestamp = datetime .now () - timedelta (days = self .days_of_history )
60
+ self .repo_activity_limit_timestamp = datetime .now () - timedelta (days = self .days_of_history * 3 )
61
+
57
62
async def __aenter__ (self ) -> "GithubClient" :
58
63
self ._session = create_session (timeout = self .timeout , headers = self ._headers )
59
64
return self
@@ -67,12 +72,19 @@ async def close(self) -> None:
67
72
68
73
@property
69
74
def days_of_history (self ) -> int :
70
- days = int (self .config .integration .properties ["daysOfHistory" ])
71
- if days < 1 :
72
- self .logger .warning ("Invalid days of history, using default value 30" )
73
- return 30
75
+ if self ._days_of_history is None :
76
+ try :
77
+ days = int (self .config .integration .properties ["daysOfHistory" ])
78
+ if days < 1 :
79
+ self .logger .warning ("Invalid days of history, using default value %d" , self .DEFAULT_DAYS_OF_HISTORY )
80
+ days = self .DEFAULT_DAYS_OF_HISTORY
81
+ except (ValueError , TypeError ):
82
+ self .logger .warning ("Missing days of history, using default value %d" , self .DEFAULT_DAYS_OF_HISTORY )
83
+ days = self .DEFAULT_DAYS_OF_HISTORY
84
+
85
+ self ._days_of_history = days
74
86
75
- return days
87
+ return self . _days_of_history
76
88
77
89
@property
78
90
def base_url (self ) -> str :
@@ -134,10 +146,16 @@ async def _make_request(
134
146
self .logger .error (f"Error while making request, defaulting to empty response. ({ e } )" )
135
147
return None
136
148
137
- async def _make_graphql_request (self , query : dict [str , Any ]) -> Any :
149
+ async def _make_graphql_request (self , query : dict [str , Any ], * , ignore_file_not_found_errors : bool = True ) -> Any :
138
150
response = await self ._make_request ("POST" , f"{ self .base_url } /graphql" , json = query , raise_on_error = True )
139
151
if response .get ("errors" ):
140
- self .logger .warning ("GraphQL error: %r" , response ["errors" ])
152
+ if not ignore_file_not_found_errors :
153
+ errors = response ["errors" ]
154
+ else :
155
+ errors = [e for e in response ["errors" ] if isinstance (e , dict ) and e .get ("type" ) != "NOT_FOUND" ]
156
+
157
+ if errors :
158
+ self .logger .warning ("GraphQL error: %r" , errors )
141
159
return response
142
160
143
161
def _parse_datetime (self , datetime_str : str ) -> datetime :
@@ -170,12 +188,12 @@ async def get_repos(
170
188
171
189
return repos_list
172
190
173
- async def get_repo (self , organization : str , repo : str ) -> dict [str , str | int ]:
191
+ async def get_repo (self , organization : str , repo : str ) -> dict [str , Any ]:
174
192
query = build_graphql_query (query_type = QueryType .REPOSITORY , repo_id = self .build_repo_id (organization , repo ))
175
193
response = await self ._make_graphql_request (query )
176
194
return response ["data" ]["repository" ]
177
195
178
- async def get_pull_requests (self , organization : str , repo : str , states : list [str ]) -> list [dict [str , str | int ]]:
196
+ async def get_pull_requests (self , organization : str , repo : str , states : list [str ]) -> list [dict [str , Any ]]:
179
197
all_pull_requests = []
180
198
181
199
cursor = None
@@ -205,7 +223,7 @@ async def get_pull_requests(self, organization: str, repo: str, states: list[str
205
223
206
224
return all_pull_requests
207
225
208
- async def get_issues (self , organization : str , repo : str , state : str ) -> list [dict [str , str | int ]]:
226
+ async def get_issues (self , organization : str , repo : str , state : str ) -> list [dict [str , Any ]]:
209
227
all_issues = []
210
228
211
229
cursor = None
@@ -234,7 +252,7 @@ async def get_issues(self, organization: str, repo: str, state: str) -> list[dic
234
252
235
253
return all_issues
236
254
237
- async def get_workflows (self , organization : str , repo : str ) -> list [dict [str , str | int ]]:
255
+ async def get_workflows (self , organization : str , repo : str ) -> list [dict [str , Any ]]:
238
256
all_workflows = []
239
257
240
258
url = f"{ self .base_url } /repos/{ organization } /{ repo } /actions/workflows"
@@ -250,7 +268,7 @@ async def get_workflows(self, organization: str, repo: str) -> list[dict[str, st
250
268
251
269
return all_workflows
252
270
253
- async def get_workflow_runs (self , organization : str , repo : str , workflow_id : str ) -> list [dict [str , str | int ]]:
271
+ async def get_workflow_runs (self , organization : str , repo : str , workflow_id : str ) -> list [dict [str , Any ]]:
254
272
all_workflow_runs = []
255
273
256
274
url = f"{ self .base_url } /repos/{ organization } /{ repo } /actions/workflows/{ workflow_id } /runs"
@@ -290,7 +308,7 @@ async def get_workflow_run_jobs(self, organization: str, repo: str, run_id: str)
290
308
291
309
return all_jobs
292
310
293
- async def get_members (self , organization : str ) -> list [dict [str , str | int ]]:
311
+ async def get_members (self , organization : str ) -> list [dict [str , Any ]]:
294
312
all_members = []
295
313
cursor = None
296
314
while True :
@@ -391,7 +409,7 @@ async def get_team_repositories(self, organization: str, team_id: str) -> list[d
391
409
392
410
return all_repositories
393
411
394
- async def get_environments (self , organization : str , repo : str ) -> list [dict [str , str | int ]]:
412
+ async def get_environments (self , organization : str , repo : str ) -> list [dict [str , Any ]]:
395
413
all_environments = []
396
414
397
415
url = f"{ self .config .integration .properties ['url' ]} /repos/{ organization } /{ repo } /environments"
@@ -409,7 +427,7 @@ async def get_environments(self, organization: str, repo: str) -> list[dict[str,
409
427
410
428
async def get_deployments (
411
429
self , organization : str , repo : str , environments : Iterable [str ] | None = None
412
- ) -> list [dict [str , str | int ]]:
430
+ ) -> list [dict [str , Any ]]:
413
431
all_deployments = []
414
432
cursor = None
415
433
while True :
@@ -435,8 +453,12 @@ async def get_deployments(
435
453
return all_deployments
436
454
437
455
async def get_commits (
438
- self , organization : str , repo : str , branch : str , * , exclude_merge_commits : bool = True
439
- ) -> list [dict [str , str | int ]]:
456
+ self , organization : str , repo : str , branch : str | None , * , exclude_merge_commits : bool = True
457
+ ) -> list [dict [str , Any ]]:
458
+ if branch is None or not branch :
459
+ self .logger .warning ("Unable to fetch commits: branch not specified" )
460
+ return []
461
+
440
462
all_commits = []
441
463
442
464
query_builder = partial (
0 commit comments