# Incidente: anchors YAML no soportados por Gitea Actions — y un diagnóstico equivocado en el camino (2026-08) | | | |---|---| | **Ventana del incidente** | 2026-08-15, desde el primer commit que agregó Gitleaks a `build.yaml` | | **Servicio afectado** | Gitea Actions — el workflow `build.yaml` (frontend) | | **Impacto** | `build.yaml` no generaba **ningún** `action_run`, ni en `push` ni en `pull_request` — el pipeline entero era invisible para Gitea, sin ningún error visible en la UI | ## Qué es un anchor/alias YAML, para quien no lo conoce YAML tiene una forma de evitar repetir el mismo bloque dos veces: ```yaml paths: &frontend_paths - 'workloads/ecommerce/**' - '.gitea/workflows/build.yaml' on: push: paths: *frontend_paths pull_request: paths: *frontend_paths ``` `&frontend_paths` es un **anchor** (marca ese nodo con un nombre). `*frontend_paths` es un **alias** (dice "poné acá una copia de lo que marcó ese anchor"). Es YAML 100% estándar — cualquier parser que siga la especificación lo resuelve sin problema, y es una forma común de no duplicar listas idénticas en el mismo archivo. ## Síntoma `build.yaml` (con Gitleaks recién agregado, usando anchors para no repetir la lista de `paths` entre `push:` y `pull_request:`) no generaba ningún run en Gitea Actions. Ni en el push directo a la rama del PR, ni al abrir el pull request. Sin mensaje de error visible en la UI de Gitea — el workflow simplemente no aparecía en la lista de Actions, como si no existiera. ## Primer diagnóstico (equivocado) La primera sospecha fue una indentación rota específicamente en el step de Semgrep: el bloque `python3 -c "..."` embebido dentro de un `run: |` tenía código pegado a columna 0, por debajo de la indentación esperada del block scalar de YAML. Eso *sí* era un problema real — cortaba el block scalar ahí mismo y en teoría podía hacer que Gitea rechazara el archivo con un error de parseo genérico (`could not find expected ':'`). Se corrigió la indentación, se validó con un parser YAML real y `bash -n` sobre los 20 steps del archivo, se mergeó a `main` como fix (`fix(ci): corregir indentación YAML rota en el step de Semgrep`, PR #19)... y `build.yaml` **siguió sin generar runs**. !!! warning "Por qué vale la pena contar el diagnóstico que no era" El primer fix no estaba mal — la indentación efectivamente estaba rota y corregirla era necesario. El error fue asumir que esa era *la única* causa sin confirmarlo con una corrida real después del fix. La lección de proceso: un fix que "tiene sentido" y que pasa la validación local (parser YAML, `bash -n`) todavía necesita una confirmación en vivo contra el sistema real antes de darlo por cerrado — sobre todo cuando el síntoma es "no pasa nada" en vez de un error explícito, que es exactamente el tipo de fallo más fácil de dar por resuelto sin verificar. ## Causa raíz real `deploy-docs.yaml` (sin anchors) corría normal. `build.yaml` (con anchors, agregados junto con Gitleaks) no generaba ningún run — ni en `push` ni en `pull_request`, desde el primer commit que los introdujo. El log del propio Gitea lo confirmó: ```text unknown on type: &yaml.Node{...Value:"frontend_paths"...} ``` El parser propio de Gitea Actions para el bloque `on:` de un workflow **no resuelve `&anchor`/`*alias` antes de inspeccionar el tipo de nodo** — encuentra un anchor donde esperaba un valor ya resuelto, no sabe qué tipo de dato es, y descarta el archivo completo en silencio. `pyyaml` y cualquier parser YAML estándar sí resuelven el alias primero (por eso el archivo "parseaba bien" en cualquier herramienta de validación genérica) — es una limitación específica del parser de workflows de Gitea Actions, no un YAML inválido. Esto explica por qué el síntoma no tenía ningún error visible: no es que el job fallara, es que **Gitea nunca llegaba a registrar el workflow como existente**. ## Fix aplicado Se eliminaron los anchors/alias. Las dos listas de `paths` (una para `push:`, otra para `pull_request:`) quedan **duplicadas literalmente**, sin referencia compartida: ```yaml on: push: branches: [main] paths: - 'workloads/ecommerce/**' - '.gitea/workflows/build.yaml' pull_request: branches: [main] paths: - 'workloads/ecommerce/**' - '.gitea/workflows/build.yaml' ``` Es más repetitivo, pero es el precio de que el parser de Gitea Actions lo entienda. Este mismo criterio (sin anchors, paths duplicados) se replicó a propósito en `build-medusa.yaml` y `deploy-docs.yaml` al agregarles el resto del pipeline de seguridad, para no repetir el mismo problema. ## Validación Confirmado en vivo: tras mergear el fix, `build.yaml` generó su primer `action_run` real. Validado también con un parser YAML + `bash -n` sobre los 20 steps del archivo, igual que en el intento anterior — la diferencia esta vez fue confirmarlo contra una corrida real antes de cerrar el incidente.