fix(cli): add Impact and History panels to action archive output
CI / benchmark-publish (pull_request) Has been skipped
CI / helm (pull_request) Successful in 32s
CI / build (pull_request) Successful in 52s
CI / lint (pull_request) Successful in 1m3s
CI / quality (pull_request) Successful in 1m11s
CI / typecheck (pull_request) Successful in 1m23s
CI / security (pull_request) Successful in 1m48s
CI / push-validation (pull_request) Successful in 22s
CI / e2e_tests (pull_request) Successful in 3m36s
CI / integration_tests (pull_request) Successful in 3m44s
CI / unit_tests (pull_request) Successful in 4m54s
CI / docker (pull_request) Successful in 1m50s
CI / coverage (pull_request) Successful in 11m1s
CI / status-check (pull_request) Successful in 3s

- Add _get_action_history() helper to gather plan statistics
- Add _render_archive_panels() to render three panels: Action Archived, Impact, History
- Update archive() command to call _render_archive_panels() for rich format
- Include impact and history data in non-rich output formats (json, yaml, plain)
- Panels show action name, state transition, archived timestamp, impact on plans, and usage history
This commit is contained in:
2026-04-14 09:49:13 +00:00
committed by Forgejo
parent 9888c2f6e6
commit 7ca1571d73
+122 -1
View File
@@ -203,6 +203,112 @@ def _print_action(
console.print(Panel(details, title=title, expand=False))
def _get_action_history(
service: PlanLifecycleService, action_name: str
) -> dict[str, object]:
"""Get action history statistics from plans using this action.
Returns a dict with:
- total_plans: Total number of plans created from this action
- completed: Number of completed plans
- failed: Number of failed plans
- last_used: ISO-8601 timestamp of last plan creation, or None
"""
try:
plans = service.list_plans()
action_plans = [p for p in plans if str(p.action_name) == action_name]
total = len(action_plans)
completed = sum(
1
for p in action_plans
if p.processing_state and p.processing_state.value == "applied"
)
failed = sum(
1
for p in action_plans
if p.processing_state and p.processing_state.value == "errored"
)
last_used = None
if action_plans:
last_used = max(
(p.timestamps.created_at for p in action_plans),
default=None,
)
return {
"total_plans": total,
"completed": completed,
"failed": failed,
"last_used": last_used.strftime("%Y-%m-%d") if last_used else None,
}
except Exception:
# If we can't get history, return zeros
return {
"total_plans": 0,
"completed": 0,
"failed": 0,
"last_used": None,
}
def _render_archive_panels(action: Action, history: dict[str, object]) -> None:
"""Render the three archive output panels: Action Archived, Impact, History.
Args:
action: The archived action
history: History statistics dict from _get_action_history
"""
# Panel 1: Action Archived
action_panel_content = (
f"[cyan]Name:[/cyan] {action.namespaced_name}\n"
f"[yellow]State:[/yellow] available -> archived\n"
f"[green]Archived:[/green] {action.updated_at.strftime('%Y-%m-%d %H:%M')}"
)
action_panel = Panel(
action_panel_content,
title="Action Archived",
expand=False,
)
console.print(action_panel)
# Panel 2: Impact
impact_panel_content = (
"[yellow]Availability:[/yellow] hidden from list\n"
"[blue]Existing Plans:[/blue] unchanged\n"
"[blue]Active Plans:[/blue] 0 affected"
)
impact_panel = Panel(
impact_panel_content,
title="Impact",
expand=False,
)
console.print(impact_panel)
# Panel 3: History
total_plans = history.get("total_plans", 0)
completed = history.get("completed", 0)
failed = history.get("failed", 0)
last_used = history.get("last_used")
history_panel_content = (
f"[blue]Total Plans:[/blue] {total_plans}\n"
f"[green]Completed:[/green] {completed}\n"
f"[red]Failed:[/red] {failed}\n"
f"[blue]Last Used:[/blue] {last_used or 'Never'}"
)
history_panel = Panel(
history_panel_content,
title="History",
expand=False,
)
console.print(history_panel)
# Final confirmation message
console.print("[green]✓ OK[/green] Action archived")
@app.command()
def create(
config: Annotated[
@@ -456,10 +562,25 @@ def archive(
if fmt != OutputFormat.RICH.value:
data = _action_spec_dict(action)
data["archived"] = True
# Add impact and history to non-rich output
data["impact"] = {
"availability": "hidden from list",
"existing_plans": "unchanged",
"active_plans_affected": 0,
}
history = _get_action_history(service, str(action.namespaced_name))
data["history"] = {
"total_plans": history.get("total_plans", 0),
"completed": history.get("completed", 0),
"failed": history.get("failed", 0),
"last_used": history.get("last_used"),
}
console.print(format_output(data, fmt))
return
console.print(f"[green]✓[/green] Action archived: {action.namespaced_name}")
# Rich format: render panels
history = _get_action_history(service, str(action.namespaced_name))
_render_archive_panels(action, history)
except NotFoundError as e:
console.print(f"[red]Action not found:[/red] {name}")