Reservalia ya tiene cuatro jobs, pruebas de verdad, análisis estático y un artefacto publicado en ECR. Y sin embargo, todo eso puede seguir sin funcionar por una razón que no tiene nada que ver con el YAML: si las ramas viven tres semanas, no hay Integración Continua por muy bueno que sea el pipeline. Esta última lección del módulo cierra el círculo conectando la herramienta con la forma de trabajar del equipo. Compararemos los tres modelos de ramas más extendidos y veremos cuál encaja con CI/CD y cuál no; configuraremos en GitHub las reglas que convierten los acuerdos de la lección 02-01 en algo que no depende de la buena voluntad; aprenderemos a evitar ejecuciones inútiles con paths y concurrency; analizaremos qué efecto tiene cada estrategia de merge sobre la trazabilidad del artefacto y sobre el cálculo del lead time; y terminaremos con el ci.yml completo de Reservalia, con sus cuatro jobs y sus dependencias, y con el balance de lo conseguido en el módulo.
Contenido
- Por qué el modelo de ramas decide el destino de tu CI
- Trunk-based, GitHub Flow y Git Flow cara a cara
- Ramas cortas y tamaño del pull request
- Proteger
main: checks obligatorios,CODEOWNERSy merge queue - Evitar ejecuciones inútiles:
pathsyconcurrency - Estrategias de merge, trazabilidad y lead time
- Entornos efímeros de previsualización por PR
- El
ci.ymlcompleto de Reservalia - Errores Comunes y Consejos
- Ejercicios
- Conclusión
- Por qué el modelo de ramas decide el destino de tu CI
Vuelve al integration hell de la lección 01-01: el coste de fusionar crece de forma no lineal con el tiempo que las ramas viven separadas. Ese hecho, por sí solo, ya determina qué modelos de ramas son compatibles con la CI.
Una rama de vida larga es un lote grande disfrazado. Mientras vive, no se está integrando nada —el pipeline verifica esa rama contra un main que se aleja cada día—; el verde es engañoso, porque "mi rama pasa" no significa "pasará cuando se fusione con lo que ha entrado mientras tanto"; y el riesgo se acumula: diez cambios pequeños fusionados a lo largo de dos semanas se diagnostican uno a uno, mientras que los mismos diez fusionados de golpe forman un único fallo con diez causas posibles.
La regla que resume el apartado. La frecuencia de integración es una variable del proceso, no de la herramienta. Ningún pipeline puede compensar ramas de tres semanas.
- Trunk-based, GitHub Flow y Git Flow cara a cara
| Trunk-based | GitHub Flow | Git Flow | |
|---|---|---|---|
| Ramas permanentes | main |
main |
main + develop |
| Ramas temporales | Muy cortas o ninguna | Una por funcionalidad | feature/, release/, hotfix/ |
| Vida de la rama | Horas, máx. 1 día | 1-3 días | Semanas |
| Frecuencia de integración | Varias veces al día | Diaria | Semanal o menos |
| Coste de merge | Casi nulo | Bajo | Alto |
| Encaje con CI/CD | Excelente | Muy bueno | Malo |
| Complejidad mental | Baja | Baja | Alta |
| Requiere feature flags | Sí, a menudo | A veces | Rara vez |
| Contexto donde brilla | Equipos con CI madura y despliegue continuo | La mayoría de equipos de producto | Software con versiones mantenidas en paralelo |
Tres precisiones que evitan malentendidos:
Git Flow no es "malo", está diseñado para otro problema. Nació en 2010 para software que se distribuye en versiones y mantiene varias a la vez —piensa en una aplicación de escritorio que da soporte a la 3.x mientras desarrolla la 4.0—. En ese contexto, las ramas release/ y hotfix/ tienen sentido. Aplicarlo a un SaaS con un único despliegue, como Reservalia, añade una rama develop que solo sirve para retrasar la integración.
GitHub Flow es el punto dulce para la mayoría. Una rama corta por cambio, un pull request, verificación automática, revisión y merge a main. Es lo que hace Reservalia, y es lo que hemos supuesto durante todo el módulo.
Trunk-based no significa "sin ramas ni revisión". Significa ramas de horas y merge diario. Cuando un cambio no se puede terminar en un día, se integra incompleto pero inactivo, escondido tras un feature flag —la técnica de la lección 03-05—. Esa es la habilidad que hay que aprender, y no una cuestión de disciplina.
- Ramas cortas y tamaño del pull request
Hay una variable que predice el tiempo de revisión mejor que ninguna otra: el número de líneas cambiadas.
| Tamaño del PR | Tiempo típico hasta el merge | Calidad de la revisión |
|---|---|---|
| < 100 líneas | Horas | Alta: se lee de verdad |
| 100-400 líneas | 1 día | Aceptable |
| 400-1.000 líneas | 2-4 días | Baja: se revisa en diagonal |
| > 1.000 líneas | Una semana o más | Casi nula: "LGTM" |
Y funciona como un bucle que se retroalimenta: un PR grande tarda en revisarse, y mientras espera acumula conflictos con main, lo que obliga a rehacer partes, lo que lo hace más grande. La salida del bucle es partir el trabajo.
Cómo se parte en la práctica, con el ejemplo de las reservas recurrentes de Reservalia:
- PR 1: migración que añade la columna
recurrenciaacitas, sin usarla. Cero riesgo. - PR 2: el tipo
Recurrenciaentipos-compartidosy la lógica de cálculo, con sus pruebas unitarias. Nadie la llama todavía. - PR 3: el endpoint que la usa, detrás de un flag desactivado.
- PR 4: la interfaz en
apps/web, también tras el flag. - PR 5: activación del flag.
Cinco PR de 100-200 líneas, cada uno revisable en un rato, cada uno integrado el mismo día. Y una propiedad valiosa: si algo falla, se sabe exactamente cuál de los cinco lo rompió.
- Proteger
main: checks obligatorios, CODEOWNERS y merge queue
main: checks obligatorios, CODEOWNERS y merge queueLos acuerdos de la lección 02-01 —"nadie empuja a main", "no se fusiona en rojo"— siguen dependiendo de que todo el mundo se acuerde. Las reglas de protección de rama los convierten en algo que el sistema hace cumplir.
Configuración de Reservalia para main:
| Regla | Qué impide | Por qué |
|---|---|---|
| Require a pull request before merging | git push directo a main |
Todo cambio pasa por verificación y revisión |
Require status checks to pass: calidad, test, build |
Fusionar en rojo | Es la regla 3 del acuerdo, ya no negociable |
| Require branches to be up to date | Fusionar sobre una base antigua | Evita el "verde que se rompe al fusionar" |
| Require 1 approval | Fusionar tu propio código sin revisión | Segunda mirada sobre el diseño |
| Dismiss stale approvals | Aprobar y luego cambiar el código | La aprobación se refiere a un diff concreto |
| Require linear history | Historial en forma de espagueti | Un main lineal es legible y bisecable |
| Block force pushes | Reescribir el historial de main |
Un force-push a main es irreversible en la práctica |
| Include administrators | Que Marta se salte sus propias reglas | Una excepción convierte la regla en sugerencia |
CODEOWNERS declara quién debe revisar según la ruta tocada. Se guarda en .github/CODEOWNERS:
# Por defecto, cualquier cambio lo revisa el equipo
* @reservalia/equipo
# Las migraciones y el pipeline necesitan mirada experta
apps/api/src/db/migraciones/ @reservalia/marta @reservalia/nuria
.github/workflows/ @reservalia/nuria
infra/ @reservalia/nuriaCombinado con "require review from Code Owners", garantiza que un cambio en una migración no se fusione sin que lo vea alguien que entiende las consecuencias.
La merge queue resuelve un problema real y poco conocido. Escenario: los PR A y B están ambos verdes, ambos partiendo del mismo main. A se fusiona. B sigue diciendo verde, pero nunca se probó junto a A. Si A renombró una función que B usa, main se pone roja después del merge, sin que ningún PR estuviera en rojo.
flowchart LR
A["PR A verde<br/>base: main@X"] --> Q["merge queue"]
B["PR B verde<br/>base: main@X"] --> Q
Q --> C1["prueba A sobre main@X"] --> C2["prueba B sobre main@X+A"]
C2 -- verde --> M["merge de A y B"]
C2 -- rojo --> R["B sale de la cola<br/>main sigue sana"]
La cola construye una rama temporal con los cambios ya encolados y verifica cada PR contra el resultado de los anteriores. Con dos o tres PR al día no compensa; a partir de una decena diaria sobre el mismo repositorio, evita que main se rompa varias veces por semana. Reservalia no la necesita hoy; sí la necesitaría con quince desarrolladores.
- Evitar ejecuciones inútiles:
paths y concurrency
paths y concurrencyCada ejecución cuesta minutos y, sobre todo, cuesta atención. Dos mecanismos evitan gastarlos en balde.
concurrency: cancelar ejecuciones obsoletas. Diego empuja tres veces seguidas a su rama en diez minutos. Sin configuración, tendrás tres pipelines completos corriendo a la vez, y solo el último importa:
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }} # una cola por rama
cancel-in-progress: true # cancela la anteriorgithub.ref identifica la rama, así que cada rama tiene su propia cola y los PR no se cancelan entre sí. Aviso importante: en main conviene no cancelar (cancel-in-progress: false o una condición sobre la rama), porque cada commit de main produce un artefacto publicable y no quieres perder ninguno.
paths: no ejecutar lo que no aplica. Un cambio en un .md no necesita construir imágenes. La forma robusta no es filtrar el evento entero —ya vimos en la 02-02 que eso deja los checks obligatorios esperando para siempre—, sino detectar qué ha cambiado y saltarse el trabajo caro, manteniendo el check verde:
- uses: dorny/paths-filter@v3
id: cambios
with:
filters: |
codigo:
- 'apps/**'
- 'packages/**'
- 'package-lock.json'
- name: Construir la imagen
if: steps.cambios.outputs.codigo == 'true' # ← el step se salta, el job sale verde
run: docker build -f apps/api/Dockerfile .Así el check build siempre reporta un resultado, y el PR de documentación se fusiona sin esperar tres minutos por nada.
- Estrategias de merge, trazabilidad y lead time
Cómo se integra un PR en main tiene consecuencias que van más allá del estilo.
| Estrategia | Qué deja en main |
Efecto en la trazabilidad | Efecto en el lead time |
|---|---|---|---|
| Merge commit | Todos los commits del PR + un commit de fusión | Historial completo pero ramificado; git bisect se complica |
El primer commit puede ser muy anterior al merge |
| Squash | Un solo commit por PR | Un commit = un cambio = un artefacto; ideal para bisect | Se pierden las fechas intermedias |
| Rebase | Los commits del PR, reescritos sobre main |
Historial lineal y detallado | Cada commit conserva su fecha original |
Reservalia usa squash, y las razones son concretas:
- Un commit de
main= un artefacto. Como el jobpublicaretiqueta la imagen con el SHA, unmaincon un commit por PR hace quereservalia/api:a3f9c21se corresponda exactamente con un pull request revisable. Con merge commits, un solo merge introduce varios SHA y la correspondencia se difumina. git bisectfunciona bien. Cada commit demaines un estado completo y verificado. Con merge commits te tropiezas con commits intermedios rotos ("wip", "arreglando el test").- Los commits de trabajo dejan de importar. Diego puede hacer quince commits con mensajes de andar por casa; lo que queda escrito es el título del PR, que es lo que valida commitlint (lección 02-05).
Ahora el efecto sobre el lead time for changes de la lección 01-05, que se calcula desde la fecha del commit hasta el despliegue:
- Con squash, el commit resultante nace en el momento del merge, así que el lead time medido cubre solo merge → despliegue y subestima el tiempo real: no cuenta lo que el cambio pasó esperando revisión.
- Con merge commit o rebase, se conserva la fecha del primer commit y el lead time incluye toda la espera, con lo que refleja mejor la realidad.
Si usas squash —como Reservalia—, la medición honesta consiste en tomar como origen la fecha del primer commit del PR (dato que la API de GitHub proporciona) en lugar de la del commit fusionado. No es un detalle menor: es la diferencia entre medir 40 minutos y medir los 6,2 días reales de la línea base.
- Entornos efímeros de previsualización por PR
Un entorno de previsualización es un despliegue temporal y aislado del código de un pull request, con su propia URL: pr-482.dev.reservalia.com. Nace al abrir el PR y se destruye al cerrarlo.
Para qué sirve, en orden de valor real: Marta abre el enlace y ve funcionar el cambio en lugar de imaginárselo leyendo el diff; se pueden ejecutar contra él las pruebas E2E críticas de la 02-04; y alguien de negocio valida el cambio sin instalar nada.
Y lo que hay que tener en cuenta antes de montarlo: cuesta dinero (cada PR abierto consume recursos, y sin destrucción automática se acumulan), necesita datos (una base de datos por entorno, poblada con datos ficticios: nunca una copia de producción con datos de clientes reales) y no todo lo merece: en Reservalia tiene mucho más sentido para apps/web, que es visual y barata de desplegar en S3, que para apps/api.
La mecánica de despliegue y destrucción es materia del módulo 3; aquí basta con conocer el concepto y saber que el artefacto ya está listo para alimentarlo.
- El
ci.yml completo de Reservalia
ci.yml completo de ReservaliaEste es el resultado del módulo entero, con las partes ya explicadas resumidas para que se vea la estructura:
# .github/workflows/ci.yml
name: CI
on:
pull_request: { branches: [main] }
push: { branches: [main] }
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} # nunca cancelar main
env:
TZ: Europe/Madrid
jobs:
calidad: # ~50 s
name: Calidad
runs-on: ubuntu-22.04
timeout-minutes: 10
steps:
# checkout · setup-node (.nvmrc + cache) · npm ci
- run: npx prettier --check .
- run: npm run lint # --max-warnings 0
- run: npm run typecheck # tsc --noEmit
test: # ~3 min
name: Pruebas
runs-on: ubuntu-22.04
timeout-minutes: 15
services:
postgres:
image: postgres:16.3
env: { POSTGRES_USER: reservalia, POSTGRES_PASSWORD: ci, POSTGRES_DB: reservalia_test }
ports: ['5432:5432']
options: --health-cmd "pg_isready -U reservalia -d reservalia_test" --health-retries 10
env:
DATABASE_URL: postgres://reservalia:ci@localhost:5432/reservalia_test
steps:
# checkout · setup-node · npm ci
- run: npm run test:unidad --workspaces --if-present
- run: npm run migrate --workspace apps/api
- run: npm run test:integracion --workspace apps/api
- run: npm run test --workspace apps/api -- --coverage
build: # ~4 min
name: Construcción
runs-on: ubuntu-22.04
timeout-minutes: 15
steps:
# checkout · setup-node · npm ci
- run: npm run build
- run: test -f apps/api/dist/index.js && test -d apps/web/dist
- uses: docker/build-push-action@v5
with: { context: ., file: apps/api/Dockerfile, push: false,
cache-from: 'type=gha', cache-to: 'type=gha,mode=max' }
publicar: # ~2 min · solo en main
name: Publicar artefacto
runs-on: ubuntu-22.04
needs: [calidad, test, build]
if: github.ref == 'refs/heads/main'
permissions: { id-token: write, contents: read }
steps:
# checkout · credenciales OIDC de AWS · login en ECR
- uses: docker/build-push-action@v5
with: { context: ., file: apps/api/Dockerfile, push: true,
tags: '${{ steps.ecr.outputs.registry }}/reservalia/api:${{ steps.meta.outputs.sha_corto }}' }flowchart LR
E["pull_request / push a main"] --> Q["calidad ~50 s"]
E --> T["test ~3 min"]
E --> B["build ~4 min"]
Q --> P["publicar ~2 min<br/>solo en main"]
T --> P
B --> P
Tres propiedades de este diseño que conviene subrayar:
calidad,testybuildcorren en paralelo. El tiempo total de un PR es el del job más lento —unos 4 minutos—, no la suma de los tres. Muy por debajo del límite de 10 minutos que fijó el equipo.publicardepende de los tres y solo se ejecuta enmain. Un PR nunca publica; unmainverde siempre deja artefacto.- Los tres primeros son los checks obligatorios de la regla de protección de rama del apartado 4. Sin ellos en verde, el botón de fusionar está desactivado.
Errores Comunes y Consejos
Error 1: ramas de vida larga con un pipeline excelente. Es el error que resume el módulo. Ningún YAML compensa integrar cada tres semanas.
Error 2: adoptar Git Flow por costumbre. Si tu producto tiene un único despliegue y no mantienes versiones antiguas, la rama develop solo sirve para retrasar la integración. Error 3: no marcar "include administrators"; el día que alguien con permisos se salta el check "porque corre prisa", la regla deja de existir para todos.
Error 4: filtrar con paths un evento cuyo check es obligatorio. El PR queda esperando eternamente un resultado que nunca llegará. Filtra a nivel de step, no de evento.
Error 5: cancelar ejecuciones en main. cancel-in-progress: true sin excepción para main te deja commits fusionados sin artefacto publicado.
Consejo 1: mide el tamaño medio de tus PR. Si supera las 400 líneas, el problema del equipo no es el pipeline: es cómo se parte el trabajo.
Consejo 2: revisa los tiempos del pipeline cada mes. Es la métrica que se degrada más silenciosamente. Trátala como un presupuesto: para añadir tres minutos, busca de dónde quitarlos.
Consejo 3: escribe las reglas de protección en el README.md; que el equipo sepa qué se exige y por qué reduce la fricción y las peticiones de excepción.
Ejercicios
Ejercicio 1
Un equipo de 6 personas desarrolla un SaaS con despliegue único. Usa Git Flow: ramas feature/ de 2-3 semanas, develop, ramas release/ semanales y hotfix/. Tienen un pipeline completo y bien hecho. Explica tres razones por las que no practican Integración Continua y propón la transición, indicando qué cambiar primero.
Ejercicio 2
Los PR A y B están verdes sobre main@X. A renombra calcularHuecos a calcularDisponibilidad y actualiza sus llamadas. B añade una llamada nueva a calcularHuecos. Se fusionan ambos. Describe qué ocurre, por qué ninguna regla de protección lo evitó y qué dos mecanismos lo habrían impedido.
Ejercicio 3
Reservalia mide un lead time de 41 minutos, pero Marta sabe que un cambio tarda días desde que se empieza. Explica de dónde viene la discrepancia y cómo corregir la medición.
Soluciones
Solución 1. Tres razones: (1) las ramas feature/ de 2-3 semanas violan la práctica central de integrar al menos a diario, así que el pipeline verifica ramas cada vez más divergentes de develop; (2) develop actúa como un almacén intermedio: el código está "integrado" ahí, pero main —lo que de verdad se despliega— solo lo recibe semanalmente, con lo que la integración real es semanal; (3) las ramas release/ implican que el software se estabiliza después de desarrollarse, lo contrario de "la rama principal siempre desplegable".
Transición, por orden: primero acortar las ramas (partir el trabajo en PR de menos de 400 líneas, con feature flags para lo incompleto), porque es el cambio que produce el beneficio y el más difícil; segundo, eliminar develop y hacer que los PR vayan directos a main; tercero, suprimir las ramas release/ desplegando desde main cuando corresponda; cuarto, activar las reglas de protección con los checks obligatorios. Empezar por la configuración sin acortar las ramas no cambiaría nada.
Solución 2. Al fusionar A, main deja de tener calcularHuecos. B sigue verde porque se verificó contra main@X, donde la función todavía existía; al fusionarse, main se rompe: fallará el typecheck del job calidad y probablemente las pruebas. Ningún PR estuvo nunca en rojo.
No lo evitó ninguna regla porque las reglas comprueban el estado del PR, no el resultado de combinarlo con lo que se ha fusionado entre medias. Los dos mecanismos que lo impiden: (a) require branches to be up to date before merging, que obliga a B a actualizarse con main —y entonces su pipeline falla antes del merge, como debe—; y (b) la merge queue, que prueba B sobre el resultado de A antes de fusionarlo y lo saca de la cola si falla. La primera es gratis y basta para equipos pequeños; la segunda escala mejor con volumen alto de PR.
Solución 3. La discrepancia viene de la estrategia de squash. Al fusionar, git crea un commit nuevo cuya fecha es la del merge, de modo que el git show -s --format=%cI que usábamos en la 01-05 mide únicamente el tramo merge → despliegue, que en Reservalia son unos 41 minutos: el tiempo del pipeline y del despliegue. Todo lo anterior —desarrollo, espera de revisión, correcciones— desaparece del cálculo.
Corrección: tomar como origen la fecha del primer commit del pull request, disponible en la API de GitHub, y guardarla en la tabla despliegues junto al SHA. El lead time pasa a medirse desde que el trabajo empezó de verdad. Como validación cruzada, conviene comparar esa cifra con el tiempo medio entre la apertura del PR y su merge; si difieren mucho, el cuello de botella está antes de abrir el PR.
Conclusión
Con esta lección se cierra el módulo 2, y conviene mirar de dónde venimos. Al empezar, Reservalia no tenía nada: .github/workflows/ estaba vacío, Diego compilaba en su portátil y las pruebas se ejecutaban "cuando alguien se acordaba". Ahora:
- El equipo tiene seis reglas escritas antes que una sola línea de YAML, y las prácticas que constituyen la CI de verdad: integración diaria, build automática,
mainsiempre desplegable, stop the line y feedback rápido. - Un
ci.ymlque se dispara en cada pull request y en cada push amain, sobre runners fijados, con Node leído del.nvmrcy un PostgreSQL 16.3 con healthcheck para las pruebas. - Una build reproducible con
npm ciy el lockfile, y unDockerfilemulti-etapa con imagen base fijada, usuario no root y.dockerignore. - Pruebas unitarias y de integración con criterio sobre qué bloquea el merge, cobertura tratada como señal y una política de cuarentena para las pruebas inestables.
- Un job
calidadcon Prettier, ESLint a--max-warnings 0ytsc --noEmit, y un plan realista para reducir la deuda sin parar el equipo. - Un job
publicarque sube a ECR un artefacto inmutable identificado por el SHA, listo para promocionarse sin reconstruirse, y un endpoint/versionpara saber siempre qué está corriendo. - Y las reglas de protección de
mainque convierten los acuerdos en algo que el sistema hace cumplir, junto conCODEOWNERS,concurrencyy una estrategia de merge —squash— elegida por sus consecuencias sobre la trazabilidad, no por gusto.
En cuanto a las métricas DORA de la lección 01-05, el módulo ha atacado sobre todo el change failure rate: cada cambio se verifica en una máquina limpia antes de fusionarse. El lead time también ha mejorado, aunque de forma parcial, porque los PR son más pequeños. Pero las otras dos métricas siguen intactas, y la razón es simple: el artefacto existe, está publicado y verificado… y sigue siendo Diego quien lo despliega a mano. El ritual del viernes continúa. Hemos automatizado la mitad izquierda del diagrama que dibujamos en la 01-01 y no hemos tocado la derecha.
Eso es exactamente lo que arranca en el módulo 3, Despliegue Continuo (CD). La primera lección, Introducción al Despliegue Continuo, retoma la distinción entre Entrega Continua y Despliegue Continuo —ahora con un pipeline real delante— y define qué necesita un equipo antes de dejar que una máquina toque producción: entornos reproducibles, migraciones seguras, capacidad de volver atrás y observabilidad suficiente para enterarse antes que el cliente. A partir de ahí, el artefacto reservalia/api:a3f9c21 que hoy espera en ECR empezará a viajar solo hasta dev, staging y prod, y el viernes por la tarde volverá a ser, sencillamente, un viernes por la tarde.
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
