chore: import upstream snapshot with attribution
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
CI / coverage-report (push) Has been cancelled
CI / test-kubernetes (push) Has been cancelled
CI / should-run-thorough (push) Has been cancelled
CI / test-thorough (cloudwatch-demo) (push) Has been cancelled
CI / test-thorough (flink-ecs) (push) Has been cancelled
CI / test-thorough (upstream-lambda) (push) Has been cancelled
CI / test-thorough (prefect-ecs-fargate) (push) Has been cancelled
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Has been cancelled
Benchmark image — build + push to ECR (any adapter) / build + push (push) Has been cancelled
CI / quality (ubuntu-latest) (push) Has been cancelled
CI / test (tools-runtime) (push) Has been cancelled
CI / test (e2e-general) (push) Has been cancelled
CI / test (cli-runtime) (push) Has been cancelled
CI / test (e2e-provider-and-openclaw) (push) Has been cancelled
CI / test (integrations-and-misc) (push) Has been cancelled
Release / verify (push) Has been cancelled
Release / build-python-dist (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Has been cancelled
Release / publish-release (push) Has been cancelled
Release / publish-main-release (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Has been cancelled
Release / prepare (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Has been cancelled
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Has been cancelled
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
CI / coverage-report (push) Has been cancelled
CI / test-kubernetes (push) Has been cancelled
CI / should-run-thorough (push) Has been cancelled
CI / test-thorough (cloudwatch-demo) (push) Has been cancelled
CI / test-thorough (flink-ecs) (push) Has been cancelled
CI / test-thorough (upstream-lambda) (push) Has been cancelled
CI / test-thorough (prefect-ecs-fargate) (push) Has been cancelled
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Has been cancelled
Benchmark image — build + push to ECR (any adapter) / build + push (push) Has been cancelled
CI / quality (ubuntu-latest) (push) Has been cancelled
CI / test (tools-runtime) (push) Has been cancelled
CI / test (e2e-general) (push) Has been cancelled
CI / test (cli-runtime) (push) Has been cancelled
CI / test (e2e-provider-and-openclaw) (push) Has been cancelled
CI / test (integrations-and-misc) (push) Has been cancelled
Release / verify (push) Has been cancelled
Release / build-python-dist (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Has been cancelled
Release / publish-release (push) Has been cancelled
Release / publish-main-release (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Has been cancelled
Release / prepare (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Has been cancelled
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
"""Report composition helpers for GitHub workflow tools."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Sequence
|
||||
from typing import Any
|
||||
|
||||
from integrations.github.tools.workflow.models import PullRequestStatus, WorkItem, WorkStatusReport
|
||||
|
||||
|
||||
def _as_dict(item: WorkItem | PullRequestStatus | dict[str, Any]) -> dict[str, Any]:
|
||||
if isinstance(item, WorkItem | PullRequestStatus):
|
||||
return item.to_dict()
|
||||
return item
|
||||
|
||||
|
||||
def _item_line(item: dict[str, Any]) -> str:
|
||||
assignees = item.get("assignees") or []
|
||||
owner = f" — @{', @'.join(assignees)}" if assignees else ""
|
||||
return f"• #{item.get('number', '?')} {item.get('title', '')}{owner}"
|
||||
|
||||
|
||||
def _pr_line(pr: dict[str, Any]) -> str:
|
||||
reasons = pr.get("blocking_reasons") or []
|
||||
reason_text = f" — {', '.join(str(reason) for reason in reasons)}" if reasons else ""
|
||||
return f"• PR #{pr.get('number', '?')} {pr.get('title', '')}{reason_text}"
|
||||
|
||||
|
||||
def _recommended_actions(
|
||||
*,
|
||||
up_for_grabs: list[dict[str, Any]],
|
||||
unassigned: list[dict[str, Any]],
|
||||
blocked_prs: list[dict[str, Any]],
|
||||
mergeable_prs: list[dict[str, Any]],
|
||||
errors: list[str],
|
||||
) -> list[str]:
|
||||
actions: list[str] = []
|
||||
if errors:
|
||||
actions.append("• Re-run failed GitHub reads before trusting this status report.")
|
||||
if blocked_prs:
|
||||
actions.append(f"• Unblock {len(blocked_prs)} PR(s) before starting new work.")
|
||||
if mergeable_prs:
|
||||
actions.append(f"• Review or merge {len(mergeable_prs)} ready PR(s).")
|
||||
if up_for_grabs:
|
||||
actions.append(f"• Assign {len(up_for_grabs)} up-for-grabs task(s).")
|
||||
if unassigned:
|
||||
actions.append(f"• Triage {len(unassigned)} unassigned issue(s).")
|
||||
if not actions:
|
||||
actions.append("• No obvious blockers from the supplied data.")
|
||||
return actions
|
||||
|
||||
|
||||
def build_work_status_report(
|
||||
*,
|
||||
work_items: Sequence[WorkItem | dict[str, Any]],
|
||||
pull_requests: Sequence[PullRequestStatus | dict[str, Any]],
|
||||
context: str = "today",
|
||||
errors: list[str] | None = None,
|
||||
) -> WorkStatusReport:
|
||||
"""Build a Slack-ready report from an already-read GitHub snapshot."""
|
||||
|
||||
errors = list(errors or [])
|
||||
item_dicts = [_as_dict(item) for item in work_items]
|
||||
pr_dicts = [_as_dict(pr) for pr in pull_requests]
|
||||
up_for_grabs = [item for item in item_dicts if item.get("work_status") == "up_for_grabs"]
|
||||
unassigned = [item for item in item_dicts if item.get("work_status") == "unassigned"]
|
||||
taken = [item for item in item_dicts if item.get("work_status") == "taken"]
|
||||
blocked_prs = [pr for pr in pr_dicts if pr.get("status") == "blocked"]
|
||||
mergeable_prs = [pr for pr in pr_dicts if pr.get("status") == "mergeable"]
|
||||
unknown_prs = [pr for pr in pr_dicts if pr.get("status") == "unknown"]
|
||||
|
||||
sections = [f"*Engineering status — {context}*", ""]
|
||||
if errors:
|
||||
sections.extend(["*Incomplete report:*", *[f"• {error}" for error in errors], ""])
|
||||
sections.append(
|
||||
f"*Open work:* {len(item_dicts)} total ({len(taken)} taken, "
|
||||
f"{len(up_for_grabs)} up for grabs, {len(unassigned)} unassigned)"
|
||||
)
|
||||
if up_for_grabs:
|
||||
sections.extend(["", "*Up for grabs:*", *[_item_line(item) for item in up_for_grabs[:10]]])
|
||||
if unassigned:
|
||||
sections.extend(["", "*Unassigned:*", *[_item_line(item) for item in unassigned[:10]]])
|
||||
if blocked_prs:
|
||||
sections.extend(["", "*Blocked PRs:*", *[_pr_line(pr) for pr in blocked_prs[:10]]])
|
||||
if unknown_prs:
|
||||
sections.extend(["", "*Unknown PR status:*", *[_pr_line(pr) for pr in unknown_prs[:10]]])
|
||||
if mergeable_prs:
|
||||
sections.extend(["", "*Ready to merge:*", *[_pr_line(pr) for pr in mergeable_prs[:10]]])
|
||||
sections.extend(
|
||||
[
|
||||
"",
|
||||
"*Recommended next actions:*",
|
||||
*_recommended_actions(
|
||||
up_for_grabs=up_for_grabs,
|
||||
unassigned=unassigned,
|
||||
blocked_prs=blocked_prs,
|
||||
mergeable_prs=mergeable_prs,
|
||||
errors=errors,
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
return WorkStatusReport(
|
||||
counts={
|
||||
"open_work": len(item_dicts),
|
||||
"taken": len(taken),
|
||||
"up_for_grabs": len(up_for_grabs),
|
||||
"unassigned": len(unassigned),
|
||||
"blocked_prs": len(blocked_prs),
|
||||
"mergeable_prs": len(mergeable_prs),
|
||||
"unknown_prs": len(unknown_prs),
|
||||
},
|
||||
slack_markdown="\n".join(sections).strip(),
|
||||
available=not errors,
|
||||
incomplete=bool(errors),
|
||||
errors=errors,
|
||||
)
|
||||
Reference in New Issue
Block a user