feat(automation): weekly Forgejo package prune shell resolver (WP-0020)
Some checks are pending
CI Smoke / host-smoke (push) Waiting to run
CI Smoke / container-smoke (push) Waiting to run
Build and Publish Container Image / build-and-push (push) Successful in 35s

Add forgejo_package_prune query, weekly activity-definition (disabled),
State Hub evidence sink support for shell sources, and runbook notes.
This commit is contained in:
tegwick 2026-07-12 11:35:04 +02:00
parent a853cd3118
commit 5b6d9f4e95
7 changed files with 176 additions and 7 deletions

View file

@ -0,0 +1,62 @@
"""Forgejo package retention prune shell context query."""
from __future__ import annotations
import json
import logging
import os
import subprocess
from pathlib import Path
from typing import Any
logger = logging.getLogger(__name__)
_DEFAULT_SCRIPT = Path.home() / "railiance-platform" / "tools/cmd/forgejo-package-prune"
_DEFAULT_TIMEOUT_SECONDS = 900
def forgejo_package_prune(params: dict[str, Any]) -> dict[str, Any]:
"""Run the platform prune script and return its JSON summary."""
script = Path(str(params.get("prune_script", _DEFAULT_SCRIPT))).expanduser()
if not script.is_file():
raise FileNotFoundError(f"forgejo_package_prune script not found: {script}")
max_versions = int(params.get("max_versions", 3))
apply = bool(params.get("apply", False))
timeout = float(params.get("timeout_seconds", _DEFAULT_TIMEOUT_SECONDS))
cmd = [str(script), f"--max-versions={max_versions}"]
if apply:
cmd.append("--apply")
env = os.environ.copy()
completed = subprocess.run(
cmd,
capture_output=True,
text=True,
timeout=timeout,
check=False,
env=env,
)
stdout = (completed.stdout or "").strip()
if completed.returncode != 0 and not stdout:
stderr = (completed.stderr or "").strip()
snippet = stderr[:500]
raise RuntimeError(
f"forgejo_package_prune failed (exit {completed.returncode}): {snippet}"
)
try:
summary = json.loads(stdout)
except json.JSONDecodeError as exc:
stderr = (completed.stderr or "").strip()
raise RuntimeError(
f"forgejo_package_prune returned invalid JSON: {exc}; stderr={stderr[:300]}"
) from exc
if completed.returncode != 0:
summary.setdefault("errors", []).append(
f"script_exit_code:{completed.returncode}"
)
summary["kind"] = "forgejo_package_prune"
return summary

View file

@ -21,6 +21,7 @@ import httpx
import yaml
from activity_core.context_resolvers.base import CONTEXT_RESOLVER_REGISTRY, ContextResolver
from activity_core.context_resolvers.forgejo_prune import forgejo_package_prune
from activity_core.context_resolvers.kaizen import KaizenContextResolver
from activity_core.context_resolvers.state_hub import StateHubContextResolver
@ -509,6 +510,8 @@ class ShellContextResolver(ContextResolver):
def resolve(self, query: str, event: Any, params: dict[str, Any]) -> dict[str, Any]:
if query == "reuse_surface_report_gaps":
return reuse_surface_report_gaps(params)
if query == "forgejo_package_prune":
return forgejo_package_prune(params)
return KaizenContextResolver().resolve(query, event, params)