# 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.
