# Del commit al despliegue: flujo GitOps

> **TODO (fase 2+):** narrar cada paso con ejemplos reales tomados de
> `.gitea/workflows/build-medusa.yaml` y `build.yaml`. El diagrama de
> secuencia de abajo refleja el pipeline real (build → push imagen →
> promoción segura → commit del tag → sync de Argo CD).

## Secuencia: un commit hasta quedar corriendo en el cluster

```mermaid
sequenceDiagram
    actor Dev as Devops
    participant Gitea
    participant CI as Gitea Actions
    participant Reg as Gitea Registry
    participant Argo as Argo CD
    participant K8s as Cluster k3d

    Dev->>Gitea: push a fix/<rama>
    Dev->>Gitea: abre PR → main
    Gitea->>Gitea: merge a main
    Gitea->>CI: dispara workflow (paths: workloads/**)
    CI->>CI: build de la imagen (Docker)
    CI->>Reg: push imagen vX.Y.Z
    CI->>CI: verifica promoción segura (HEAD == origin/main)
    CI->>Gitea: commit "chore(gitops): release vX.Y.Z" actualizando el manifiesto
    Argo->>Gitea: detecta el nuevo commit (poll/webhook)
    Argo->>K8s: sync (prune:true, selfHeal:true)
    K8s->>K8s: rollout del nuevo pod
```

## Por qué esta separación (build vs. deploy)

- El **pipeline de CI** solo construye y publica la imagen — nunca
  aplica nada directo al cluster.
- El **commit al manifiesto** (`sed` sobre el tag de imagen) es lo único
  que representa "intención de desplegar" — y vive en el mismo repo Git
  que Argo CD vigila.
- **Argo CD** es la única pieza con permisos de escritura sobre el
  cluster real. Nada fuera de GitOps toca `kubectl apply` en producción.
- El paso de "promoción segura" (comparar `HEAD` contra `origin/main`)
  evita que un pipeline viejo sobreescriba el tag con una versión
  anterior si hubo un push más reciente mientras corría.

## TODO

- Ejemplo real con hashes de commit (tomar del historial de
  `apps-registry`).
- Explicar `syncPolicy.automated.selfHeal` con un caso concreto (qué
  pasa si alguien hace `kubectl edit` a mano).
