Files
wehub-resource-sync bb5c75ce05
Component Security Validation / Security Audit (push) Waiting to run
Deploy to Cloudflare Pages / deploy (push) Waiting to run
chore: import upstream snapshot with attribution
2026-07-13 12:38:58 +08:00

128 lines
3.5 KiB
Python

#!/usr/bin/env python3
"""
Generate Claude Code PRs data.
Fetches all PRs from the GitHub API that were created from branches
starting with 'claude/' and writes a static JSON file for the dashboard.
Usage:
python scripts/generate_claude_prs.py
Optionally set GITHUB_TOKEN env var to avoid rate limits.
"""
import json
import os
import requests
import time
from datetime import datetime, timezone
REPO = "davila7/claude-code-templates"
API_URL = f"https://api.github.com/repos/{REPO}/pulls"
OUTPUT_FILE = os.path.join(os.path.dirname(__file__), "..", "docs", "claude-prs", "data.json")
def fetch_prs(state="all", token=None):
"""Fetch all PRs with pagination."""
headers = {"Accept": "application/vnd.github+json"}
if token:
headers["Authorization"] = f"Bearer {token}"
all_prs = []
page = 1
while True:
url = f"{API_URL}?state={state}&per_page=100&page={page}&sort=created&direction=desc"
print(f" Fetching page {page}...")
for attempt in range(3):
try:
resp = requests.get(url, headers=headers, timeout=30)
break
except requests.exceptions.RequestException as e:
if attempt < 2:
wait = 2 ** (attempt + 1)
print(f" Retry in {wait}s: {e}")
time.sleep(wait)
else:
raise
if resp.status_code == 403:
print(f" Rate limited. Set GITHUB_TOKEN env var to increase limits.")
break
if resp.status_code != 200:
print(f" Error {resp.status_code}: {resp.text[:200]}")
break
data = resp.json()
if not data:
break
all_prs.extend(data)
page += 1
if len(data) < 100:
break
return all_prs
def is_claude_pr(pr):
"""Check if a PR was created by Claude Code (branch starts with claude/)."""
ref = pr.get("head", {}).get("ref", "")
return ref.startswith("claude/")
def extract_pr_data(pr):
"""Extract only the fields needed for the dashboard."""
return {
"number": pr["number"],
"title": pr["title"],
"state": pr["state"],
"merged": pr.get("merged_at") is not None,
"branch": pr["head"]["ref"],
"created_at": pr["created_at"],
"merged_at": pr.get("merged_at"),
"closed_at": pr.get("closed_at"),
"url": pr["html_url"],
"user": pr.get("user", {}).get("login", "unknown"),
}
def main():
print("Generating Claude Code PRs data...")
token = os.environ.get("GITHUB_TOKEN")
if token:
print(" Using GITHUB_TOKEN for authentication")
else:
print(" No GITHUB_TOKEN set (60 req/hr limit). Set it to avoid rate limits.")
all_prs = fetch_prs(token=token)
print(f" Total PRs fetched: {len(all_prs)}")
claude_prs = [extract_pr_data(pr) for pr in all_prs if is_claude_pr(pr)]
print(f" Claude Code PRs found: {len(claude_prs)}")
# Sort by creation date descending
claude_prs.sort(key=lambda p: p["created_at"], reverse=True)
output = {
"generated_at": datetime.now(timezone.utc).isoformat(),
"repo": REPO,
"total": len(claude_prs),
"prs": claude_prs,
}
os.makedirs(os.path.dirname(OUTPUT_FILE), exist_ok=True)
with open(OUTPUT_FILE, "w") as f:
json.dump(output, f, indent=2)
print(f" Written to {OUTPUT_FILE}")
print("Done.")
if __name__ == "__main__":
main()