Saltar a contenido

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

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:

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.