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:
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.¶
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ó:
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:
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.