@@ -150,25 +150,52 @@ def get_org_runners(org: str) -> List[Dict]:
150150 return []
151151
152152
153- def get_recent_workflow_summary (org : str , repos : List [Dict ], days : int = 30 ) -> Dict :
153+ def get_org_workflow_runs (org : str , days : int = 30 ) -> List [Dict ]:
154+ """Get all workflow runs for organization (single API call)."""
155+ since = (datetime .now () - timedelta (days = days )).strftime ("%Y-%m-%d" )
156+ output = run_gh ([
157+ "api" , f"/orgs/{ org } /actions/runs" ,
158+ "--paginate" ,
159+ "-q" , f".workflow_runs[] | select(.created_at >= \" { since } \" ) | {{repo: .repository.name, conclusion: .conclusion}}"
160+ ])
161+ if not output :
162+ return []
163+
164+ runs = []
165+ for line in output .strip ().split ('\n ' ):
166+ if line :
167+ try :
168+ runs .append (json .loads (line ))
169+ except json .JSONDecodeError :
170+ pass
171+ return runs
172+
173+
174+ def get_recent_workflow_summary (org : str , repos : List [Dict ], days : int = 30 , show_progress : bool = False ) -> Dict :
154175 """Get a quick summary of recent workflow activity."""
155- total_runs = 0
156- total_success = 0
157- total_failure = 0
158- active_repos = 0
159-
160- for repo in repos [:50 ]: # Limit to first 50 repos for speed
161- runs = get_workflow_runs (org , repo ["name" ], days )
162- if runs :
163- active_repos += 1
164- total_runs += len (runs )
165- total_success += len ([r for r in runs if r .get ("conclusion" ) == "success" ])
166- total_failure += len ([r for r in runs if r .get ("conclusion" ) == "failure" ])
176+ if show_progress :
177+ print (f" Fetching workflow runs..." , end = "" , flush = True )
178+
179+ # Single API call for all org runs
180+ runs = get_org_workflow_runs (org , days )
181+
182+ if show_progress :
183+ print ("\r " + " " * 40 + "\r " , end = "" )
184+
185+ if not runs :
186+ return {"total_runs" : 0 , "success" : 0 , "failure" : 0 , "active_repos" : 0 }
187+
188+ # Count by conclusion
189+ success = len ([r for r in runs if r .get ("conclusion" ) == "success" ])
190+ failure = len ([r for r in runs if r .get ("conclusion" ) == "failure" ])
191+
192+ # Count unique repos with runs
193+ active_repos = len (set (r .get ("repo" ) for r in runs if r .get ("repo" )))
167194
168195 return {
169- "total_runs" : total_runs ,
170- "success" : total_success ,
171- "failure" : total_failure ,
196+ "total_runs" : len ( runs ) ,
197+ "success" : success ,
198+ "failure" : failure ,
172199 "active_repos" : active_repos
173200 }
174201
@@ -317,11 +344,12 @@ def main():
317344 print ()
318345 else :
319346 print (f" { YELLOW } Could not fetch billing data{ NC } " )
347+ print (f" { DIM } (Requires org owner/billing manager role + admin:org scope){ NC } " )
320348 print ()
321349
322350 # Quick activity summary (always show)
323351 print (f"{ BOLD } Recent Activity (last { args .days } days):{ NC } " )
324- summary = get_recent_workflow_summary (args .org , repos , args .days )
352+ summary = get_recent_workflow_summary (args .org , repos , args .days , show_progress = True )
325353
326354 if summary ["total_runs" ] > 0 :
327355 success_rate = (summary ["success" ] / summary ["total_runs" ] * 100 ) if summary ["total_runs" ] > 0 else 0
0 commit comments