CreaRack-SL

Widget CI del Health Endpoint: cobertura multi-repo y filtro event=push

Widget CI del Health Endpoint: cobertura multi-repo y filtro event=push

Contexto

El endpoint /api/health de Cloudflare Workers expone un widget CI Pipeline que agrega el estado de las GitHub Actions del ecosistema CreaRack. Antes de este cambio, la función checkCI consultaba únicamente el repositorio CreaRack-Pro y no filtraba por tipo de evento, lo que provocaba que dispatches manuales fallidos (p. ej. el workflow Audit Docs Drift) contaminasen el ratio mostrado.

Reporte que motivó el cambio (s78 / Edu, 2026-05-21):

“el ultimo CI esta todo en verde 6/6 pero el widget dice 4/5 con 1 fallida hace 27h”

Los 6 jobs verdes correspondían al commit 9572d5e9 (18-05) y la run fallida era un workflow_dispatch manual de Audit Docs Drift (19-05) — no una regresión real del pipeline.

Qué cambió

Antes

const res = await fetch(
  'https://api.github.com/repos/CreaRackSL/CreaRack-Pro/actions/runs?branch=main&per_page=5',
  ...
);
const runs = (data.workflow_runs || []).slice(0, 5);
  • Solo CreaRack-Pro.
  • Sin filtro de evento → workflow_dispatch y schedule incluidos.
  • Máximo 5 runs.

Ahora

const CI_REPOS = ['CreaRackSL/CreaRack-Pro', 'CreaRackSL/CreaRackSL-workspace'];

const fetched = await Promise.all(
  CI_REPOS.map((repo) =>
    fetch(`…/repos/${repo}/actions/runs?branch=main&event=push&per_page=5`, ...)
  )
);
const runs = fetched
  .flatMap((r) => r.runs)
  .sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
  • Dos repos en paralelo: CreaRack-Pro + CreaRackSL-workspace.
    (El repo claude-method queda fuera: no tiene workflows propios.)
  • Filtro event=push: solo CI disparado por commits reales. Dispatches manuales y crons no computan.
  • Hasta 10 runs agregadas (5 por repo), ordenadas por fecha DESC.
  • El campo "ultima" refleja el push más reciente entre ambos repos.

Lógica de color / insight resultante

Estado última runColorInsight
conclusion === 'success'🟢 GREENTodos los push runs verdes en Pro + workspace
conclusion === 'failure'🔴 REDÚltima run falló — revisar <nombre>
status in_progress / queued🟡 YELLOW(runs en curso)
Error API en algún repo⬜ DIMGitHub API <status> — alguno de los repos falló
Sin runs⬜ DIMNo hay ejecuciones de Actions en main de Pro+workspace

Decisiones de diseño

  1. Promise.all en lugar de secuencial: las dos llamadas a la API de GitHub corren en paralelo; el timeout de 5 s aplica por fetch individual.
  2. Error parcial: si solo uno de los repos falla, el widget devuelve error global (allOk = fetched.every(r => r.ok)). Se opta por visibilidad explícita antes que silenciar el fallo de un repo.
  3. claude-method excluido: no tiene workflows Actions propios; añadirlo solo agregaría 0 runs y aumentaría la latencia.
  4. per_page=5 por repo: límite conservador para no saturar el presupuesto de token-rate de la GitHub API desde el Worker.

Archivos afectados

ArchivoTipo de cambio
functions/api/health.tsRefactor + feature — checkCI, nueva constante CI_REPOS

Véase también

  • [[entity—workers—service—health-endpoint]]
  • [[concept—infra—ci-pipeline]]
  • [[feature—infra—health-dashboard]]