Skip to content

Commit ec17357

Browse files
committed
feat: Refactor workflow summary to use single API call for organization workflow runs and improve performance
1 parent e98ccd3 commit ec17357

File tree

1 file changed

+45
-17
lines changed

1 file changed

+45
-17
lines changed

services/devtools/scripts/gh-actions-usage.py

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)