diff --git a/docs/playbooks/gitops-commit-workflow.md b/docs/playbooks/gitops-commit-workflow.md new file mode 100644 index 0000000..1e16f91 --- /dev/null +++ b/docs/playbooks/gitops-commit-workflow.md @@ -0,0 +1,154 @@ +# Playbook: fix de inconsistencia y flujo de commit en repos GitOps + +Reconstruido a partir del fix real ejecutado el 2026-08-09 en `apps-registry` +sobre `repoURL` (http vs https). Úsalo como referencia reproducible para +cualquier fix similar (inconsistencias de configuración, typos en manifiestos, +etc.) en `apps-registry`, `platform-infra` o `scripts`. + +## Caso real de referencia + +- Repo: `devops/apps-registry` +- Síntoma: `apps/ecommerce-app.yaml` apuntaba a `repoURL: http://gitea.cruzcloud.net/...` + mientras que `application.yaml` (raíz, App of Apps) usaba `https://`. + Argo CD trataba ambos como fuentes distintas por el esquema, generando + drift/ambigüedad en el App of Apps. +- Rama: `fix/repo-url-consistency` +- Commit: `a90c0a7` — `fix(gitops): usar https en repoURL de ecommerce-app para consistencia con application.yaml` +- PR: [#1 — fix(gitops): unificar repoURL a https en ecommerce-app](http://gitea.cruzcloud.net/devops/apps-registry/pulls/1) + +## 1. Detectar la inconsistencia + +Antes de tocar nada, confirma el alcance real del problema comparando el +`repoURL` de la Application raíz contra todas las Applications hijas: + +```bash +grep -rn "repoURL" application.yaml apps/ +``` + +En este caso mostró la mezcla `http://` / `https://` sobre el mismo host +(`gitea.cruzcloud.net`), lo que confirmó que era un problema de consistencia +y no de configuración intencional por app. + +## 2. Crear la rama de fix + +Nunca se edita ni se commitea directo sobre `main` (regla del repo). Se parte +siempre de `main` actualizado: + +```bash +git checkout main +git pull origin main +git checkout -b fix/repo-url-consistency +``` + +## 3. Aplicar el cambio y commitear + +Edita solo el/los archivo(s) afectado(s) — cambio mínimo, sin tocar nada más: + +```yaml +# apps/ecommerce-app.yaml +spec: + source: +- repoURL: http://gitea.cruzcloud.net/devops/apps-registry.git ++ repoURL: https://gitea.cruzcloud.net/devops/apps-registry.git +``` + +```bash +git add apps/ecommerce-app.yaml +git commit -m "fix(gitops): usar https en repoURL de ecommerce-app para consistencia con application.yaml" +``` + +## 4. Intento de push por SSH (falló) y por qué + +El primer intento fue generar clave SSH y cambiar el remote para pushear por +SSH: + +```bash +ssh-keygen -t ed25519 -C "cristiancruz0529@gmail.com" -f ~/.ssh/id_ed25519 +git remote set-url origin git@gitea.cruzcloud.net:devops/apps-registry.git +git push -u origin fix/repo-url-consistency +``` + +**Resultado:** timeout/conexión rechazada en el puerto 22. Causa raíz: +`gitea.cruzcloud.net` está detrás de **Cloudflare en modo proxy (nube +naranja)**, que solo reenvía tráfico HTTP/HTTPS (80/443). El puerto 22 (SSH) +no está expuesto a través del proxy, así que cualquier clon/push por SSH +contra ese hostname fallará mientras el registro DNS siga proxied. + +> Alternativas si en el futuro se necesita SSH de verdad: usar un puerto SSH +> alterno expuesto directamente (sin proxy Cloudflare), un registro DNS +> "solo DNS" (nube gris) para un subdominio dedicado a Git, o simplemente +> quedarse con HTTPS (ver siguiente paso) — es la opción soportada aquí. + +## 5. Fallback a HTTPS con credential helper + +Se revirtió el remote a HTTPS y se configuró un credential helper para no +tener que reautenticar en cada push: + +```bash +git remote set-url origin https://gitea.cruzcloud.net/devops/apps-registry.git + +git config --global credential.helper store +git config --global credential.username devops +git config --global credential.usehttppath false + +# Blindaje extra: reescribe cualquier referencia http:// a https:// para +# este host a nivel de git, para que un remote/URL mal escrito con http +# nunca vuelva a intentar una ruta insegura o inconsistente. +git config --global url."https://gitea.cruzcloud.net/".insteadOf "http://gitea.cruzcloud.net/" +``` + +El primer `git push` después de esto pide usuario/token una única vez y lo +persiste (en texto plano) en `~/.git-credentials` — de ahí en adelante los +pushes son no interactivos. + +## 6. Push de la rama + +```bash +git push -u origin fix/repo-url-consistency +``` + +## 7. Abrir y mergear el PR + +Vía UI de Gitea (`http://gitea.cruzcloud.net/devops/apps-registry/pulls`) o, +de forma reproducible, vía API: + +```bash +curl -sk -u devops:$GITEA_TOKEN \ + -X POST "https://gitea.cruzcloud.net/api/v1/repos/devops/apps-registry/pulls" \ + -H "Content-Type: application/json" \ + -d '{ + "title": "fix(gitops): unificar repoURL a https en ecommerce-app", + "body": "Corrige inconsistencia http/https en repoURL detectada entre application.yaml y apps/ecommerce-app.yaml.", + "base": "main", + "head": "fix/repo-url-consistency" + }' +``` + +Revisar el diff en el PR (regla del repo: nunca merge/push a `main` sin +mostrar el diff primero) y, tras aprobarlo: + +```bash +curl -sk -u devops:$GITEA_TOKEN \ + -X POST "https://gitea.cruzcloud.net/api/v1/repos/devops/apps-registry/pulls/1/merge" \ + -H "Content-Type: application/json" \ + -d '{"Do": "merge"}' +``` + +Tras el merge, Argo CD (con `selfHeal:true`) reconcilia automáticamente y el +App of Apps deja de reportar la inconsistencia de `repoURL`. + +## Checklist reproducible para el próximo fix similar + +1. `grep -rn "" application.yaml apps/` para confirmar el + alcance real del problema. +2. `git checkout main && git pull && git checkout -b fix/` +3. Cambio mínimo + commit con mensaje `fix(gitops): ...` en español, + describiendo el qué y el porqué. +4. Si el push falla por SSH contra `gitea.cruzcloud.net`: es casi seguro el + proxy de Cloudflare bloqueando el puerto 22 — no perder tiempo debuggeando + SSH, volver a HTTPS directamente. +5. Confirmar `credential.helper=store` y `url..insteadOf=` ya + configurados globalmente (si no, configurarlos una sola vez, no por repo). +6. `git push -u origin fix/` +7. Abrir PR, mostrar el diff, esperar aprobación, mergear. +8. Verificar en Argo CD que la Application correspondiente vuelve a `Synced`.