From 70cf260b8856abe210cdfd954b5c8c51f2d64fa3 Mon Sep 17 00:00:00 2001 From: zhifu gao Date: Tue, 30 Jun 2026 11:49:44 +0800 Subject: [PATCH] Track integration status contexts Surface commit status contexts in external integration metrics so CLA and other non-check-run blockers are actionable. --- scripts/collect_growth_metrics.py | 14 ++++++++ tests/test_collect_growth_metrics.py | 53 ++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/scripts/collect_growth_metrics.py b/scripts/collect_growth_metrics.py index 323d26d44..ab43e6572 100755 --- a/scripts/collect_growth_metrics.py +++ b/scripts/collect_growth_metrics.py @@ -120,6 +120,15 @@ def summarize_commit_checks(repo: str, head_sha: str) -> Dict[str, Any]: elif check_run.get("conclusion") in FAILED_CHECK_CONCLUSIONS: failed_check_runs.append({"name": name, "conclusion": check_run.get("conclusion"), "url": url}) + for status_context in status.get("statuses", []): + name = status_context.get("context") + url = status_context.get("target_url") + state = status_context.get("state") + if state in {"error", "failure"}: + failed_check_runs.append({"name": name, "conclusion": state, "url": url}) + elif state == "pending": + pending_check_runs.append({"name": name, "status": state, "url": url}) + status_state = status.get("state") if failed_check_runs or status_state in {"error", "failure"}: state = "failure" @@ -166,6 +175,11 @@ def recommend_integration_action(pull_request: Dict[str, Any], checks: Dict[str, return "finish draft" check_state = checks.get("state") + pending_names = " ".join( + str(check.get("name") or "") for check in checks.get("pending_check_runs") or [] + ).lower() + if "cla" in pending_names: + return "resolve CLA" if check_state == "failure": return "fix checks" if check_state == "pending": diff --git a/tests/test_collect_growth_metrics.py b/tests/test_collect_growth_metrics.py index 6982bed4b..de8081943 100644 --- a/tests/test_collect_growth_metrics.py +++ b/tests/test_collect_growth_metrics.py @@ -311,6 +311,59 @@ def test_collect_integration_metrics_recommends_review_for_clean_success_pr(monk assert metrics["integrations"][0]["next_action"] == "request review" +def test_collect_integration_metrics_surfaces_pending_cla_status(monkeypatch): + module = load_growth_metrics_module() + + def fake_fetch_json(url, headers=None): + if url == "https://api.github.com/repos/activepieces/activepieces/pulls/13985": + return { + "number": 13985, + "title": "feat: add FunASR speech recognition piece", + "state": "open", + "draft": False, + "mergeable": True, + "mergeable_state": "blocked", + "html_url": "https://github.com/activepieces/activepieces/pull/13985", + "updated_at": "2026-06-30T01:17:07Z", + "head": {"sha": "f9d22ee", "ref": "funasr/activepieces-13450-conflict-fix"}, + "base": {"ref": "main"}, + "user": {"login": "LauraGPT"}, + } + if url == "https://api.github.com/repos/activepieces/activepieces/commits/f9d22ee/status": + return { + "state": "pending", + "statuses": [ + { + "context": "license/cla", + "state": "pending", + "target_url": "https://cla-assistant.io/activepieces/activepieces?pullRequest=13985", + } + ], + } + if url == "https://api.github.com/repos/activepieces/activepieces/commits/f9d22ee/check-runs?per_page=100": + return { + "total_count": 1, + "check_runs": [ + {"name": "GitGuardian Security Checks", "status": "completed", "conclusion": "success"}, + ], + } + raise AssertionError(f"unexpected URL: {url}") + + monkeypatch.setattr(module, "fetch_json", fake_fetch_json) + + metrics = module.collect_integration_metrics(["activepieces/activepieces#13985"]) + + integration = metrics["integrations"][0] + assert integration["next_action"] == "resolve CLA" + assert integration["checks"]["pending_check_runs"] == [ + { + "name": "license/cla", + "status": "pending", + "url": "https://cla-assistant.io/activepieces/activepieces?pullRequest=13985", + } + ] + + def test_format_integration_markdown_includes_update_age_and_next_action(): module = load_growth_metrics_module() metrics = {