--- name: gitea-releases-monitor id: 0004 status: pending created: 2026-05-16 updated: 2026-05-16 priority: medium risk: low related_issues: [] apps: - registry_api - data_factory - agents_and_robots trigger: webhook schedule: "" expected_runtime_s: 5 tags: [git, webhook, multi-repo, monitoring] --- ## Goal Probar webhooks como trigger (no cron, no manual). Cada push a un repo `dataforge/*` registra commit en data_factory + notifica via Matrix bot. Demuestra reactividad event-driven. ## Pre-requisitos - `gitea_create_webhook_bash_infra` disponible. - Servidor HTTP receptor (reusar `registry_api` o `deploy_server`). - Bot Matrix en sala `#fn-registry-releases`. - GITEA_TOKEN en `pass registry/api-token`. ## Flow 1. Crear endpoint receptor `POST /webhook/gitea` en una app (probable: nueva mini-app `gitea_webhook_listener` o anadir a `deploy_server`). 2. Iterar repos `dataforge/` (35 apps + analyses). Instalar webhook en cada uno apuntando al receptor: ```bash for app in $(ls apps/); do gitea_create_webhook "dataforge" "$app" "http:///webhook/gitea" "$secret" done ``` 3. Receptor parsea payload Gitea (event `push`): `{ref, commits: [{id, message, author, url}]}`. 4. INSERT en `data_factory.runs` con `node_id='gitea_push_'` (upsert node si no existe). 5. Notifica Matrix: ``` [] : ``` 6. dag_engine recibe trigger `api` con info del run. 7. data_factory tab Extractors muestra `gitea_push_` por cada repo con activity. ## Acceptance - [ ] Webhook instalado en >=3 repos. - [ ] Push de prueba dispara recepcion + entry en `data_factory.runs`. - [ ] Matrix recibe mensaje formateado. - [ ] data_factory muestra nodos `gitea_push_` con last_run reciente. - [ ] Receptor maneja fallos (timeout, payload invalido) sin crash. ## Telemetria esperada - `data_factory.runs` con `trigger='api'`. - Por repo: 1 nodo extractor. - Matrix: 1 msg por push. ## Definition of Done Ver `README.md` seccion DoD + user-facing. ### Generico - [ ] **Repetibilidad**: 3 pushes test distintos disparan 3 mensajes Matrix sin intervencion. - [ ] **Observabilidad**: `data_factory.runs` con `trigger=webhook` + `call_monitor.calls` chain por push. - [ ] **Error-path**: payload invalido → 4xx + entry en log + NO crash receptor. - [ ] **Idempotencia**: recepcion duplicada (Gitea retry) → 1 mensaje, no N. - [ ] **Secrets**: webhook secret en `pass gitea/webhook-secret`; HMAC verificado por receptor. - [ ] **Docs**: `## Notas` con setup webhook + onboarding. - [ ] **Registry-first**: receptor reusa `http_post_json_*` + `matrix_send_message_*`. - [ ] **INDEX + status**: `status: done` + INDEX + movido. ### User-facing - [ ] **User-facing**: usuario lee mensaje en sala Matrix `#fn-registry-news` con formato `[] pushed commits to ` + link al commit. - [ ] **User-facing repeat**: cada push real a `dataforge/*` dispara mensaje; sala es la fuente diaria de actividad multi-repo. - [ ] **User-facing onboarding**: parrafo en `## Notas`: "Para enterarse de pushes: unirse a sala Matrix `#fn-registry-news`. Para anadir un repo nuevo: `gitea_create_webhook_bash_infra `." - [ ] **User-facing latencia**: push → mensaje en <5s p95. ### Custom - [ ] >=3 repos cubiertos (no solo 1). - [ ] Rate-limit: max 1 mensaje/repo/minuto (no flood si N pushes seguidos). - [ ] Health endpoint `/webhook/health` retorna 200 + lista repos suscritos. ## Notas - Webhook secret debe estar en `pass gitea/webhook-secret` o env var. - Si el receptor se cae, los pushes se pierden (no hay queue). Mejora futura: redis/sqlite queue. - Cuidado con loops: commits que GENERA el bot pueden disparar webhooks.