From d0f036cb244685e9df72ce9f629a4e8e22718a34 Mon Sep 17 00:00:00 2001 From: zhifu gao Date: Tue, 30 Jun 2026 16:52:52 +0800 Subject: [PATCH] Show integration repository exposure metrics (#3081) --- scripts/collect_growth_metrics.py | 30 ++++++++- tests/test_collect_growth_metrics.py | 95 +++++++++++++++++++++++++++- 2 files changed, 120 insertions(+), 5 deletions(-) diff --git a/scripts/collect_growth_metrics.py b/scripts/collect_growth_metrics.py index ed9d1d23f..d6ef6b634 100755 --- a/scripts/collect_growth_metrics.py +++ b/scripts/collect_growth_metrics.py @@ -241,6 +241,7 @@ def collect_pull_request_metrics(spec: str, now: Optional[dt.datetime] = None) - pull_request = fetch_json(f"https://api.github.com/repos/{repo}/pulls/{pr_number}", github_headers()) head = pull_request.get("head") or {} base = pull_request.get("base") or {} + base_repo = base.get("repo") or {} author = pull_request.get("user") or {} head_sha = head.get("sha") checks = summarize_commit_checks(repo, head_sha) if head_sha else {"state": "unknown"} @@ -254,6 +255,8 @@ def collect_pull_request_metrics(spec: str, now: Optional[dt.datetime] = None) - "draft": pull_request.get("draft"), "mergeable": pull_request.get("mergeable"), "mergeable_state": pull_request.get("mergeable_state"), + "repo_stars": base_repo.get("stargazers_count"), + "repo_forks": base_repo.get("forks_count"), "updated_at": updated_at, "updated_age_days": days_since(updated_at, now), "next_action": recommend_integration_action(pull_request, checks), @@ -450,8 +453,8 @@ def format_integration_markdown(metrics: Dict[str, Any]) -> str: lines = [ f"# FunASR External Integration Snapshot ({metrics['collected_at_utc']})", "", - "| Pull request | State | Mergeable | Checks | Failed | Pending | Age | Action | Updated |", - "|---|---|---|---|---:|---:|---:|---|---|", + "| Pull request | Stars | Forks | State | Mergeable | Checks | Failed | Pending | Age | Action | Updated |", + "|---|---:|---:|---|---|---|---:|---:|---:|---|---|", ] for integration in metrics["integrations"]: checks = integration.get("checks", {}) @@ -459,8 +462,14 @@ def format_integration_markdown(metrics: Dict[str, Any]) -> str: pending_count = len(checks.get("pending_check_runs") or []) updated_age_days = integration.get("updated_age_days") age = f"{updated_age_days}d" if updated_age_days is not None else "n/a" + repo_stars = integration.get("repo_stars") + repo_stars = f"{repo_stars:,}" if repo_stars is not None else "n/a" + repo_forks = integration.get("repo_forks") + repo_forks = f"{repo_forks:,}" if repo_forks is not None else "n/a" lines.append( f"| [{integration['pr']}]({integration.get('html_url')}) | " + f"{repo_stars} | " + f"{repo_forks} | " f"{integration.get('state')} | " f"{integration.get('mergeable_state') or integration.get('mergeable')} | " f"{checks.get('state')} | " @@ -470,6 +479,23 @@ def format_integration_markdown(metrics: Dict[str, Any]) -> str: f"{integration.get('next_action') or 'inspect'} | " f"`{integration.get('updated_at')}` |" ) + priority_integrations = sorted( + ( + integration + for integration in metrics["integrations"] + if integration.get("state") == "open" and integration.get("repo_stars") is not None + ), + key=lambda integration: int(integration.get("repo_stars") or 0), + reverse=True, + ) + if priority_integrations: + lines.extend(["", "## High-exposure priorities", ""]) + for integration in priority_integrations[:5]: + lines.append( + f"- [{integration['pr']}]({integration.get('html_url')}): " + f"{int(integration['repo_stars']):,} stars, " + f"{integration.get('next_action') or 'inspect'}" + ) lines.extend(["", "## Failed or pending checks", ""]) for integration in metrics["integrations"]: checks = integration.get("checks", {}) diff --git a/tests/test_collect_growth_metrics.py b/tests/test_collect_growth_metrics.py index 70a57517b..d3ad401b4 100644 --- a/tests/test_collect_growth_metrics.py +++ b/tests/test_collect_growth_metrics.py @@ -640,6 +640,8 @@ def test_format_integration_markdown_includes_update_age_and_next_action(): "html_url": "https://github.com/huggingface/transformers/pull/46180", "state": "open", "mergeable_state": "blocked", + "repo_stars": 155_000, + "repo_forks": 31_000, "updated_at": "2026-06-29T23:45:57Z", "updated_age_days": 2, "next_action": "fix checks", @@ -650,13 +652,92 @@ def test_format_integration_markdown_includes_update_age_and_next_action(): output = module.format_integration_markdown(metrics) - assert "| Pull request | State | Mergeable | Checks | Failed | Pending | Age | Action | Updated |" in output + assert "| Pull request | Stars | Forks | State | Mergeable | Checks | Failed | Pending | Age | Action | Updated |" in output assert ( "| [huggingface/transformers#46180](https://github.com/huggingface/transformers/pull/46180) | " - "open | blocked | failure | 0 | 0 | 2d | fix checks | `2026-06-29T23:45:57Z` |" + "155,000 | 31,000 | open | blocked | failure | 0 | 0 | 2d | fix checks | `2026-06-29T23:45:57Z` |" ) in output +def test_format_integration_markdown_marks_missing_exposure_metrics_as_unavailable(): + module = load_growth_metrics_module() + metrics = { + "collected_at_utc": "2026-07-02T00:00:00+00:00", + "integrations": [ + { + "pr": "deleted-org/deleted-repo#1", + "html_url": "https://github.com/deleted-org/deleted-repo/pull/1", + "state": "open", + "mergeable_state": "unknown", + "updated_at": "2026-06-29T23:45:57Z", + "updated_age_days": None, + "next_action": "inspect", + "checks": {"state": "unknown", "failed_check_runs": [], "pending_check_runs": []}, + } + ], + } + + output = module.format_integration_markdown(metrics) + + assert ( + "| [deleted-org/deleted-repo#1](https://github.com/deleted-org/deleted-repo/pull/1) | " + "n/a | n/a | open | unknown | unknown | 0 | 0 | n/a | inspect | `2026-06-29T23:45:57Z` |" + ) in output + + +def test_format_integration_markdown_lists_high_exposure_priorities_by_stars(): + module = load_growth_metrics_module() + metrics = { + "collected_at_utc": "2026-07-02T00:00:00+00:00", + "integrations": [ + { + "pr": "ray-project/ray#64053", + "html_url": "https://github.com/ray-project/ray/pull/64053", + "state": "open", + "mergeable_state": "blocked", + "repo_stars": 43_000, + "repo_forks": 7_700, + "updated_at": "2026-06-30T07:02:58Z", + "updated_age_days": 0, + "next_action": "review gate", + "checks": {"state": "success", "failed_check_runs": [], "pending_check_runs": []}, + }, + { + "pr": "huggingface/transformers#46180", + "html_url": "https://github.com/huggingface/transformers/pull/46180", + "state": "open", + "mergeable_state": "blocked", + "repo_stars": 162_000, + "repo_forks": 33_000, + "updated_at": "2026-06-30T04:24:15Z", + "updated_age_days": 0, + "next_action": "request rerun", + "checks": {"state": "failure", "failed_check_runs": [], "pending_check_runs": []}, + }, + { + "pr": "deleted-org/deleted-repo#1", + "html_url": "https://github.com/deleted-org/deleted-repo/pull/1", + "state": "open", + "mergeable_state": "unknown", + "updated_at": "2026-06-29T23:45:57Z", + "updated_age_days": None, + "next_action": "inspect", + "checks": {"state": "unknown", "failed_check_runs": [], "pending_check_runs": []}, + }, + ], + } + + output = module.format_integration_markdown(metrics) + + assert "## High-exposure priorities" in output + transformers = "- [huggingface/transformers#46180](https://github.com/huggingface/transformers/pull/46180): 162,000 stars, request rerun" + ray = "- [ray-project/ray#64053](https://github.com/ray-project/ray/pull/64053): 43,000 stars, review gate" + assert transformers in output + assert ray in output + assert output.index(transformers) < output.index(ray) + assert "deleted-org/deleted-repo#1" not in output.split("## High-exposure priorities", 1)[1].split("## Failed or pending checks", 1)[0] + + def test_collect_issue_metrics_filters_pull_requests_and_assigns_waiting_on(monkeypatch): module = load_growth_metrics_module() @@ -810,7 +891,13 @@ def test_main_outputs_integrations_json(monkeypatch): "html_url": "https://github.com/ray-project/ray/pull/64053", "updated_at": "2026-06-30T01:53:52Z", "head": {"sha": "780eb4c", "ref": "issue-64052"}, - "base": {"ref": "master"}, + "base": { + "ref": "master", + "repo": { + "stargazers_count": 36_000, + "forks_count": 6_800, + }, + }, "user": {"login": "nh-atuan"}, } if url == "https://api.github.com/repos/ray-project/ray/commits/780eb4c/status": @@ -844,5 +931,7 @@ def test_main_outputs_integrations_json(monkeypatch): payload = json.loads(stdout.getvalue()) integration = payload["integrations"][0] assert integration["pr"] == "ray-project/ray#64053" + assert integration["repo_stars"] == 36_000 + assert integration["repo_forks"] == 6_800 assert integration["checks"]["state"] == "success" assert integration["next_action"] == "request review"