Add todo_md_staleness State Hub context resolver
Supports daily TODO.md stale-review ActivityDefinition via GET /repos/todo-md-staleness.
This commit is contained in:
parent
20f8b2f31f
commit
00917696dd
2 changed files with 71 additions and 0 deletions
|
|
@ -100,6 +100,8 @@ class StateHubContextResolver(ContextResolver):
|
|||
return _fetch_json(f"/state/domain/{domain}")
|
||||
if query == "repo_sbom_status":
|
||||
return _repo_sbom_status(params)
|
||||
if query == "todo_md_staleness":
|
||||
return _todo_md_staleness(params)
|
||||
if query == "state_summary":
|
||||
return _fetch_json("/state/summary")
|
||||
if query == "next_steps":
|
||||
|
|
@ -374,6 +376,26 @@ def _repo_sbom_status(params: dict[str, Any]) -> dict[str, Any]:
|
|||
return {}
|
||||
|
||||
|
||||
def _todo_md_staleness(params: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Resolve TODO.md staleness from State Hub.
|
||||
|
||||
Bulk mode (default): GET /repos/todo-md-staleness?stale_days=N
|
||||
Returns stale repos under `repos` plus summary fields for rule matching.
|
||||
"""
|
||||
stale_days = params.get("stale_days", 6)
|
||||
try:
|
||||
stale_days = int(stale_days)
|
||||
except (TypeError, ValueError):
|
||||
stale_days = 6
|
||||
payload = _fetch_json("/repos/todo-md-staleness", {"stale_days": stale_days})
|
||||
if not isinstance(payload, dict) or not payload:
|
||||
return {}
|
||||
repos = payload.get("repos")
|
||||
if not isinstance(repos, list):
|
||||
return {}
|
||||
return payload
|
||||
|
||||
|
||||
def _sbom_status_entry(repo_slug: str, last_sbom_at: Any) -> dict[str, Any]:
|
||||
age_days, has_sbom, normalised = _sbom_age_days(last_sbom_at)
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -192,6 +192,55 @@ def test_repo_sbom_status_bulk_returns_worst_repo(monkeypatch) -> None:
|
|||
assert by_slug["never-scanned"]["last_sbom_at"] is None
|
||||
|
||||
|
||||
def test_todo_md_staleness_returns_stale_repos(monkeypatch) -> None:
|
||||
calls: list[dict[str, Any]] = []
|
||||
|
||||
def fake_get(url: str, **kwargs: Any) -> DummyResponse:
|
||||
calls.append({"url": url, **kwargs})
|
||||
return DummyResponse({
|
||||
"stale_days": 6,
|
||||
"repos": [
|
||||
{
|
||||
"repo_slug": "markitect-main",
|
||||
"has_todo": True,
|
||||
"age_days": 12,
|
||||
"mtime": "2026-06-26T10:00:00+00:00",
|
||||
"todo_path": "/home/worsch/markitect-main/TODO.md",
|
||||
}
|
||||
],
|
||||
"stale_count": 1,
|
||||
"total_with_todo": 1,
|
||||
"total_scanned": 62,
|
||||
"worst_repo_slug": "markitect-main",
|
||||
"worst_age_days": 12,
|
||||
})
|
||||
|
||||
monkeypatch.setenv("STATE_HUB_URL", "http://state-hub.test")
|
||||
monkeypatch.setattr(httpx, "get", fake_get)
|
||||
|
||||
result = StateHubContextResolver().resolve(
|
||||
"todo_md_staleness", None, {"stale_days": 6}
|
||||
)
|
||||
|
||||
assert calls == [{
|
||||
"url": "http://state-hub.test/repos/todo-md-staleness",
|
||||
"params": {"stale_days": 6},
|
||||
"timeout": 10.0,
|
||||
}]
|
||||
assert result["stale_count"] == 1
|
||||
assert result["repos"][0]["repo_slug"] == "markitect-main"
|
||||
|
||||
|
||||
def test_todo_md_staleness_returns_empty_on_failure(monkeypatch) -> None:
|
||||
def fake_get(url: str, **kwargs: Any) -> DummyResponse:
|
||||
return DummyResponse(None, status_error=httpx.HTTPError("boom"))
|
||||
|
||||
monkeypatch.setenv("STATE_HUB_URL", "http://state-hub.test")
|
||||
monkeypatch.setattr(httpx, "get", fake_get)
|
||||
|
||||
assert StateHubContextResolver().resolve("todo_md_staleness", None, {}) == {}
|
||||
|
||||
|
||||
def test_repo_sbom_status_returns_empty_on_failure(monkeypatch) -> None:
|
||||
def fake_get(url: str, **kwargs: Any) -> DummyResponse:
|
||||
return DummyResponse(None, status_error=httpx.HTTPError("boom"))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue