Si has llegado hasta aquí es porque en algún momento has vivido —o te han contado— una escena parecida a esta: viernes por la tarde, alguien compila el proyecto en su portátil, sube los ficheros a un servidor y cruza los dedos. Esta lección es el punto de partida para dejar atrás esa escena. Vamos a definir con precisión qué significan las siglas CI/CD, a distinguir las tres prácticas que se esconden detrás de ellas (porque son tres, no dos) y a fijar el vocabulario que usaremos durante todo el curso. No es una lección de herramientas ni de configuración: es la lección que hace que todo lo demás tenga sentido. Si confundes Entrega Continua con Despliegue Continuo —el error más habitual del sector—, el resto del curso te sonará a ruido. Cuando termines, sabrás nombrar cada pieza del proceso y entenderás por qué el equipo de nuestro proyecto de ejemplo, Reservalia, tiene un problema serio.

Contenido

  1. El problema que CI/CD viene a resolver
  2. Qué es la Integración Continua (CI)
  3. Qué es la Entrega Continua (Continuous Delivery)
  4. Qué es el Despliegue Continuo (Continuous Deployment)
  5. Las dos "CD" cara a cara
  6. El flujo completo: de commit a producción
  7. Vocabulario base del curso
  8. Errores comunes y consejos
  9. Ejercicios
  10. Conclusión

  1. El problema que CI/CD viene a resolver

1.1. El punto de partida de Reservalia

Durante todo el curso trabajaremos sobre un proyecto ficticio llamado Reservalia, una plataforma SaaS de reservas de cita para pequeños negocios: peluquerías, clínicas dentales, talleres mecánicos. El equipo es pequeño: Marta (tech lead), Diego (desarrollador backend) y Nuria (SRE). En la lección 01-04 lo veremos en detalle; de momento solo nos interesa cómo trabajan hoy:

  • Diego compila en su portátil. La versión de Node que tiene instalada no es exactamente la del servidor.
  • Sube los ficheros resultantes por SFTP a un único servidor de producción.
  • Ejecuta las migraciones de base de datos a mano, pegando SQL en una consola de psql.
  • Las pruebas se ejecutan "cuando alguien se acuerda".
  • Todo esto ocurre los viernes por la tarde y dura unas 3 horas.
  • Resultado: dos incidencias graves en producción el último trimestre.

Este proceso no es "malo" por descuido: es malo por diseño. Cada uno de esos pasos depende de que una persona concreta, en un momento concreto, no se equivoque. Y las personas nos equivocamos.

1.2. El "integration hell"

Hay un segundo problema, menos visible pero igual de caro. Imagina que Marta y Diego trabajan cada uno en su rama durante dos semanas:

  • Marta reescribe el sistema de notificaciones por correo.
  • Diego cambia el modelo de datos de las citas para soportar reservas recurrentes.

Ninguno de los dos toca el trabajo del otro aparentemente. Pero el día que intentan fusionar ambas ramas, aparecen conflictos en 40 ficheros, la firma de una función que ambos usan ha cambiado, y las pruebas de Marta fallan por un cambio de esquema de Diego. Lo que debería haber sido una tarde se convierte en tres días de "resolver la integración".

Eso es el integration hell (infierno de la integración): el coste de fusionar aumenta de forma no lineal con el tiempo que las ramas viven separadas.

graph LR
    subgraph "Integración tardía: dolor concentrado"
        A1[Día 1] --> A2[Día 5] --> A3[Día 10] --> A4["Día 14<br/>MERGE<br/>3 días de conflictos"]
    end
    subgraph "Integración continua: dolor repartido"
        B1["Día 1<br/>merge"] --> B2["Día 2<br/>merge"] --> B3["Día 3<br/>merge"] --> B4["Día 14<br/>merge<br/>10 minutos"]
    end

La intuición clave, que se repetirá en todo el curso: si algo duele, hazlo más a menudo. Fusionar duele porque lo haces poco. Desplegar duele porque lo haces poco. La respuesta contraintuitiva de CI/CD es aumentar la frecuencia hasta que cada operación individual sea trivial.

  1. Qué es la Integración Continua (CI)

Definición. La Integración Continua es la práctica de que cada miembro del equipo integre su trabajo en la línea principal de desarrollo al menos una vez al día, y de que cada integración sea verificada automáticamente por un proceso de construcción y pruebas que se ejecuta en un entorno limpio y compartido.

Hay tres ideas dentro de esa definición, y las tres son igual de importantes:

  1. Integrar a menudo. El código de cada persona vuelve a la rama principal en horas, no en semanas. Si tu rama vive tres semanas, no estás haciendo CI aunque tengas un servidor de CI configurado.
  2. Verificar automáticamente. No basta con fusionar: un sistema automático compila, ejecuta las pruebas y comprueba la calidad. Sin verificación automática, integrar a menudo solo significa romper la rama principal más a menudo.
  3. En un entorno limpio y compartido. No en el portátil de Diego. En una máquina que parte de cero cada vez, para que "en mi máquina funciona" deje de ser una frase válida.

2.1. Lo que CI no es

Conviene desactivar tres malentendidos muy extendidos:

Malentendido Realidad
"Tenemos CI porque tenemos un servidor de CI" Si las ramas viven semanas, tienes un servidor de builds, no Integración Continua.
"CI significa ejecutar tests" Ejecutar tests es parte de CI. CI es la práctica de integrar; los tests son el mecanismo de verificación.
"CI es cosa de la herramienta" CI es sobre todo un acuerdo de equipo: qué se hace cuando la build falla, cuánto puede vivir una rama, quién arregla qué.

2.2. El contrato implícito de CI

Cuando un equipo adopta CI de verdad, firma un contrato tácito:

  • La rama principal siempre está sana. Si la build está roja, arreglarla es la prioridad número uno del equipo, por encima de cualquier funcionalidad.
  • Nadie se va a casa con la build rota. Se revierte el cambio y se investiga con calma al día siguiente.
  • Cada cambio se verifica antes de integrarse, no después.

Sin ese contrato, la automatización se convierte en un semáforo que todo el mundo ignora. Volveremos sobre esto en el módulo 2.

  1. Qué es la Entrega Continua (Continuous Delivery)

Definición. La Entrega Continua es la práctica de mantener el software siempre en un estado desplegable, de manera que cualquier versión que haya pasado el pipeline pueda llevarse a producción pulsando un botón, en cualquier momento, con un riesgo conocido.

La Entrega Continua da por supuesta la Integración Continua y añade una capa por encima: no basta con que el código compile y pase los tests; hace falta que exista un artefacto construido, versionado, probado en entornos parecidos a producción y listo para desplegarse.

La frase clave es "pulsando un botón". En Entrega Continua:

  • El proceso técnico de desplegar está completamente automatizado.
  • La decisión de desplegar sigue siendo humana.

Esa decisión humana no es un fallo del sistema: es una elección deliberada. Puede haber razones perfectamente legítimas para no desplegar automáticamente:

  • Una campaña de marketing que arranca el martes y la funcionalidad no debe verse antes.
  • Un requisito de cumplimiento normativo que exige aprobación registrada.
  • Un equipo que aún no confía lo suficiente en su suite de pruebas.

Lo importante es que, cuando alguien decide desplegar, no hay trabajo manual que hacer: solo autorizar.

  1. Qué es el Despliegue Continuo (Continuous Deployment)

Definición. El Despliegue Continuo es la práctica de que todo cambio que supera el pipeline automatizado se despliegue en producción automáticamente, sin intervención humana.

Es la Entrega Continua sin el botón. Se elimina la puerta manual: si el pipeline está verde, el cambio llega a los usuarios. Sin reuniones, sin ventanas de despliegue, sin viernes por la tarde.

Esto suena temerario y, sin una base sólida, lo es. El Despliegue Continuo solo funciona si se apoya en:

  • Una suite de pruebas en la que el equipo confía de verdad (módulo 2).
  • Estrategias de despliegue progresivo —canary, blue-green— para limitar el radio de impacto (módulo 3).
  • Feature flags para separar "desplegar código" de "activar funcionalidad" (módulo 3).
  • Rollback automático cuando las métricas se degradan (módulo 3).
  • Monitorización que detecte el problema antes que el cliente (módulo 3).

Fíjate en algo importante: el Despliegue Continuo no es el objetivo obligatorio de todo equipo. Es una opción. Muchísimas organizaciones excelentes se quedan deliberadamente en Entrega Continua. Lo que sí es innegociable es la capacidad de desplegar en cualquier momento; usarla automáticamente o no es una decisión de contexto.

  1. Las dos "CD" cara a cara

Aquí está el núcleo de la lección. Las siglas CI/CD son ambiguas a propósito y eso genera confusión constante en entrevistas, documentación y conversaciones de equipo.

Aspecto Integración Continua (CI) Entrega Continua (Continuous Delivery) Despliegue Continuo (Continuous Deployment)
Qué automatiza Construcción y pruebas de cada cambio integrado Todo lo de CI + empaquetado, versionado y despliegue a entornos previos (dev, staging) Todo lo de Delivery + despliegue a producción
Dónde está la puerta manual Al fusionar a la rama principal (revisión de código) Antes de producción: alguien pulsa "Deploy" No hay puerta manual
Quién decide desplegar No aplica: CI no despliega Una persona (tech lead, product owner, responsable de release) El pipeline: si está verde, sale
Resultado del proceso Una build verificada Un artefacto listo para producción en cualquier momento Un cambio ya en producción
Pregunta que responde "¿Este cambio rompe algo?" "¿Podríamos desplegar ahora mismo?" "¿Ya está desplegado?"
Requisito previo Control de versiones y pruebas automatizadas CI sólida + entornos reproducibles Delivery sólida + despliegue progresivo + monitorización + rollback
Riesgo si falta madurez Builds rojas ignoradas Artefactos que nadie se atreve a desplegar Incidentes en producción a diario

Una forma de recordarlo que funciona muy bien:

  • Delivery = "podemos desplegar cuando queramos" → la capacidad está automatizada, la decisión es humana.
  • Deployment = "desplegamos siempre que el pipeline lo permite" → también la decisión está automatizada.

Y una relación de inclusión que conviene tener grabada:

graph TD
    CD2["Despliegue Continuo<br/>(Continuous Deployment)"] --> CD1["Entrega Continua<br/>(Continuous Delivery)"]
    CD1 --> CI["Integración Continua<br/>(CI)"]
    CI --> VCS["Control de versiones + pruebas automatizadas"]

    style CD2 fill:#c9e4ff,stroke:#333
    style CD1 fill:#d9f2d9,stroke:#333
    style CI fill:#fff2cc,stroke:#333

Se lee de abajo arriba: no puede haber Despliegue Continuo sin Entrega Continua, ni Entrega Continua sin Integración Continua. Cualquier intento de saltarse un escalón produce un sistema frágil. Si Reservalia intentara mañana desplegar automáticamente a producción sin pruebas fiables, no tendría dos incidencias por trimestre: tendría dos por semana.

  1. El flujo completo: de commit a producción

Veamos el recorrido que hará un cambio de Diego a lo largo de todo el curso. Este diagrama es el mapa mental del curso entero:

flowchart LR
    A["👤 Diego<br/>hace un commit"] --> B["📥 push / pull request<br/>al repositorio"]
    B -->|trigger| C{{"Pipeline arrancado"}}
    C --> D["🔨 Etapa: Build<br/>compilar, instalar dependencias"]
    D --> E["🧪 Etapa: Test<br/>unitarias, integración, lint"]
    E --> F["📦 Artefacto<br/>imagen Docker versionada"]
    F --> G["🗄️ Registro de artefactos<br/>ECR"]
    G --> H["🚀 Despliegue a dev"]
    H --> I["🚀 Despliegue a staging"]
    I --> J{"¿Puerta manual?"}
    J -->|"Sí → Entrega Continua"| K["👤 Alguien aprueba"]
    J -->|"No → Despliegue Continuo"| L
    K --> L["🚀 Despliegue a prod"]
    L --> M["📊 Monitorización<br/>y feedback"]
    M -.->|"si algo falla"| N["⏪ Rollback"]

Lee el diagrama identificando dónde encaja cada práctica:

  • De A a E (commit → build → test): esto es Integración Continua. Lo construiremos en el módulo 2.
  • De F a I (artefacto → registro → dev → staging): esto es Entrega Continua. Módulos 2 y 3.
  • El paso J → L sin intervención humana: esto es Despliegue Continuo. Módulo 3.
  • M y N (monitorización y rollback): la red de seguridad que hace posible lo anterior. Módulo 3.

  1. Vocabulario base del curso

Fijemos ahora los términos. Los usaremos sin volver a definirlos, así que merece la pena leer esta sección con calma. Los agrupo por familias.

7.1. Familia "control de versiones"

Término Definición Ejemplo en Reservalia
Repositorio Almacén del código fuente y su historia completa de cambios. github.com/reservalia/reservalia
Commit Una unidad de cambio confirmada, con autor, fecha, mensaje y un identificador único (SHA). a3f9c21 — "fix: validar solapamiento de citas"
Rama (branch) Una línea de desarrollo paralela que puede fusionarse después en otra. main, feat/reservas-recurrentes
Pull request / merge request Propuesta de fusionar una rama en otra, que abre revisión y verificación automática. PR #142 de Diego hacia main

Un detalle que usaremos mucho: el SHA del commit es la identidad canónica de un cambio. Cuando en el módulo 3 nos preguntemos "¿qué versión exacta hay en producción?", la respuesta correcta nunca será "la última", sino un SHA concreto.

# El SHA identifica de forma única el estado del código.
# Este comando devuelve el SHA corto del commit actual:
git rev-parse --short HEAD
# → a3f9c21

# Y este, la fecha exacta del commit en formato ISO 8601.
# La usaremos en la lección 01-05 para calcular el lead time.
git show -s --format=%cI HEAD
# → 2026-03-14T10:22:41+01:00

7.2. Familia "ejecución del pipeline"

Término Definición Matiz importante
Pipeline La secuencia completa y automatizada que lleva un cambio desde el commit hasta su destino. Es el concepto paraguas: contiene etapas, que contienen jobs, que contienen pasos.
Trigger (disparador) El evento que inicia una ejecución del pipeline. push a una rama, apertura de un PR, una etiqueta, un horario (cron), una ejecución manual.
Stage (etapa) Agrupación lógica de trabajo dentro del pipeline, normalmente secuencial. buildtestdeploy. Una etapa suele esperar a que termine la anterior.
Job (trabajo) Unidad de ejecución independiente dentro de una etapa. Varios jobs de la misma etapa pueden correr en paralelo. test-api y test-web corren a la vez.
Step (paso) Un comando o acción concreta dentro de un job, en orden. npm ci, luego npm test.
Runner / agente La máquina (física, virtual o contenedor) donde se ejecuta un job. Un runner Ubuntu efímero que se destruye al acabar.

La jerarquía, visualmente:

graph TD
    P["PIPELINE<br/>(disparado por un trigger)"]
    P --> S1["ETAPA: build"]
    P --> S2["ETAPA: test"]
    P --> S3["ETAPA: deploy"]
    S2 --> J1["JOB: test-api<br/>en runner ubuntu"]
    S2 --> J2["JOB: test-web<br/>en runner ubuntu"]
    J1 --> ST1["paso: npm ci"]
    J1 --> ST2["paso: npm run test"]

Sobre los runners hay una distinción que importará mucho más adelante:

  • Efímero: se crea limpio para cada job y se destruye al terminar. Garantiza reproducibilidad. Es el modelo por defecto de GitHub Actions.
  • Persistente: una máquina que se reutiliza entre ejecuciones. Es más rápido (conserva cachés) pero acumula estado, y ese estado es una fuente clásica de builds que "funcionan solo la segunda vez". Típico de instalaciones antiguas de Jenkins.

7.3. Familia "resultado y destino"

Término Definición Ejemplo en Reservalia
Artefacto El producto empaquetado y versionado de una construcción, listo para desplegar o distribuir. La imagen Docker reservalia/api:a3f9c21
Registro de artefactos Almacén versionado donde se publican y se recuperan los artefactos. Amazon ECR
Entorno Una instancia desplegada y ejecutable del sistema, con su propia configuración y sus propios datos. dev, staging, prod
Promoción Llevar el mismo artefacto ya construido de un entorno al siguiente, sin reconstruirlo. Promocionar api:a3f9c21 de staging a prod
Build reproducible Propiedad por la cual construir el mismo commit produce siempre un artefacto funcionalmente equivalente. Fijar Node 20.11.0 y usar npm ci con package-lock.json

Los dos últimos merecen desarrollo, porque son los que más se malinterpretan.

Promoción: construir una vez, desplegar muchas. Es una de las reglas de oro de CI/CD. El artefacto que se prueba en staging debe ser el mismísimo binario que llega a producción, byte a byte. Si reconstruyes para producción, estás desplegando algo que nadie ha probado nunca.

graph LR
    C["commit a3f9c21"] --> B["BUILD<br/>una sola vez"]
    B --> ART["artefacto<br/>api:a3f9c21"]
    ART --> D["dev"]
    ART --> S["staging"]
    ART --> P["prod"]

    style ART fill:#d9f2d9,stroke:#333,stroke-width:2px

Y lo que no hay que hacer:

graph LR
    C["commit a3f9c21"] --> B1["build para dev"] --> D["dev"]
    C --> B2["build para staging"] --> S["staging"]
    C --> B3["build para prod ⚠️<br/>artefacto nunca probado"] --> P["prod"]

    style B3 fill:#ffd6d6,stroke:#c00,stroke-width:2px

Si el artefacto es el mismo en los tres entornos, ¿cómo cambia entonces la configuración? Por fuera: variables de entorno y secretos inyectados en el momento del despliegue. El artefacto no sabe en qué entorno vive.

# El MISMO artefacto, distinta configuración según el entorno.
# En staging:
DATABASE_URL="postgres://reservalia@rds-staging:5432/reservalia"
LOG_LEVEL="debug"

# En producción:
DATABASE_URL="postgres://reservalia@rds-prod:5432/reservalia"
LOG_LEVEL="info"

Build reproducible. Que dos construcciones del mismo commit den el mismo resultado no es automático: hay que ganárselo. Los enemigos habituales son:

  • Versiones de herramientas no fijadas (node a secas en vez de [email protected]).
  • Dependencias sin fichero de bloqueo, que resuelven a la última versión disponible.
  • Instalar con npm install (que puede modificar el lock) en vez de npm ci (que lo respeta estrictamente).
  • Marcas de tiempo o rutas absolutas incrustadas en el artefacto.
# ❌ No reproducible: "^4.18.0" puede resolver a 4.18.2 hoy y a 4.19.0 mañana
npm install

# ✅ Reproducible: instala EXACTAMENTE lo que dice package-lock.json
# y falla si el lock y el package.json no son coherentes
npm ci

Este es exactamente el problema de Diego: compila en su portátil, con su versión de Node y sus node_modules acumulados durante meses. Su build no es reproducible, y por eso nadie puede reconstruir lo que hay en producción.

Errores Comunes y Consejos

Error 1: creer que "CD" siempre significa lo mismo. Cuando alguien dice "tenemos CI/CD", pregunta siempre: "¿el despliegue a producción lo lanza una persona o el pipeline?". Es la única pregunta que desambigua. En una entrevista de trabajo, distinguir Delivery de Deployment y explicar por qué se elige una u otra te sitúa por delante de la mayoría de candidatos.

Error 2: pensar que CI/CD es una herramienta que se instala. GitHub Actions no te da Integración Continua, igual que comprar unas zapatillas no te da forma física. La herramienta ejecuta; la práctica la sostiene el equipo. Un equipo con ramas de tres semanas y un servidor de CI carísimo no hace CI.

Error 3: reconstruir el artefacto en cada entorno. Si el deploy a producción vuelve a compilar, lo que llega a los usuarios no es lo que se validó en staging. Construye una vez, promociona el mismo artefacto. Lo formalizaremos en la lección 02-06.

Error 4: confundir despliegue con release. Desplegar es poner el código en producción; hacer release es activar la funcionalidad para los usuarios. Con feature flags puedes desplegar el lunes y activar el jueves. Son dos operaciones distintas y separarlas reduce muchísimo el riesgo. Lo veremos en 03-05.

Error 5: usar ramas de larga duración y llamarlo CI. Si tu rama tiene 60 commits y dos semanas de vida, integrarás mal aunque tengas mil tests verdes. La frecuencia de integración es la práctica; los tests son el mecanismo.

Consejo 1: empieza midiendo, no automatizando. Antes de escribir tu primer workflow, apunta cuánto tarda hoy tu despliegue y cuántas veces al mes falla. Sin línea base no podrás demostrar que la inversión ha valido la pena. La lección 01-05 va justo de esto.

Consejo 2: el pipeline es código de producción. Vive en el repositorio, se revisa en pull requests y se versiona igual que el resto. Un .github/workflows/ci.yml editado a mano desde una interfaz web es deuda técnica desde el minuto uno.

Consejo 3: si duele, hazlo más a menudo. Es el principio que resume el curso entero. Los merges duelen porque son raros; los despliegues dan miedo porque son excepcionales. Aumentar la frecuencia obliga a automatizar, y automatizar elimina el dolor.

Ejercicios

Ejercicio 1: clasificar situaciones

Para cada situación, indica si describe Integración Continua, Entrega Continua, Despliegue Continuo o ninguna de las tres, y justifica en una frase.

  1. El equipo tiene un servidor que ejecuta las pruebas cada noche a las 3:00 sobre la rama main. Las ramas de funcionalidad se fusionan cada tres semanas.
  2. Cada pull request dispara build y tests en 6 minutos. Si están verdes, se puede fusionar. Los despliegues siguen siendo manuales por SFTP.
  3. Al fusionar a main, el pipeline construye una imagen Docker, la despliega en staging y ejecuta pruebas de humo. Marta pulsa "Deploy to production" cuando lo considera oportuno.
  4. Al fusionar a main, el pipeline despliega a producción en un 5 % del tráfico, vigila los errores 10 minutos y, si todo va bien, completa el despliegue. Nadie interviene.
  5. Diego compila en su portátil y sube por SFTP los viernes.

Ejercicio 2: detectar rupturas de la reproducibilidad

El siguiente pseudo-script es el proceso manual de Diego. Identifica al menos cuatro motivos por los que el artefacto resultante no es reproducible, y propón una corrección para cada uno.

#!/bin/bash
# deploy-viernes.sh — el proceso actual de Reservalia
cd ~/proyectos/reservalia/apps/api
git pull
npm install
npm run build
echo "Version: $(date)" > dist/VERSION.txt
sftp diego@servidor-prod <<< "put -r dist/* /var/www/api/"
psql -h rds-prod -U admin -f migrations/latest.sql

Ejercicio 3: dibujar el flujo objetivo

Escribe un diagrama mermaid del pipeline objetivo de Reservalia con estas condiciones, usando correctamente los términos trigger, etapa, job, artefacto, entorno y promoción:

  • Se dispara al fusionar a main.
  • Etapa de verificación con dos jobs en paralelo: test-api y test-web.
  • Si ambos pasan, se construye un artefacto etiquetado con el SHA del commit.
  • El artefacto se despliega en staging automáticamente.
  • Se promociona a prod solo tras aprobación manual de Marta.

Soluciones

Solución al Ejercicio 1

  1. Ninguna de las tres. Es una nightly build. Hay automatización de pruebas, pero las ramas viven tres semanas: no hay integración continua, sino integración tardía verificada de noche. La verificación llega hasta 21 días después del cambio que la rompió.
  2. Integración Continua. Cada cambio se verifica automáticamente antes de integrarse y el ciclo de feedback es de minutos. No hay Entrega Continua porque no existe un artefacto desplegable ni despliegue automatizado: el despliegue sigue siendo un proceso manual.
  3. Entrega Continua. Todo el camino técnico hasta producción está automatizado (build, artefacto, staging, pruebas de humo) y solo queda una puerta manual: la decisión de Marta. Es el ejemplo canónico de Delivery.
  4. Despliegue Continuo. No hay intervención humana entre el merge y producción. Además aparece la red de seguridad imprescindible: despliegue progresivo (canary al 5 %) y verificación automática antes de completar.
  5. Ninguna de las tres. Es despliegue manual con integración tardía. Es el punto de partida de Reservalia.

Solución al Ejercicio 2

# Problema Por qué rompe la reproducibilidad Corrección
1 Se construye en ~/proyectos/... del portátil de Diego El entorno acumula estado: node_modules antiguos, ficheros no versionados, variables locales, versión de Node personal Construir en un runner efímero que clona el repositorio desde cero
2 git pull sin fijar commit No se sabe qué commit exacto se ha construido; si alguien empuja durante el proceso, se construye otra cosa Hacer checkout de un SHA concreto y usarlo como etiqueta del artefacto
3 npm install Puede resolver versiones nuevas dentro de los rangos semver y modificar package-lock.json Usar npm ci, que instala exactamente el lock y falla si hay incoherencias
4 Versión de Node no fijada Node 20.9 y Node 20.11 pueden producir artefactos distintos Fijar la versión en .nvmrc / engines y en el pipeline
5 echo "Version: $(date)" La marca de tiempo hace que dos builds del mismo código produzcan artefactos distintos Etiquetar con el SHA del commit, no con la fecha
6 sftp put -r dist/* Es un despliegue incremental: los ficheros borrados en el código siguen vivos en el servidor. El servidor acumula historia Desplegar un artefacto inmutable completo (imagen de contenedor)
7 psql -f migrations/latest.sql a mano No hay control de qué migraciones se han aplicado ni orden garantizado, ni posibilidad de revertir Herramienta de migraciones versionada, ejecutada por el pipeline (lección 04-06)

Con cuatro habría bastado; si has encontrado más, mejor señal aún.

Solución al Ejercicio 3

flowchart TD
    T(["TRIGGER: push / merge a main"]) --> V

    subgraph V["ETAPA: verificar"]
        direction LR
        J1["JOB: test-api"]
        J2["JOB: test-web"]
    end

    V -->|"ambos en verde"| B

    subgraph B["ETAPA: construir"]
        J3["JOB: build<br/>docker build -t reservalia/api:$SHA"]
    end

    B --> ART[("ARTEFACTO<br/>reservalia/api:a3f9c21<br/>en ECR")]
    ART -->|"despliegue automático"| ENV1["ENTORNO: staging"]
    ENV1 --> GATE{"puerta manual:<br/>aprueba Marta"}
    GATE -->|"PROMOCIÓN<br/>del mismo artefacto"| ENV2["ENTORNO: prod"]

    style ART fill:#d9f2d9,stroke:#333,stroke-width:2px
    style GATE fill:#fff2cc,stroke:#333

Puntos que debían aparecer y conviene comprobar en tu versión:

  • El trigger es un evento del repositorio, no una acción manual.
  • test-api y test-web son jobs paralelos dentro de una misma etapa, no etapas distintas.
  • Se construye un único artefacto, etiquetado con el SHA (no con la fecha ni con "latest").
  • A producción va el mismo artefacto que se validó en staging: eso es promoción, no una reconstrucción.
  • La puerta manual sitúa este pipeline en Entrega Continua. Quitando esa puerta, sería Despliegue Continuo.

Conclusión

En esta lección hemos puesto los cimientos del curso:

  • El enemigo tiene dos caras: el integration hell (fusionar tarde y de golpe) y el despliegue manual (procesos que dependen de que una persona no se equivoque). Reservalia sufre las dos.
  • La Integración Continua es integrar a menudo y verificar automáticamente en un entorno limpio. Es una práctica de equipo antes que una herramienta.
  • La Entrega Continua mantiene el software siempre desplegable: el proceso está automatizado y la decisión es humana.
  • El Despliegue Continuo elimina esa última puerta manual, y solo es sensato con pruebas fiables, despliegue progresivo, monitorización y rollback.
  • Las tres se apilan: no hay Deployment sin Delivery, ni Delivery sin CI.
  • Y tenemos un vocabulario común: repositorio, commit, rama, trigger, pipeline, etapa, job, runner, artefacto, entorno, promoción y build reproducible. Dos reglas de oro que repetiremos hasta el final: construir una vez y promocionar el mismo artefacto, y fijar versiones para que la build sea reproducible.

Ahora ya sabes qué es CI/CD. La pregunta lógica de Marta cuando le presente esto a su equipo será otra: "¿y esto qué nos aporta, y qué nos va a costar?". Porque montar un pipeline no es gratis: consume tiempo de configuración, mantenimiento y minutos de ejecución. En la siguiente lección, Beneficios de CI/CD, veremos con honestidad las dos columnas de la balanza: qué gana un equipo como el de Reservalia, cómo se mide cada beneficio y en qué situaciones CI/CD aporta menos de lo que cuesta.

Curso de CI/CD: Integración y Despliegue Continuo

Módulo 1: Introducción a CI/CD

Módulo 2: Integración Continua (CI)

Módulo 3: Despliegue Continuo (CD)

Módulo 4: Prácticas Avanzadas de CI/CD

Módulo 5: Implementación de CI/CD en Proyectos Reales

Módulo 6: Herramientas y Tecnologías

Módulo 7: Ejercicios Prácticos

Módulo 8: Recursos Adicionales

© Copyright 2026. Todos los derechos reservados