Las cinco lecciones anteriores eran laboratorios: cada paso estaba escrito, cada fichero estaba dado y cada fallo estaba previsto. Esta no. Esta es el encargo. Aquí tienes un contexto de empresa, unas restricciones, un presupuesto y una lista de requisitos con sus criterios de aceptación, y a partir de ahí decides tú: qué herramienta, qué estrategia de despliegue, qué pruebas escribir primero, qué escaneos ejecutar en cada PR y cuáles solo en main, dónde poner las puertas, qué dejar fuera y —lo más difícil— cómo justificar cada una de esas decisiones ante alguien que no estaba cuando las tomaste.
Puedes hacerlo sobre un proyecto tuyo (mejor, si tienes uno) o sobre Mini-Reservalia. Lo que no puedes es copiar el pipeline de la 07-05 tal cual: el contexto del encargo tiene restricciones que obligan a apartarse de él en al menos tres puntos, y encontrarlas forma parte del ejercicio.
Contenido
- El encargo
- El contexto: Citas Norte, S.L.
- Requisitos obligatorios y criterios de aceptación
- Entregables
- Rúbrica de autoevaluación
- Plan de trabajo en cinco sesiones
- Retos opcionales
- Errores típicos del proyecto final
- Errores Comunes y Consejos
- Ejercicios
- Conclusión y cierre del curso en la práctica
- El encargo
Te incorporas como responsable de entrega a una empresa pequeña que tiene un producto en producción y ningún pipeline. Despliegan a mano, los viernes no despliegan, y la última vez que algo salió mal tardaron dos horas en volver atrás porque nadie recordaba qué versión estaba antes.
Tu encargo: llevar ese producto desde el estado actual hasta un pipeline completo de extremo a extremo, con puertas de calidad, artefacto inmutable, despliegue automatizado con rollback y métricas que demuestren que la situación ha mejorado.
La condición del encargo: todo lo que construyas tiene que poder ser verificado por un revisor externo que no ha hablado contigo, en menos de una hora, mirando solo el repositorio.
Esa última condición es la que convierte el ejercicio en algo parecido al trabajo real. Un pipeline que solo funciona cuando tú estás delante para explicarlo no es un entregable: es una dependencia.
- El contexto: Citas Norte, S.L.
Las restricciones son las que hacen que las decisiones tengan que justificarse. Si todo fuera posible, no habría nada que decidir.
La empresa. Citas Norte, S.L. vende un software de reservas para pequeños negocios. Tiene:
| Dato | Valor |
|---|---|
| Clientes de pago | 180 negocios |
| Volumen | ~4.000 citas al mes |
| Equipo técnico | 3 personas: una tech lead, un backend, una persona a medias entre frontend y soporte |
| Producto | Un monolito Node.js + PostgreSQL, y una SPA |
| Entornos actuales | Uno solo: producción |
| Despliegue actual | git pull por SSH y pm2 restart, a mano, por la tech lead |
| Frecuencia | Una vez cada dos semanas, martes o miércoles por la mañana |
| Pruebas | 40 pruebas unitarias que "casi siempre" pasan; nadie las ejecuta antes de desplegar |
| Última incidencia | 2 h 20 min de caída por un despliegue que rompió el login |
Las restricciones, que son innegociables:
- Presupuesto de herramientas: 0 €/mes. La empresa no aprueba gasto nuevo hasta el próximo ejercicio. Todo debe caber en planes gratuitos.
- Nadie puede dedicarse a operar el pipeline. El equipo son tres personas y las tres están al 100 % en producto. Un Jenkins autoalojado está descartado por esto, no por lo técnico.
- La ventana de mantenimiento actual es sagrada para el negocio: los sábados por la mañana, entre las 9:00 y las 13:00, se concentra el 40 % de las reservas del fin de semana. Una caída ahí cuesta clientes.
- Hay datos personales (nombre, teléfono y email de los clientes finales de los 180 negocios). Cualquier filtración es un incidente reportable.
- La tech lead se va de vacaciones tres semanas dentro de dos meses. Durante ese tiempo, las otras dos personas tienen que poder desplegar y revertir sin ella.
- El equipo desconfía de la automatización. El backend, en concreto, ha dicho literalmente: "cada minuto que le dediquemos a esto es un minuto que no dedicamos a lo que nos pagan". Tu propuesta tiene que rendir pronto y tienes que poder demostrarlo con números.
Tres consecuencias de leer bien las restricciones (compruébalas contra tus decisiones cuando termines):
- La restricción 2 y la 6 juntas descartan cualquier solución que requiera mantenimiento continuo. Menos piezas y más estándar gana a más potente.
- La restricción 5 significa que el rollback tiene que ser ejecutable por alguien que no lo escribió, con un botón y sin recordar comandos. Documentar no es opcional aquí: es un requisito funcional.
- La restricción 3 no significa "ventanas de despliegue". Significa que el tiempo de restauración importa más que la frecuencia. Si puedes revertir en 3 minutos, el sábado deja de dar miedo; si tardas 2 horas, ninguna ventana te salva.
La línea base que tienes que medir antes de tocar nada (es el requisito más incumplido de todo el proyecto):
| Métrica DORA | Valor actual estimado | Cómo lo medirías hoy |
|---|---|---|
| Frecuencia de despliegue | 0,5 / semana | Contar los git log de producción |
| Lead time (commit → producción) | ~9 días | Del commit al despliegue en el que entró |
| Change failure rate | ~20 % (1 de cada 5) | Incidencias tras despliegue ÷ despliegues |
| Time to restore | 140 min | La última incidencia |
- Requisitos obligatorios y criterios de aceptación
Cada requisito lleva su criterio verificable. La fórmula "un revisor externo debe poder comprobar que…" es deliberada: si no se puede comprobar mirando el repositorio y sus ejecuciones, no cuenta.
Grupo A — Integración continua (módulo 2)
| # | Requisito | Criterio de aceptación |
|---|---|---|
| A1 | Build reproducible | Un revisor debe poder ejecutar el mismo comando que ejecuta el CI, en su máquina, y obtener el mismo resultado. Lockfile commiteado, versión de runtime fijada explícitamente, ninguna dependencia de estado previo del runner |
| A2 | Tres capas de pruebas | Existen pruebas unitarias, de integración (contra una dependencia real: base de datos o API) y al menos una end-to-end contra el sistema arrancado. El revisor puede identificar qué fichero pertenece a qué capa sin preguntar |
| A3 | Quality gate | Un PR con un fallo de lint, un test roto o cobertura por debajo del umbral no se puede mergear. Verificable abriendo un PR de prueba: el botón de merge está deshabilitado |
| A4 | Artefacto inmutable identificado por digest | El pipeline produce un artefacto (imagen de contenedor o equivalente) publicado en un registro, referenciado por digest en todos los despliegues. El revisor puede ver el digest en el resumen del run y comprobar que es el mismo que se desplegó |
| A5 | Protección de rama | main no admite push directo. Existe al menos un check obligatorio. Verificable intentando un push directo: es rechazado |
| A6 | Feedback rápido | El tiempo desde el push hasta el primer resultado significativo está medido y documentado, y es inferior a 10 minutos |
Grupo B — Despliegue continuo (módulo 3)
| # | Requisito | Criterio de aceptación |
|---|---|---|
| B1 | Separación CI/CD | Son workflows distintos con permisos distintos. El de CD no se ejecuta si el de CI falló. Verificable en el YAML y en el historial de ejecuciones |
| B2 | Al menos un entorno con aprobación | Existe un entorno cuyo despliegue requiere una acción humana explícita. El revisor puede ver en el historial una ejecución que estuvo en estado Waiting |
| B3 | Despliegue idempotente | Ejecutar el despliegue dos veces con el mismo artefacto no cambia nada la segunda vez. Verificable relanzando el workflow y leyendo el log |
| B4 | Smoke test posterior al despliegue | Existe una verificación automática que falla si el despliegue fue malo. Debe estar demostrado: un run histórico donde el smoke test bloqueó un despliegue |
| B5 | Promoción sin reconstruir | El artefacto que llega al último entorno es byte a byte el mismo que se validó en el primero. Hay una comprobación explícita del digest en el log |
| B6 | Rollback cronometrado < 10 min | Existe un procedimiento de rollback ejecutable con una acción, y un run histórico con el tiempo medido en el resumen |
| B7 | Rollback ejecutable por otra persona | La restricción 5 del contexto. Documentado en un runbook con el comando exacto y sin conocimiento tácito |
Grupo C — Prácticas avanzadas (módulo 4)
| # | Requisito | Criterio de aceptación |
|---|---|---|
| C1 | Caché y paralelización con tiempos medidos | El PIPELINE.md documenta el tiempo antes y después de aplicar caché y paralelización, con capturas o enlaces a los runs concretos |
| C2 | Lógica en scripts, YAML delgado | Los pasos con lógica están en scripts/, son ejecutables en local y el YAML los invoca. Verificable: el revisor puede ejecutar ./scripts/desplegar.sh en su máquina |
| C3 | Al menos una pieza reutilizable | Una composite action, un reusable workflow o un script compartido entre al menos dos workflows, con su documentación |
| C4 | Gestión de dependencias automatizada | Dependabot o equivalente configurado, con agrupación y política de qué se automerge y qué no |
| C5 | Sin "verde falso" | Ningún ` |
Grupo D — Seguridad (módulo 4 y lección 07-05)
| # | Requisito | Criterio de aceptación |
|---|---|---|
| D1 | Mínimo privilegio | permissions: explícito en todos los workflows. Ningún write-all. El permiso por defecto del repositorio es de lectura |
| D2 | Acciones fijadas por SHA | Todas las acciones de terceros por SHA de 40 caracteres con comentario de versión. Verificable con un grep |
| D3 | Los cinco escaneos | Secretos, SCA, SAST, imagen y configuración. Los cinco reportan a un sitio consultable |
| D4 | Política de severidades | Existe un documento que dice qué rompe el build y qué no, y el pipeline la implementa. Las excepciones tienen justificación y fecha de caducidad |
| D5 | Sin secretos de larga vida en el camino crítico | Se usa OIDC o tokens efímeros. Si hay algún secreto persistente, está en un entorno protegido y justificado |
| D6 | Datos personales protegidos | La restricción 4 del contexto: ninguna prueba usa datos reales, ningún log imprime datos personales, ningún dump de base de datos sale del entorno de producción |
Grupo E — Observabilidad (módulo 3 y lección 07-04)
| # | Requisito | Criterio de aceptación |
|---|---|---|
| E1 | Métricas expuestas | La aplicación expone métricas consultables que cubren al menos tres de las cuatro señales de oro |
| E2 | Un SLO con presupuesto de error | Documentado con sus cuatro elementos (indicador, umbral, objetivo, ventana) y la aritmética del presupuesto escrita |
| E3 | Una alerta por síntoma | Definida con un for:, con runbook enlazado, y demostrada: hay evidencia de haberla visto pasar a firing |
| E4 | Las cuatro DORA calculadas automáticamente | Un job programado las calcula y publica. El revisor puede ver al menos dos ejecuciones para comparar |
| E5 | La mejora demostrada | El PIPELINE.md compara la línea base del apartado 2 con las métricas actuales |
Total: 29 requisitos. No se espera que todos queden impecables; se espera que todos estén considerados y que las ausencias sean decisiones documentadas, no olvidos.
- Entregables
4.1 El repositorio
Público (o privado con acceso al revisor), con historial real: ramas, PR, checks, runs con éxito y runs con fallo. Un repositorio con un solo commit gigante no demuestra un pipeline; demuestra un fichero.
Estructura sugerida:
proyecto/ ├── .github/ │ ├── workflows/ ci.yml, cd.yml, rollback.yml, seguridad.yml, dora.yml │ ├── actions/ composite actions propias │ └── dependabot.yml ├── scripts/ toda la logica: desplegar, smoke, vigilar, dora... ├── src/ test/ ├── seguridad/ POLITICA.md, excepciones.json, .trivyignore ├── observabilidad/ compose, prometheus.yml, alertas.yml, SLO.md, RUNBOOK.md ├── Dockerfile .dockerignore ├── PIPELINE.md ← entregable 4.2 ├── POSTMORTEM.md ← entregable 4.3 └── README.md qué es, cómo se ejecuta, badges
4.2 PIPELINE.md — decisiones y contrapartidas
Este es el entregable que más se nota y el que peor se hace. No es documentación de qué hace el pipeline —eso se lee en el YAML—: es el registro de por qué es así y qué se sacrificó.
Plantilla mínima:
# Decisiones del pipeline
## Contexto y restricciones
Resumen de las restricciones del encargo y cómo condicionan lo que sigue.
## Línea base (antes)
| Métrica | Valor | Cómo se midió |
## Decisiones
### D1 — Herramienta de CI/CD: GitHub Actions
**Alternativas consideradas:** GitLab CI, CircleCI, Jenkins autoalojado.
**Decisión:** GitHub Actions.
**Motivo:** el código ya está en GitHub (restricción de identidad, 06-07);
plan gratuito suficiente para el volumen (restricción 1); cero operación
(restricción 2).
**Contrapartida aceptada:** acoplamiento al proveedor. Se mitiga poniendo
toda la lógica en `scripts/` (C2): una migración costaría ~5 días, no 4 semanas.
**Cuándo revisar esta decisión:** si el volumen de minutos supera el plan
gratuito, o si la empresa cambia de proveedor de repositorios.
### D2 — Estrategia de despliegue: rolling, no canary
...
### D3 — Qué NO hemos hecho y por qué
- **No hay entornos efímeros por PR.** Coste de mantenimiento alto para un
equipo de tres personas (restricción 2). Se revisará cuando el equipo crezca.
- **No hay pruebas de carga en el pipeline.** El volumen actual (4.000
citas/mes) no las justifica.
...
## Mediciones
| Cambio | Antes | Después | Run de referencia |
| Caché de dependencias | 3 min 40 s | 1 min 15 s | #128 vs #131 |
## Después
| Métrica DORA | Antes | Ahora | Fuente |La sección "Qué NO hemos hecho y por qué" es la que distingue un trabajo profesional de un ejercicio. Un pipeline sin límites explícitos es un pipeline que crecerá sin control hasta que alguien lo abandone.
4.3 POSTMORTEM.md — un fallo provocado a propósito
Provoca un fallo real, déjalo llegar hasta donde tu pipeline lo detenga, y escribe el post-mortem. Sugerencias de fallo, en orden de dificultad:
| Fallo | Dónde debería detenerse | Qué demuestra |
|---|---|---|
| Un test roto | En CI, en el primer job | Lo básico |
| Una regresión que las pruebas no cubren | En el smoke test de staging | Que las capas se complementan |
| Una migración de BD incompatible hacia atrás | En el despliegue, o en el rollback | Lo aprendido en la 04-06 |
| Una versión que arranca bien y se degrada a los 5 minutos | En la vigilancia posterior, con rollback automático | El bucle completo cerrado |
Estructura del post-mortem, sin culpables:
# Post-mortem: <título descriptivo del impacto, no de la causa>
**Fecha:** · **Duración del impacto:** · **Severidad:** · **Autor:**
## Impacto
Qué dejó de funcionar, para quién y durante cuánto. En términos de usuario,
no de infraestructura: "los negocios no podían ver los huecos del día",
no "el contenedor estaba unhealthy".
## Cronología
| Hora | Evento | Quién / qué lo detectó |
|---|---|---|
| 10:32 | Merge del PR #47 | — |
| 10:38 | Despliegue a staging | pipeline |
| 10:39 | Smoke test falla | pipeline (automático) |
| 10:39 | Despliegue a producción bloqueado | pipeline |
## Causa raíz
La técnica de los cinco porqués, hasta llegar a algo sistémico.
Si la respuesta final es "un desarrollador se equivocó", no has llegado al final:
la pregunta siguiente es "¿por qué el sistema permitió que ese error llegara ahí?".
## Qué funcionó
Igual de importante que lo que falló. Aquí se justifica la inversión en el pipeline.
## Qué no funcionó
## Acciones correctivas
| # | Acción | Responsable | Fecha | Estado |
Con responsable y fecha, o no es una acción: es un deseo.
## Lecciones4.4 Panel o resumen de métricas
Un panel de Grafana versionado, o —si no montas Prometheus— un $GITHUB_STEP_SUMMARY de un job programado con las cuatro DORA, el estado del SLO y el consumo del presupuesto de error. Lo que se evalúa es que exista una superficie donde alguien que no eres tú pueda ver cómo va la cosa sin pedirte nada.
- Rúbrica de autoevaluación
Aplícatela con honestidad. La columna "Insuficiente" describe lo que la mayoría entrega en el primer intento.
| Criterio | Insuficiente | Correcto | Excelente |
|---|---|---|---|
| Build reproducible | El pipeline "funciona" pero no se puede reproducir en local | Lockfile, runtime fijado, mismo comando en local y en CI | Además, verificado periódicamente por un job que ejecuta el build en una máquina limpia |
| Pruebas | Solo unitarias, o cobertura sin asserts | Tres capas identificables, umbral de cobertura que rompe | Además, test de contrato entre implementaciones, casos límite documentados y detección de flaky |
| Quality gate | Los checks existen pero no bloquean | main protegida con check obligatorio, comprobado por el lado negativo |
Job agregador que desacopla la protección de la forma del pipeline |
| Artefacto | Se reconstruye en cada entorno | Imagen publicada, desplegada por digest | Firmada, con SBOM, y la firma se verifica antes de desplegar |
| Separación CI/CD | Un solo workflow lo hace todo | Workflows separados con permisos distintos | Además, el CD se puede lanzar a mano con un digest arbitrario para reintentos |
| Puerta de aprobación | No hay | Entorno con revisor requerido | Aprobación condicional: automática si las métricas están bien, humana si no |
| Idempotencia | Redesplegar reinicia el servicio sin necesidad | El script detecta que ya está desplegado y no hace nada | Además, el script rechaza referencias mutables y valida antes de tocar nada |
| Smoke test | Solo comprueba que responde 200 | Comprueba salud, funcionalidad y versión desplegada | Además, comprueba que los errores siguen dando error, y hay un run donde bloqueó |
| Rollback | Existe como documento | Workflow ejecutable, cronometrado, < 10 min | < 3 min, automático por métricas, y ejecutado con éxito por otra persona |
| Rendimiento | Sin medir | Caché y paralelización aplicadas, tiempos documentados | Ejecución selectiva por cambios, y el coste en minutos también medido |
| Reutilización | Todo copiado y pegado entre workflows | Una pieza compartida y documentada | Reusable workflow versionado, con inputs, outputs y su propia prueba |
| Mínimo privilegio | Sin permissions |
Explícito en workflow y ampliado por job | Verificado provocando el fallo, y documentado qué necesita cada job |
| Escaneos | Ninguno, o con ` | true` | |
| Secretos | En el repositorio o en variables globales | Secretos de entorno, alcance mínimo | OIDC / tokens efímeros; ningún secreto de larga vida en el camino crítico |
| Observabilidad | Solo logs | Métricas expuestas y un panel | SLO con presupuesto, alerta demostrada y despliegues anotados en el panel |
| DORA | No se calculan | Calculadas a mano una vez | Job programado, histórico y tendencia comparada con la línea base |
PIPELINE.md |
Describe qué hace el YAML | Explica por qué, con alternativas | Incluye contrapartidas, límites explícitos y cuándo revisar cada decisión |
POSTMORTEM.md |
Narra el fallo | Cronología, causa raíz, acciones | Sin culpables, con "qué funcionó", y las acciones tienen responsable y fecha |
| Reproducibilidad por un tercero | Solo tú sabes ejecutarlo | README con los pasos | Un revisor externo lo verifica entero en una hora sin preguntarte nada |
Cómo puntuarte: cuenta cuántas filas caen en cada columna.
- Mayoría en Insuficiente: tienes un pipeline que funciona pero no es defendible. Prioriza el grupo A y el B4/B6.
- Mayoría en Correcto: es un pipeline profesional, entregable. Es el objetivo realista del curso.
- Varias en Excelente: estás por encima de lo que tienen muchos equipos en producción. Elige dos o tres para llevar a excelente en vez de subir todas a la vez.
- Plan de trabajo en cinco sesiones
Cinco sesiones de 2-4 horas. El orden no es arbitrario: cada sesión deja algo funcionando y medible, y ninguna depende de terminar la siguiente para aportar valor. Es el mismo principio de los siete incrementos de la 05-04.
Sesión 1 — Medir y hacer verificable el proyecto (sin tocar el pipeline)
- Mide la línea base. Las cuatro DORA con los datos que tengas, aunque sean aproximados. Anótalas en
PIPELINE.mdhoy, porque dentro de tres semanas no podrás reconstruirlas. - Consigue que el proyecto se verifique con un solo comando:
npm ci && npm run lint && npm test && npm run build. Si eso no funciona en una máquina limpia, arréglalo antes de escribir una línea de YAML. - Escribe la prueba que falta para el bug más reciente que hayáis tenido.
- Commitea el lockfile si no está.
Entregable de la sesión: un comando que verifica el proyecto y la línea base escrita.
Sesión 2 — CI y la primera puerta
ci.ymlincremental, como en la 07-01: primero que se ejecute, luego que instale y pruebe, luego jobs en paralelo, luego caché. Mide los tiempos en cada paso y anótalos.- Las tres capas de pruebas (07-02). Empieza por la que más miedo te da romper.
- Cobertura con umbral 2-3 puntos por debajo del valor actual.
- Protección de
maincon un job agregador como único check requerido. - Rompe algo a propósito y comprueba que bloquea.
Entregable: A1-A6 cumplidos, con los tiempos antes/después de la caché.
Sesión 3 — Artefacto y despliegue
- Dockerfile multi-etapa, no-root,
HEALTHCHECK(07-03). - Publicación en el registro por digest, con el digest visible en el resumen.
scripts/desplegar.shidempotente y ejecutable en local. Escríbelo antes que el YAML: si empiezas por el YAML, acabarás con lógica dentro del YAML.scripts/smoke.shque verifique salud, funcionalidad y versión.cd.ymlcon dos entornos y aprobación en el segundo.rollback.ymlcronometrado. Ejecútalo y anota el tiempo.- Provoca un despliegue malo y comprueba que el smoke test lo detiene.
Entregable: B1-B7 cumplidos, con el run del rollback cronometrado y el run del despliegue bloqueado.
Sesión 4 — Seguridad
- Auditoría de lo que llevas construido, con la lista de la 07-05.
permissionsde mínimo privilegio, provocando un fallo para entenderlo.- Acciones por SHA + Dependabot.
- Los cinco escaneos, uno cada vez, comprobando que cada uno detecta algo real antes de pasar al siguiente.
- Política de severidades escrita y el job de caducidad de excepciones.
- SBOM, firma y verificación antes de desplegar.
Entregable: D1-D6, con evidencia de que cada escaneo ha detectado algo.
Sesión 5 — Observabilidad, cierre y documentación
/metricascon las señales de oro (07-04).- SLO con la aritmética del presupuesto escrita.
- Una alerta por síntoma, disparada a propósito y con captura.
- Job programado de DORA. Ejecútalo dos veces con días de diferencia para tener tendencia.
- Provoca el fallo del post-mortem y escríbelo.
PIPELINE.mdcompleto, incluida la sección de qué no has hecho.- Pásate la rúbrica.
Entregable: E1-E5, PIPELINE.md, POSTMORTEM.md y la autoevaluación.
Consejo sobre el ritmo. Si vas corto de tiempo, sacrifica el grupo E antes que el B. Un pipeline que despliega y revierte pero no se mide es incompleto; uno que se mide pero no puede revertir es peligroso. Y si tienes que elegir un solo requisito de los 29, que sea B6: rollback cronometrado. Es el que convierte el miedo en un número.
- Retos opcionales
Para cuando lo básico esté cerrado. Cada uno vale por sí solo.
| Reto | Qué añade | Dificultad | Referencia |
|---|---|---|---|
| Canary real con decisión automática | Despliegue por peso + medición + promoción o retirada automática | Alta | 03-04, 07-03 ej. 2 |
| Entornos efímeros por PR | Un entorno por pull request, destruido al cerrarlo | Alta | 02-07, 06-02 |
| Matriz de dos herramientas | El mismo pipeline en GitHub Actions y en GitLab CI, comparando esfuerzo real | Media | Módulo 6 completo |
| IaC del entorno de destino | Terraform que crea el host, el registro y la red, con plan en PR y apply tras aprobación |
Alta | 03-03 |
| Migraciones de BD en el pipeline | Expand and contract, migración versionada, y un rollback que no pierde datos | Muy alta | 04-06 |
| Política de admisión externa | Un script que valida firma, SBOM, escaneos y procedencia, consultado por el CD | Media | 07-05 reto |
| Reparto de shards por tiempos | Balanceo real de la suite con histórico | Media | 07-02 reto |
El más instructivo de todos, si quieres cerrar el curso con algo que te cambie la perspectiva, es la matriz de dos herramientas: reimplementar el pipeline en GitLab CI te obliga a separar lo que es tu proceso de lo que es sintaxis de GitHub, y esa separación es exactamente la que la 06-07 defendía. Se tarda menos de lo que parece —el trabajo real ya está en los scripts— y el resultado es una tabla de equivalencias que has escrito tú.
- Errores típicos del proyecto final
Estos tres son, con diferencia, los que más se repiten. Los tres tienen la misma forma: hacer la parte visible antes que la parte que la sostiene.
Error 1: empezar por el YAML en vez de por los scripts
Cómo se manifiesta. Se abre ci.yml y se empieza a escribir. A los tres días hay 200 líneas de YAML con run: | de veinte líneas cada uno, y la única forma de probar un cambio es hacer push y esperar cuatro minutos.
Por qué es grave. El ciclo de depuración pasa de segundos a minutos, y multiplicado por cada intento. Un problema que en local se resuelve en cinco iteraciones de diez segundos se convierte en cinco iteraciones de cuatro minutos, con commits de "arreglar CI", "arreglar CI 2", "ahora sí". Además, esa lógica no es testeable, no es revisable y no se puede ejecutar en una emergencia si el CI está caído.
El orden correcto:
1. El comando funciona en tu terminal 2. El comando está en un script con argumentos y valores por defecto 3. El script está en el repositorio y tiene su documentación 4. El YAML LLAMA al script
Prueba de fuego: ¿puedes desplegar sin GitHub Actions? Si la respuesta es no, la lógica está en el sitio equivocado.
Error 2: automatizar antes de tener una prueba que valga
Cómo se manifiesta. Un pipeline precioso que despliega en noventa segundos... el código roto. Las pruebas existen, pasan siempre, y no cubren nada de lo que se rompe de verdad.
Por qué es grave. Automatizar el despliegue multiplica la velocidad a la que llegan los cambios a producción. Si la verificación es débil, lo que has multiplicado es la velocidad a la que llegan los bugs. Un pipeline rápido sobre pruebas malas es objetivamente peor que el despliegue manual del principio, porque el manual al menos incluía a una persona mirando.
El orden correcto: una prueba que detecte el último bug real que tuvisteis, antes de automatizar el despliegue. Si no puedes escribirla, no automatices todavía: automatiza solo hasta staging y deja producción manual hasta que la red de seguridad exista.
La señal de alarma: si tu suite nunca ha estado en rojo por un bug real —solo por errores de sintaxis—, no está probando nada.
Error 3: no medir la línea base y quedarse sin poder demostrar la mejora
Cómo se manifiesta. Tres semanas de trabajo, un pipeline excelente, y en la reunión con la dirección: "¿y esto qué ha mejorado?" — "Pues... va todo mucho mejor".
Por qué es grave. Es el error que hace que la siguiente inversión no se apruebe. Recuerda la restricción 6 del contexto: el backend ya piensa que esto es tiempo robado al producto. Sin números, tiene razón él, porque su escepticismo sí está basado en algo concreto (las horas invertidas) y tu defensa no.
Y hay un agravante técnico: la línea base no se puede reconstruir a posteriori. Una vez que el pipeline está montado, el "antes" ya no existe. Es información que se destruye al hacer el trabajo.
El orden correcto: medir en la sesión 1, antes de tocar nada, aunque sea con estimaciones toscas. Cuatro números y la fecha. Diez minutos de trabajo que valen por las tres semanas siguientes.
Cómo se presenta después:
| Métrica | Antes (12/03) | Ahora (28/04) | Cambio |
|---|---|---|---|
| Frecuencia de despliegue | 0,5 / semana | 6 / semana | ×12 |
| Lead time | 9 días | 4 h | −98 % |
| Change failure rate | 20 % | 6 % | −70 % |
| Time to restore | 140 min | 3 min | −98 % |
| Tiempo de la tech lead en desplegar | 45 min/despliegue | 0 | −6 h/mes |
Esa última fila es la que cierra la discusión, y por eso conviene tenerla: traduce el trabajo a horas de personas, que es la unidad en la que piensa quien aprueba presupuestos. Es exactamente el argumento del TCO de la 06-07, aplicado a tu propio proyecto.
- Errores Comunes y Consejos
Síntoma: el proyecto se atasca en la sesión 3 y no llega a producción. Causa: intentar montar el entorno de destino "de verdad" (un VPS, Kubernetes, AWS) antes de tener el pipeline. Arreglo: usa un destino simulado como el de la 07-03 y termina el circuito completo. Un pipeline que despliega a un contenedor local pero cubre las siete piezas de B1-B7 vale infinitamente más que medio pipeline apuntando a infraestructura real. Cambia el destino al final; es la parte más fácil de cambiar.
Síntoma: 29 requisitos parecen inabordables y no se empieza. Causa: intentar hacerlos en paralelo. Arreglo: el plan de cinco sesiones está ordenado por dependencia. Haz A completo antes de tocar B. Un grupo terminado vale más que cinco a medias, porque los grupos incompletos no se pueden verificar.
Síntoma: el PIPELINE.md acaba siendo una descripción del YAML.
Causa: documentar mientras se escribe el código, cuando aún no hay perspectiva.
Arreglo: escribe cada decisión en el momento en que descartas una alternativa, con una línea: "descartado X porque Y". Al final, esas líneas son el documento. Si nunca descartaste nada, no tomaste decisiones: copiaste.
Síntoma: la rúbrica sale mayoritariamente en "Correcto" y no sabes qué mejorar. Consejo: no subas todo a "Excelente". Elige dos o tres con criterio: las que más reduzcan el riesgo en tu contexto concreto. Con las restricciones de Citas Norte, las tres candidatas obvias son el rollback (restricción 5), la verificación de firma (restricción 4, datos personales) y las DORA con tendencia (restricción 6, hay que convencer a alguien).
Consejo — no lo hagas todo tú. Si tienes con quién, pide a alguien que verifique tu repositorio siguiendo los criterios de aceptación, sin que le expliques nada. Los puntos donde tenga que preguntarte algo son exactamente los que te faltan por documentar. Es la prueba más barata y la más reveladora del proyecto.
Consejo — el pipeline nunca está terminado. Cuando cierres los 29 requisitos, el pipeline será bueno para el contexto de hoy. Con el doble de equipo y diez veces el tráfico, tres de tus decisiones serán incorrectas. Por eso cada decisión del PIPELINE.md lleva "cuándo revisar esta decisión": no es burocracia, es reconocer que un pipeline es un organismo vivo y que la alternativa a revisarlo es reescribirlo entero dentro de dos años.
- Ejercicios
Estos tres no son variaciones del laboratorio: son extensiones del propio proyecto final, pensadas para hacerlas después de entregarlo.
Ejercicio 1: la revisión cruzada
Intercambia repositorios con otra persona que haya hecho el proyecto (o audita un repositorio público real que use GitHub Actions). Aplica los 29 criterios de aceptación sin hablar con nadie y escribe un informe de auditoría con los hallazgos priorizados.
Ejercicio 2: la prueba de las vacaciones
La restricción 5 del contexto: la tech lead se va tres semanas. Demuestra que el sistema sobrevive.
Ejercicio 3: el mismo pipeline con la mitad del tiempo
Reduce a la mitad el tiempo de tu pipeline sin quitar ninguna verificación. Documenta cada cambio con su medición.
Soluciones
Solución 1. Plantilla de informe de auditoría:
# Auditoría del pipeline de <repositorio>
**Auditor:** · **Fecha:** · **Tiempo empleado:** · **Commit auditado:**
## Resumen ejecutivo
Tres frases: estado general, el riesgo más grave, la mejora de mayor
relación valor/esfuerzo.
## Verificación de criterios
| # | Requisito | Cumple | Evidencia | Notas |
|---|---|---|---|---|
| A1 | Build reproducible | ✅ | Ejecuté `npm ci && npm test` en limpio: OK | — |
| A4 | Artefacto por digest | ⚠️ | Run #88: publica por digest pero el CD usa `:main` | **La promoción no garantiza el mismo artefacto** |
| B4 | Smoke test | ❌ | No encontré ningún run donde bloqueara | Puede que nunca se haya probado |
## Hallazgos priorizados
### H1 (Alto) — El CD despliega por tag, no por digest
**Evidencia:** `cd.yml:47` usa `ghcr.io/...:main`.
**Riesgo:** entre la validación en staging y el despliegue a producción, otro
merge puede mover el tag. Producción ejecutaría código no validado.
**Arreglo:** resolver el digest una vez en un job `preparar` y propagarlo por
`outputs`. Coste: ~30 min.
## Lo que está bien hecho
(Obligatorio. Una auditoría que solo lista problemas no se lee entera y
no se aplica.)
## Preguntas que tuve que hacer al autor
Cada una de estas es documentación que falta.Lo que enseña este ejercicio: auditar el trabajo de otro es la forma más rápida de ver los agujeros del tuyo. Casi todo el mundo encuentra en el repositorio ajeno dos o tres cosas que también le faltan al propio y que no había visto en semanas.
Solución 2. El protocolo de la prueba:
# Prueba de continuidad ("las vacaciones")
## Regla
Durante el ejercicio, quien escribió el pipeline **no habla, no toca el teclado
y no responde preguntas**. Solo observa y toma notas.
## Escenario 1 — Despliegue rutinario (objetivo: < 15 min)
La otra persona debe, usando solo el repositorio:
1. Localizar cómo se despliega.
2. Lanzarlo.
3. Aprobar la puerta de producción.
4. Verificar que la versión nueva está sirviendo tráfico.
## Escenario 2 — Rollback bajo presión (objetivo: < 10 min)
Se despliega una versión mala (rompe `/salud`). La otra persona debe:
1. Darse cuenta de que algo va mal (¿la alerta llegó? ¿a quién?).
2. Encontrar a qué versión volver.
3. Ejecutar el rollback.
4. Confirmar la recuperación.
## Escenario 3 — Fallo del pipeline (objetivo: desplegar sin CI)
GitHub Actions está caído (simúlalo deshabilitando el workflow) y hay que
desplegar un parche urgente. ¿Existe un camino manual documentado?
## Registro
| Escenario | Tiempo | ¿Lo consiguió? | Dónde se atascó | Documentación que faltaba |
## Acciones correctivas
Cada atasco es un fallo del SISTEMA, no de la persona. Se convierte en:
- Una línea en el runbook, o
- Un valor por defecto mejor, o
- Un mensaje de error más claro.Los tres fallos que aparecen casi siempre en este ejercicio, por si quieres adelantarte:
- Encontrar el digest anterior. Nadie sabe dónde mirar. Arreglo: imprimirlo en el resumen de cada despliegue y aceptar el input vacío en el rollback (07-03 ejercicio 1).
- La alerta no llegó a nadie. Estaba configurada en Prometheus pero sin destinatario. Arreglo: Alertmanager con un canal real, y una prueba de que llega.
- El camino manual no existe. Todo el conocimiento está dentro del YAML. Arreglo:
scripts/desplegar.shejecutable en local (requisito C2), documentado en el runbook con el comando literal.
Si tu proyecto pasa el escenario 3, has cumplido el criterio más exigente de todo el curso: el pipeline es una comodidad, no una dependencia.
Solución 3. La estrategia, en orden de rentabilidad:
# Reducción del tiempo de pipeline
## Medición inicial (run #142)
| Job | Duración | ¿Camino crítico? |
|---|---|---|
| calidad | 1m 10s | No |
| test (×4) | 3m 40s | **Sí** |
| cobertura | 2m 50s | No |
| build | 2m 20s | Sí |
| publicar | 4m 10s | **Sí** |
| **Total (pared)** | **10m 30s** | |
Regla previa: **solo cuenta el camino crítico**. Optimizar un job que corre en
paralelo con otro más lento no ahorra ni un segundo de tiempo de pared.
## Cambios aplicados
### C1 — Caché de dependencias (−1m 50s)
`cache: 'npm'` en los 5 jobs. Segunda ejecución en adelante.
Antes: `npm ci` 22s/job · Después: 4s/job.
### C2 — Caché de capas de Docker (−2m 30s)
`cache-from: type=gha` / `cache-to: type=gha,mode=max`.
El mayor ahorro individual: el módulo nativo dejó de recompilarse.
### C3 — Reordenar el Dockerfile (−40s)
`COPY package*.json` y `npm ci` ANTES de `COPY . .`.
Sin esto, cualquier cambio de código invalida la capa de dependencias
y la caché de C2 no sirve para nada. **C3 es lo que hace que C2 funcione.**
### C4 — Fusionar `cobertura` en el job de test (−0s de pared, −2m de máquina)
No estaba en el camino crítico: no ahorra tiempo de pared, pero sí coste.
Se documenta porque el coste también es una métrica.
### C5 — Ejecución selectiva (−variable)
Los jobs pesados solo si cambian los ficheros relevantes, con job agregador
que siempre reporta (07-01 ejercicio 2). En PR de solo documentación:
10m 30s → 45s.
### C6 — Descartado: runners más grandes
Reduciría ~30 % pero cuesta dinero. Restricción 1 del encargo.
**Se documenta el descarte para que no haya que volver a evaluarlo.**
## Resultado (run #171)
| Job | Antes | Después |
|---|---|---|
| test (×4) | 3m 40s | 1m 30s |
| publicar | 4m 10s | 1m 20s |
| **Total (pared)** | **10m 30s** | **4m 15s** (−60 %) |
| Minutos de máquina | 14m 10s | 7m 30s (−47 %) |
## Verificaciones NO eliminadas
Ninguna. Mismos 5 escaneos, misma cobertura, misma matriz.
`git diff` de los workflows: solo caché, orden y condiciones.La lección de este ejercicio es C3: la caché de Docker no funciona si el Dockerfile está mal ordenado, y mucha gente añade C2, no ve mejora y concluye que "la caché no sirve". El orden de las capas es el 80 % del resultado, y es gratis.
- Conclusión y cierre del curso en la práctica
Si has llegado hasta aquí con el proyecto entregado, tienes en tu repositorio algo que muchos equipos en producción no tienen: un pipeline que integra, verifica en tres capas, construye un artefacto inmutable identificado por su contenido, lo escanea de cinco formas distintas, lo firma, lo despliega tras una puerta explícita, comprueba que el despliegue funcionó, promociona el mismo artefacto sin reconstruirlo, revierte en minutos —solo, si las métricas empeoran—, y se mide a sí mismo para poder demostrar que todo eso sirve de algo.
Pero el entregable que más va a durar no es el YAML. Son los dos documentos.
El PIPELINE.md, porque contiene lo único que no se puede deducir leyendo el código: por qué es así y qué se sacrificó a cambio. Dentro de un año, cuando alguien —quizá tú— se pregunte por qué no hay canary o por qué las acciones están fijadas por esos SHA raros, la respuesta estará escrita, con su fecha y con la condición que obligaría a revisarla. Un pipeline sin ese documento se reescribe entero cada dos años porque nadie se atreve a tocar lo que no entiende.
Y el POSTMORTEM.md, porque documenta la única prueba que de verdad importa: que el sistema falló y lo aguantó. Cualquiera puede enseñar un pipeline en verde. Enseñar uno que se puso en rojo por el motivo correcto, en el sitio correcto, y que se recuperó en tres minutos, es enseñar que funciona.
Hay una última cosa que este módulo te ha hecho hacer sin decírtelo explícitamente, y conviene nombrarla ahora. En cada laboratorio has roto algo a propósito: un test, un despliegue, un secreto, una consulta SQL, un endpoint lento. Eso no era decoración pedagógica. Es la práctica profesional que separa a quien tiene un pipeline de quien confía en su pipeline: verificar por el lado negativo. Cualquiera puede comprobar que un control deja pasar lo bueno; comprobar que detiene lo malo requiere fabricar lo malo, y casi nadie lo hace. Si te llevas una sola costumbre del curso, que sea esta: cada vez que añadas una puerta, provoca el fallo que debería detener, y no des la puerta por buena hasta haberlo visto.
Con esto se cierra la parte práctica y, con ella, la materia del curso. Has recorrido los principios (módulos 1 a 4), cuatro contextos reales (módulo 5), la maquinaria (módulo 6) y la construcción de extremo a extremo con tus manos (módulo 7). Lo que queda ya no es materia: es a dónde ir después.
El módulo 8 es el mapa de esa continuación. Las lecturas recomendadas —Continuous Delivery, Accelerate, The DevOps Handbook, el SRE Workbook— que dan el fundamento y los datos detrás de casi todo lo que has aplicado aquí. Las comunidades y foros donde se discuten estos problemas cuando se salen de lo que cabe en un curso. Las herramientas y plugins adicionales que quedaron fuera por espacio y que resuelven problemas concretos que ya sabrás reconocer: gestión de secretos con Vault, entrega progresiva con Flagger o Argo Rollouts, plataformas internas de desarrollo, políticas como código. Y la ruta de aprendizaje y certificaciones, con el orden razonable para profundizar según hacia dónde quieras moverte —plataforma, SRE, seguridad de la cadena de suministro— y qué certificaciones valen realmente la pena en cada caso.
Empieza por 08-01: Lecturas Recomendadas. Y, cuando lo hagas, léelo con el pipeline delante: ahora tienes un sistema real sobre el que probar cada idea, que es exactamente lo que faltaba la primera vez que abriste este curso.
Curso de CI/CD: Integración y Despliegue Continuo
Módulo 1: Introducción a CI/CD
- Conceptos Básicos de CI/CD
- Beneficios de CI/CD
- Herramientas Populares de CI/CD
- El Proyecto del Curso: la Aplicación que Vamos a Automatizar
- Métricas DORA: Cómo se Mide la Entrega de Software
Módulo 2: Integración Continua (CI)
- Introducción a la Integración Continua
- Configuración de un Entorno de CI
- Automatización de la Construcción
- Pruebas Automatizadas
- Calidad de Código y Análisis Estático
- Artefactos, Versionado y Promoción
- Integración con Control de Versiones
Módulo 3: Despliegue Continuo (CD)
- Introducción al Despliegue Continuo
- Automatización del Despliegue
- Infraestructura como Código y Entornos Reproducibles
- Estrategias de Despliegue
- Feature Flags, Rollback y Recuperación ante Fallos
- Monitoreo y Retroalimentación
Módulo 4: Prácticas Avanzadas de CI/CD
- Pipelines de CI/CD
- Gestión de Dependencias
- Seguridad en CI/CD
- Escalabilidad y Rendimiento
- Pipeline as Code: Plantillas, Reutilización y Pruebas del Pipeline
- Bases de Datos en el Pipeline: Migraciones Seguras
Módulo 5: Implementación de CI/CD en Proyectos Reales
- Caso de Estudio: Proyecto Web
- Caso de Estudio: Aplicación Móvil
- Caso de Estudio: Microservicios
- Caso de Estudio: Modernizar un Proyecto Legacy
Módulo 6: Herramientas y Tecnologías
- Jenkins
- GitLab CI/CD
- CircleCI
- Travis CI
- Docker y Kubernetes
- GitHub Actions a Fondo
- Comparativa y Criterios para Elegir Herramienta
Módulo 7: Ejercicios Prácticos
- Ejercicio 1: Configuración de un Pipeline Básico
- Ejercicio 2: Integración de Pruebas Automatizadas
- Ejercicio 3: Despliegue en un Entorno de Producción
- Ejercicio 4: Monitoreo y Retroalimentación
- Ejercicio 5: Endurecer el Pipeline con Seguridad y Secretos
- Proyecto Final: Pipeline Completo de Extremo a Extremo
