Skip to content

Commit 91f0d9f

Browse files
committed
feat: aggiungi deploy status data-explorer a context
- GitHubCollector.get_latest_workflow_run() nuova API generica - DataExplorerFetcher.fetch_deploy_status() via GitHub Actions API - workspace_triage.json: explorer.last_deploy con run_id, conclusion, date - session_bootstrap.md: riga deploy con icona ✅/❌ e data Operativo, non strutturale — se API fallisce, last_deploy = null
1 parent 183bdd5 commit 91f0d9f

4 files changed

Lines changed: 90 additions & 3 deletions

File tree

src/agent_context_builder/github.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from __future__ import annotations
44

55
from dataclasses import dataclass
6-
from typing import Optional
6+
from typing import Any, Optional
77

88
from lab_connectors.http import HttpClient
99

@@ -187,6 +187,47 @@ def get_repos_info(self, repos: list[str]) -> dict[str, RepoInfo]:
187187
self.fetch_errors[f"{repo}:info"] = str(exc)
188188
return result_map
189189

190+
def get_latest_workflow_run(
191+
self, repo: str, event: str = "push", status: str = "completed"
192+
) -> dict[str, Any] | None:
193+
"""Fetch the latest workflow run for a repo.
194+
195+
Args:
196+
repo: Repository name (under self.org)
197+
event: Event type filter (e.g. push, workflow_dispatch)
198+
status: Status filter (e.g. completed, success)
199+
200+
Returns:
201+
Dict with run_id, name, status, conclusion, started_at, completed_at, html_url,
202+
or None if no runs found or on error.
203+
"""
204+
url = f"{self.base_url}/repos/{self.org}/{repo}/actions/runs"
205+
params = {
206+
"event": event,
207+
"status": status,
208+
"per_page": 1,
209+
}
210+
try:
211+
result = self._http.get(url, params=params, headers=self._headers())
212+
self._raise_on_bad_status(result, url)
213+
data = result.response.json() # type: ignore[union-attr]
214+
runs = data.get("workflow_runs", [])
215+
if not runs:
216+
return None
217+
run = runs[0]
218+
return {
219+
"run_id": run.get("id"),
220+
"name": run.get("name", ""),
221+
"status": run.get("status", ""),
222+
"conclusion": run.get("conclusion"),
223+
"started_at": run.get("run_started_at", ""),
224+
"completed_at": run.get("updated_at", ""),
225+
"html_url": run.get("html_url", ""),
226+
}
227+
except Exception as exc:
228+
self.fetch_errors[f"{repo}:workflow_runs"] = str(exc)
229+
return None
230+
190231
def _get_repo_issues(self, repo: str, state: str = "open") -> list[Issue]:
191232
"""Get issues for a specific repo (excluding pull requests).
192233

src/agent_context_builder/render.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,18 @@ def render_session_bootstrap(self) -> str:
171171
lines.append(f" · {slug}")
172172
if len(gap) > 5:
173173
lines.append(f" · ... e altri {len(gap) - 5}")
174+
175+
# Deploy status
176+
last_deploy = self._de_fetcher.fetch_deploy_status()
177+
if last_deploy is not None:
178+
conclusion = last_deploy.get("conclusion", "unknown")
179+
icon = "✅" if conclusion == "success" else "❌"
180+
completed = (last_deploy.get("completed_at", "")[:10]
181+
if last_deploy.get("completed_at") else "?")
182+
lines.append(f" **Deploy**: {icon} {conclusion} ({completed})")
183+
else:
184+
lines.append(f" **Deploy**: dati non disponibili")
185+
174186
lines.append("")
175187

176188
# ── OPEN ─────────────────────────────────────────────────────────

src/agent_context_builder/sources/de.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from __future__ import annotations
44

55
from dataclasses import dataclass
6+
from typing import Any
67

78
from ..github import GitHubCollector
89
from ..signals import ExplorerTheme, parse_explorer_themes
@@ -13,22 +14,28 @@ class DataExplorerData:
1314
"""Cached data-explorer artifact bundle."""
1415

1516
themes: list[ExplorerTheme] | None
17+
last_deploy: dict[str, Any] | None
1618

1719

1820
class DataExplorerFetcher:
19-
"""Fetch data-explorer artifacts from GitHub raw URLs.
21+
"""Fetch data-explorer artifacts from GitHub raw URLs + API.
2022
2123
Consumes:
2224
- catalog/themes.json (editorial theme assignments)
25+
- GitHub Actions API (deploy status, operativo)
2326
"""
2427

2528
def __init__(self, collector: GitHubCollector):
2629
self.collector = collector
2730
self._themes_cache: list[ExplorerTheme] | None | object = _UNSET
31+
self._deploy_cache: dict[str, Any] | None | object = _UNSET
2832

2933
def fetch(self) -> DataExplorerData:
3034
"""Fetch all data-explorer artifacts."""
31-
return DataExplorerData(themes=self.fetch_themes())
35+
return DataExplorerData(
36+
themes=self.fetch_themes(),
37+
last_deploy=self.fetch_deploy_status(),
38+
)
3239

3340
def fetch_themes(self) -> list[ExplorerTheme] | None:
3441
"""Fetch and parse catalog/themes.json from data-explorer.
@@ -49,6 +56,18 @@ def fetch_themes(self) -> list[ExplorerTheme] | None:
4956
self._themes_cache = result
5057
return result
5158

59+
def fetch_deploy_status(self) -> dict[str, Any] | None:
60+
"""Fetch latest deploy workflow run for data-explorer.
61+
62+
Returns a dict with run_id, name, status, conclusion, started_at,
63+
completed_at, html_url — or None if unavailable.
64+
"""
65+
if self._deploy_cache is not _UNSET:
66+
return self._deploy_cache # type: ignore[return-value]
67+
result = self.collector.get_latest_workflow_run("data-explorer")
68+
self._deploy_cache = result
69+
return result
70+
5271

5372
class _Unset:
5473
pass

src/agent_context_builder/triage.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ def _build_explorer_dict(
232232
233233
Cross-references data-explorer themes.json with DI clean_catalog.json
234234
to surface gap analysis (clean_ready datasets not yet on explorer).
235+
Includes last deploy status from GitHub Actions API.
235236
"""
236237
themes = de_fetcher.fetch_themes()
237238
if themes is None:
@@ -251,6 +252,19 @@ def _build_explorer_dict(
251252

252253
clean_ready_not_published = sorted(clean_ready_slugs - themed_slugs)
253254

255+
# Deploy status (operativo — GitHub Actions API)
256+
deploy: dict[str, Any] | None = None
257+
raw_deploy = de_fetcher.fetch_deploy_status()
258+
if raw_deploy is not None:
259+
deploy = {
260+
"run_id": raw_deploy.get("run_id"),
261+
"name": raw_deploy.get("name", ""),
262+
"status": raw_deploy.get("status", ""),
263+
"conclusion": raw_deploy.get("conclusion"),
264+
"completed_at": raw_deploy.get("completed_at", ""),
265+
"html_url": raw_deploy.get("html_url", ""),
266+
}
267+
254268
return {
255269
"available": True,
256270
"themes": [
@@ -259,6 +273,7 @@ def _build_explorer_dict(
259273
],
260274
"published_count": len(themed_slugs),
261275
"clean_ready_not_published": clean_ready_not_published,
276+
"last_deploy": deploy,
262277
}
263278

264279

0 commit comments

Comments
 (0)