Cuando alguien empieza en CI/CD, el mayor obstáculo no suele ser el concepto: es el ruido. Jenkins, GitHub Actions, GitLab CI, CircleCI, Travis CI, Azure DevOps, Argo CD, Tekton, Spinnaker, Drone, Buildkite... la lista parece infinita y da la impresión de que hay que elegir bien o se pierden meses. Esta lección es un mapa, no un tutorial. Su objetivo es que sepas colocar cada herramienta en su casilla, entender qué categorías existen y por qué, y descubrir algo que tranquiliza mucho: el 80 % de lo que aprendas en una herramienta se transfiere a las demás, porque todas implementan los mismos conceptos que vimos en 01-01. Al final justificaremos por qué el curso usa GitHub Actions y veremos el mismo trabajo trivial escrito en dos herramientas distintas, para que compruebes de primera mano que lo que cambia es la sintaxis, no la idea.

Contenido

  1. Cómo está organizado el ecosistema
  2. Categoría 1: servidores de CI/CD (el corazón del pipeline)
  3. Categoría 2: orquestadores de contenedores
  4. Categoría 3: registros de artefactos
  5. Categoría 4: infraestructura como código
  6. Categoría 5: despliegue continuo GitOps
  7. Las herramientas, una a una
  8. Tabla comparativa de alto nivel
  9. Por qué este curso usa GitHub Actions
  10. El mismo trabajo en dos herramientas
  11. Errores comunes y consejos
  12. Ejercicios
  13. Conclusión

  1. Cómo está organizado el ecosistema

El primer error al mirar este panorama es meter todas las herramientas en el mismo saco y compararlas entre sí. Argo CD no compite con Jenkins, igual que un destornillador no compite con una caja de herramientas: hacen cosas distintas en momentos distintos del proceso.

La forma útil de organizar el ecosistema es por qué parte del recorrido de un cambio cubre cada herramienta:

flowchart LR
    A["📝 Código<br/>en el repositorio"] --> B["🏭 SERVIDOR DE CI/CD<br/>construye y prueba"]
    B --> C["📦 REGISTRO<br/>DE ARTEFACTOS<br/>guarda el resultado"]
    C --> D["🚀 DESPLIEGUE<br/>lleva el artefacto<br/>al entorno"]
    D --> E["☸️ ORQUESTADOR<br/>ejecuta y mantiene<br/>vivo el servicio"]

    F["🏗️ IaC<br/>crea y gobierna<br/>la infraestructura"] -.-> E
    G["🔄 GitOps<br/>sincroniza el estado<br/>deseado del repo"] -.-> D

    style B fill:#cfe8ff
    style C fill:#d9f2d9
    style D fill:#fff2cc
    style E fill:#f0d9ff

Cinco categorías, cinco funciones distintas:

Categoría Qué hace Ejemplos
Servidores de CI/CD Ejecutan el pipeline: reaccionan a eventos del repositorio, construyen, prueban y lanzan despliegues GitHub Actions, GitLab CI/CD, Jenkins, CircleCI, Travis CI, Azure DevOps Pipelines, Tekton
Orquestadores de contenedores Ejecutan y mantienen vivos los servicios: reinicios, escalado, salud Kubernetes, Amazon ECS, Nomad
Registros de artefactos Almacenan de forma versionada e inmutable lo que se construye Amazon ECR, Docker Hub, GitHub Packages, Artifactory, Nexus
Infraestructura como código (IaC) Definen la infraestructura en ficheros versionados en vez de a golpe de clic Terraform, OpenTofu, Pulumi, AWS CloudFormation, Ansible
Despliegue continuo GitOps Vigilan un repositorio y sincronizan continuamente el clúster con lo que dice Argo CD, Flux

Un proyecto real usa una de cada categoría, no una sola herramienta. Reservalia, al final del curso, usará: GitHub Actions (servidor de CI/CD) + Amazon ECR (registro) + ECS Fargate (orquestador) + Terraform (IaC). Nada de eso es redundante.

  1. Categoría 1: servidores de CI/CD (el corazón del pipeline)

Es la categoría que ocupa la mayor parte de este curso, y la que más confusión genera. Dentro de ella, la distinción estructural más importante es alojado (SaaS) frente a autogestionado.

2.1. Alojado (SaaS) frente a autogestionado

Aspecto Alojado / SaaS Autogestionado (self-hosted)
Quién mantiene el servidor El proveedor
Puesta en marcha Minutos: un fichero YAML en el repositorio Días: instalar, asegurar, configurar agentes
Coste Por minuto de ejecución (+ cuota gratuita) Máquinas + tiempo de administración
Actualizaciones y parches Automáticos Responsabilidad tuya
Acceso a redes privadas Limitado; requiere túneles o runners propios Nativo: la máquina ya está en tu red
Control y personalización Menor: juegas con las piezas del proveedor Total: cualquier plugin, cualquier sistema operativo
Datos y cumplimiento El código pasa por infraestructura de terceros Todo permanece en tu infraestructura
Ejemplos GitHub Actions, CircleCI, Travis CI, GitLab.com Jenkins, GitLab autoalojado, Tekton, runners propios

Hay un modelo intermedio muy usado: plataforma alojada con runners propios. Es decir, GitHub Actions coordina y muestra la interfaz, pero los jobs se ejecutan en máquinas tuyas dentro de tu red privada. Combina la comodidad del SaaS con el acceso a sistemas internos y suele ser la elección de empresas medianas con requisitos de red o de cumplimiento.

2.2. Dónde se define el pipeline

Otra distinción que marca mucho la experiencia diaria:

  • En el repositorio (pipeline as code). El pipeline es un fichero YAML versionado junto al código: se revisa en pull requests, se puede volver atrás, viaja con las ramas. Es el modelo de GitHub Actions, GitLab CI, CircleCI, Travis CI, Tekton y Jenkins moderno con Jenkinsfile.
  • En la interfaz del servidor (configuración clicada). El pipeline se configura pinchando en formularios web y vive en la base de datos del servidor. Es el modelo clásico de Jenkins con freestyle jobs, y también es posible en Azure DevOps.

La segunda opción es un antipatrón bien documentado: la configuración no se versiona, nadie sabe quién cambió qué, no se puede reproducir y recuperar el servidor tras un desastre es una pesadilla. Regla práctica: si tu pipeline no está en el repositorio, no está bajo control. Profundizaremos en esto en la lección 04-05.

  1. Categoría 2: orquestadores de contenedores

Un servidor de CI/CD construye y lanza el despliegue, pero no mantiene tu aplicación viva. De eso se encarga el orquestador: decide en qué máquina corre cada contenedor, lo reinicia si muere, lo escala si hay carga, comprueba su salud y sustituye versiones sin cortar el servicio.

Herramienta Modelo Cuándo encaja
Kubernetes Estándar de facto, extremadamente potente y extremadamente complejo Muchos servicios, varios equipos, necesidad de portabilidad entre nubes
Amazon ECS / Fargate Orquestador gestionado de AWS; con Fargate ni siquiera gestionas servidores Estás en AWS y quieres contenedores sin administrar un clúster
HashiCorp Nomad Más simple que Kubernetes, orquesta contenedores y también procesos normales Cargas mixtas, equipos que quieren menos complejidad

Reservalia usará ECS Fargate. Es una decisión deliberada y realista para un equipo de tres personas: Kubernetes para tres servicios y una SRE a tiempo parcial es sobreingeniería. Kubernetes se ve en la lección 06-05, y el caso de microservicios en 05-03.

  1. Categoría 3: registros de artefactos

Recuerda la regla de oro de 01-01: construir una vez, promocionar el mismo artefacto. Para que eso sea posible, el artefacto tiene que vivir en algún sitio del que todos los entornos puedan recuperarlo. Ese sitio es el registro.

Registro Qué almacena Notas
Amazon ECR Imágenes de contenedor Integrado con IAM y ECS; el que usaremos en Reservalia
Docker Hub Imágenes de contenedor Público y muy conocido; límites de descarga en cuentas gratuitas
GitHub Packages Imágenes y paquetes (npm, Maven, NuGet...) Pegado al repositorio; cómodo si ya usas GitHub
JFrog Artifactory / Sonatype Nexus Casi cualquier formato Opción empresarial; suelen usarse también como proxy de dependencias

Una propiedad crítica de un registro bien usado: los artefactos son inmutables. La etiqueta reservalia/api:a3f9c21 debe apuntar siempre a los mismos bytes. Reetiquetar o sobrescribir destruye la trazabilidad y hace imposible saber qué hay realmente en producción. Por eso etiquetamos con el SHA del commit y no con latest.

  1. Categoría 4: infraestructura como código

Nuria, la SRE de Reservalia, creó a mano en la consola de AWS la base de datos RDS, el balanceador y las reglas de red. Es rápido... una vez. El problema aparece cuando hay que crear un entorno de staging idéntico, o cuando alguien cambia algo un martes y en octubre nadie recuerda por qué.

La infraestructura como código define esos recursos en ficheros versionados:

# Fragmento ilustrativo de Terraform: la base de datos de Reservalia.
# No hay que entenderlo todo ahora; solo ver que la infraestructura
# se declara en un fichero que vive en el repositorio y se revisa en un PR.
resource "aws_db_instance" "reservalia" {
  identifier     = "reservalia-${var.entorno}"   # reservalia-staging, reservalia-prod
  engine         = "postgres"
  engine_version = "16.3"
  instance_class = var.entorno == "prod" ? "db.t4g.medium" : "db.t4g.micro"
  multi_az       = var.entorno == "prod"
}

Lo relevante para esta lección es la categoría: estas herramientas no ejecutan pipelines, definen infraestructura. El pipeline las invoca. Terraform, OpenTofu, Pulumi, CloudFormation y Ansible juegan aquí. Lo desarrollaremos en la lección 03-03.

  1. Categoría 5: despliegue continuo GitOps

Es la categoría más reciente y la que peor se entiende, así que merece una explicación del mecanismo.

Los servidores de CI/CD tradicionales usan un modelo push: el pipeline termina y empuja el despliegue al entorno. Para eso, el pipeline necesita credenciales con permiso para modificar producción.

GitOps invierte la dirección. Es un modelo pull: un agente instalado dentro del clúster vigila continuamente un repositorio Git que describe el estado deseado. Cuando detecta una diferencia entre lo que dice el repositorio y lo que hay en el clúster, la corrige él mismo.

graph TB
    subgraph PUSH["Modelo PUSH (CI/CD tradicional)"]
        P1["Pipeline de CI/CD"] -->|"credenciales de producción<br/>+ empuja el cambio"| P2["Clúster"]
    end
    subgraph PULL["Modelo PULL (GitOps)"]
        G1["Repositorio Git<br/>= estado deseado"] -.->|"el agente consulta"| G2["Agente GitOps<br/>DENTRO del clúster"]
        G2 -->|"aplica y corrige<br/>desviaciones"| G3["Clúster"]
    end
    style PUSH fill:#fff6f6
    style PULL fill:#f6fff6

Ventajas del modelo pull: el pipeline nunca necesita credenciales de producción (mejora de seguridad importante), el repositorio es la fuente de verdad auditable, y las desviaciones manuales se revierten solas. Inconveniente: añade una pieza más y hoy está muy ligado a Kubernetes.

Herramientas: Argo CD (interfaz web muy visual, muy adoptado) y Flux (más minimalista, sin interfaz propia por defecto).

  1. Las herramientas, una a una

Ahora sí, la presentación individual. Para cada una: modelo de ejecución, dónde se define el pipeline y SaaS o autoalojado.

7.1. GitHub Actions

  • Modelo de ejecución: workflows disparados por eventos del repositorio (push, pull_request, etiquetas, cron, despacho manual). Cada workflow contiene jobs; cada job corre en un runner efímero (máquina virtual limpia que se destruye al terminar).
  • Dónde se define: ficheros YAML en .github/workflows/ dentro del propio repositorio.
  • SaaS o autoalojado: SaaS, con opción de runners autoalojados en tu infraestructura.
  • Rasgo distintivo: el Marketplace de acciones, un catálogo enorme de pasos reutilizables (actions/checkout, actions/setup-node, aws-actions/configure-aws-credentials...). Reduce muchísimo el código que escribes, pero introduce dependencias de terceros que hay que fijar y auditar (lección 04-03).
  • Punto fuerte: cercanía total al repositorio. El evento, el código, la revisión y el resultado están en el mismo sitio.
  • Punto débil: el modelo de reutilización (workflows reutilizables y acciones compuestas) es menos flexible que un lenguaje de programación real, y los pipelines muy complejos pueden volverse verbosos.

7.2. GitLab CI/CD

  • Modelo de ejecución: un fichero de pipeline con stages que agrupan jobs; cada job lo recoge un runner (con distintos ejecutores: Docker, shell, Kubernetes).
  • Dónde se define: .gitlab-ci.yml en la raíz del repositorio.
  • SaaS o autoalojado: ambos. GitLab.com es SaaS; GitLab autogestionado es una de las opciones autoalojadas más completas del mercado.
  • Rasgo distintivo: es una plataforma DevOps integrada: repositorio, CI/CD, registro de contenedores, gestión de incidencias, escaneo de seguridad y entornos, todo en el mismo producto y con la misma autenticación.
  • Punto fuerte: integración vertical y un modelo de plantillas (include, extends) muy potente para reutilizar configuración entre proyectos.
  • Punto débil: si te autogestionas GitLab, te haces cargo de una pieza de infraestructura grande.

7.3. Jenkins

  • Modelo de ejecución: un servidor controlador que orquesta y unos agentes que ejecutan los jobs. Modelo clásico de servidor persistente.
  • Dónde se define: idealmente en un Jenkinsfile en el repositorio, escrito en un DSL basado en Groovy (declarativo o scripted). Históricamente también mediante formularios en la interfaz web, lo que produce la deuda técnica que mencionábamos.
  • SaaS o autoalojado: autoalojado, siempre. Es software libre que instalas tú.
  • Rasgo distintivo: un ecosistema de más de mil plugins. Puede integrarse literalmente con cualquier cosa. Esa es también su maldición: los plugins tienen calidades y ritmos de mantenimiento muy dispares, y las incompatibilidades entre versiones son un clásico.
  • Punto fuerte: control absoluto, madurez de más de dos décadas, y el Jenkinsfile al ser código real permite lógica compleja que en YAML sería imposible.
  • Punto débil: coste de administración alto (actualizaciones, seguridad, gestión de agentes) y una interfaz que muestra su edad. Aun así, sigue siendo dominante en grandes empresas y en entornos con sistemas internos que nunca saldrán a la nube.
  • Lección 06-01.

7.4. CircleCI

  • Modelo de ejecución: jobs que se ejecutan en contenedores Docker o máquinas virtuales, con soporte nativo para paralelización y división automática de la suite de tests.
  • Dónde se define: .circleci/config.yml en el repositorio.
  • SaaS o autoalojado: principalmente SaaS; ofrece runners propios y una edición para servidor.
  • Rasgo distintivo: los orbs, paquetes reutilizables de configuración (equivalente conceptual a las acciones de GitHub), y una atención muy marcada al rendimiento y al tiempo de ejecución del pipeline.
  • Punto fuerte: rapidez, buenas herramientas de caché y paralelismo, agnóstico respecto al proveedor de repositorio.
  • Punto débil: una pieza más fuera de tu plataforma de repositorio, con su propia facturación y su propia gestión de accesos.
  • Lección 06-03.

7.5. Travis CI

  • Modelo de ejecución: builds disparadas por eventos del repositorio, ejecutadas en máquinas virtuales o contenedores.
  • Dónde se define: .travis.yml en la raíz del repositorio.
  • SaaS o autoalojado: SaaS (con una edición empresarial).
  • Rasgo distintivo: es históricamente importante: fue el primero en popularizar el modelo de "un YAML en tu repositorio dispara tu CI" y en ofrecerlo gratis a proyectos de código abierto. Prácticamente todo lo que hoy damos por sentado empezó ahí.
  • Situación actual: tras el cambio de su modelo gratuito para código abierto, gran parte del ecosistema migró a GitHub Actions y su cuota se redujo mucho. Lo estudiaremos en 06-04 por dos razones: sigue habiendo proyectos que lo usan y hay que saber leerlo, y su configuración es la más sencilla de todas, lo que la hace excelente para entender la esencia de un pipeline.

7.6. Azure DevOps Pipelines

  • Modelo de ejecución: pipelines con stages, jobs y steps, ejecutados en agentes alojados por Microsoft o propios.
  • Dónde se define: azure-pipelines.yml en el repositorio (o mediante el editor clásico visual, que es el modelo antiguo).
  • SaaS o autoalojado: SaaS (Azure DevOps Services) o autoalojado (Azure DevOps Server, antes TFS).
  • Rasgo distintivo: forma parte de una suite completa (Boards, Repos, Artifacts, Test Plans) muy implantada en organizaciones con inversión en el ecosistema Microsoft, y con soporte excelente para .NET y Windows.
  • Punto fuerte: entornos de aprobación y controles de gobernanza muy elaborados, útiles en empresas con procesos formales de release.
  • Punto débil: conviven dos modelos (clásico visual y YAML) y la documentación histórica mezcla ambos, lo que confunde a quien empieza.

7.7. Argo CD

  • Modelo de ejecución: no es un servidor de CI. Es un controlador que vive dentro de un clúster de Kubernetes y reconcilia continuamente el estado del clúster con lo declarado en un repositorio Git.
  • Dónde se define: manifiestos de Kubernetes (o Helm/Kustomize) en un repositorio Git.
  • SaaS o autoalojado: autoalojado en tu clúster (hay ofertas gestionadas de terceros).
  • Rasgo distintivo: es la referencia de GitOps. Se combina, no se sustituye: GitHub Actions construye y publica el artefacto, actualiza el manifiesto, y Argo CD se encarga de llevarlo al clúster.
  • Cuándo tiene sentido: cuando ya usas Kubernetes. Sin Kubernetes, hoy por hoy, no aplica.

7.8. Tekton

  • Modelo de ejecución: un framework de CI/CD nativo de Kubernetes: cada paso del pipeline es un contenedor y cada ejecución es un recurso de Kubernetes (Task, Pipeline, PipelineRun).
  • Dónde se define: manifiestos YAML de Kubernetes, versionados en el repositorio.
  • SaaS o autoalojado: autoalojado sobre Kubernetes; es la base de varios productos comerciales.
  • Rasgo distintivo: no es una herramienta "de usar", es una base para construir tu propia plataforma de CI/CD. Muy potente y muy de bajo nivel.
  • Cuándo tiene sentido: organizaciones grandes que construyen una plataforma interna para muchos equipos. Para un equipo de tres personas es claramente excesivo.

  1. Tabla comparativa de alto nivel

Herramienta Categoría SaaS / autoalojado Dónde se define Modelo de ejecución Encaja bien cuando...
GitHub Actions Servidor CI/CD SaaS (+ runners propios) .github/workflows/*.yml Runners efímeros por job Tu código está en GitHub y quieres empezar hoy
GitLab CI/CD Servidor CI/CD Ambos .gitlab-ci.yml Runners con varios ejecutores Quieres una plataforma DevOps única e integrada
Jenkins Servidor CI/CD Autoalojado Jenkinsfile (o interfaz web) Controlador + agentes persistentes Necesitas control total, redes internas o integraciones exóticas
CircleCI Servidor CI/CD SaaS (+ runners propios) .circleci/config.yml Contenedores/VM con paralelismo El tiempo de pipeline es tu prioridad y quieres independencia del repositorio
Travis CI Servidor CI/CD SaaS .travis.yml VM/contenedores por build Mantienes un proyecto que ya lo usa; o quieres el ejemplo más simple posible
Azure DevOps Pipelines Servidor CI/CD Ambos azure-pipelines.yml Agentes alojados o propios Tu organización vive en el ecosistema Microsoft
Argo CD Despliegue GitOps Autoalojado (en Kubernetes) Manifiestos en Git Reconciliación continua (pull) Ya usas Kubernetes y quieres despliegues auditables sin credenciales en el CI
Tekton Servidor CI/CD Autoalojado (en Kubernetes) CRDs de Kubernetes Cada paso, un contenedor Construyes una plataforma interna de CI/CD para muchos equipos

Una advertencia sobre esta tabla: no elijas por número de casillas verdes. En la práctica, el criterio que más pesa es dónde vive tu código y qué sabe mantener tu equipo. Los criterios formales de elección los sistematizaremos en la lección 06-07.

  1. Por qué este curso usa GitHub Actions

La elección de este curso es GitHub Actions, y conviene explicar los motivos para que sepas cuáles son transferibles a tu caso y cuáles no:

  1. Cercanía al repositorio. El pipeline vive en el mismo sitio que el código. El evento que lo dispara (un pull request), la revisión, el resultado y el histórico están en la misma pantalla. Para aprender, esto elimina una barrera enorme: no hay un segundo sistema que configurar ni credenciales cruzadas.
  2. Modelo declarativo y legible. Un workflow de GitHub Actions se lee de arriba abajo casi como prosa. Al ser declarativo, describes qué quieres, no cómo orquestarlo. Esto hace que los ejemplos del curso sean fáciles de entender aunque nunca hayas visto la herramienta.
  3. Coste cero para empezar. Los repositorios públicos tienen ejecución gratuita, y los privados una cuota mensual generosa. Puedes reproducir todos los ejemplos del curso sin pagar nada.
  4. Adopción muy amplia. Es hoy la herramienta más probable con la que te encuentres en un proyecto nuevo, y aparece constantemente en ofertas de empleo.
  5. Los conceptos son universales. Todo lo que aprenderás —triggers, jobs, matrices, artefactos, caché, secretos, entornos con aprobación, promoción— existe con otro nombre en todas las demás. La sección siguiente lo demuestra.

Y por honestidad, los motivos por los que podrías elegir otra:

  • Tu código no está en GitHub → GitLab CI o CircleCI encajan mejor.
  • Necesitas acceder a sistemas internos que no salen de tu red → Jenkins o runners autoalojados.
  • Tu organización ya tiene una plataforma establecida → aprende esa; el conocimiento se transfiere igual.

El módulo 6 profundiza en cada herramienta por separado (Jenkins en 06-01, GitLab CI en 06-02, CircleCI en 06-03, Travis CI en 06-04, Docker y Kubernetes en 06-05, GitHub Actions a fondo en 06-06) y en la lección 06-07 veremos los criterios formales para elegir. Además, en ese módulo reexpresaremos el mismo pipeline de Reservalia en cada herramienta, que es la mejor forma de comprobar que lo aprendido se transfiere.

  1. El mismo trabajo en dos herramientas

Vamos a verlo ya, en pequeño. El trabajo es deliberadamente trivial: instalar las dependencias y ejecutar los tests de apps/api cuando alguien empuja código.

Importante: no es necesario que entiendas cada línea. Aquí solo queremos que compares las dos columnas y veas que dicen lo mismo. La construcción real del pipeline de Reservalia empieza en la lección 02-02.

10.1. GitHub Actions

# Fichero: .github/workflows/test-api.yml
name: Tests de la API

# TRIGGER: qué evento dispara este workflow.
on: [push]

jobs:
  # Nombre interno del JOB. Aparecerá así en la interfaz de GitHub.
  test-api:
    # RUNNER: la máquina donde se ejecuta. Efímera y limpia.
    runs-on: ubuntu-latest

    # STEPS: los pasos, en orden estricto.
    steps:
      # Paso 1: descargar el código del repositorio en el runner.
      # Sin esto, la máquina está vacía. Es siempre el primer paso.
      - uses: actions/checkout@v4

      # Paso 2: instalar Node 20. Fijamos la versión para que la
      # build sea reproducible (concepto de la lección 01-01).
      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      # Paso 3: instalar dependencias EXACTAMENTE como dice el lock.
      # working-directory sitúa el comando dentro de apps/api.
      - run: npm ci
        working-directory: apps/api

      # Paso 4: ejecutar los tests. Si el comando devuelve un código
      # de salida distinto de 0, el job falla y el pipeline se pone rojo.
      - run: npm test
        working-directory: apps/api

10.2. GitLab CI

# Fichero: .gitlab-ci.yml (en la raíz del repositorio)

# STAGES: las etapas del pipeline, en orden.
stages:
  - test

# Nombre del JOB.
test-api:
  # A qué etapa pertenece.
  stage: test

  # RUNNER: aquí se expresa como la imagen Docker en la que corre el job.
  # Equivale a runs-on + setup-node de GitHub Actions, en una sola línea.
  image: node:20

  # No hace falta un paso de checkout: GitLab clona el repositorio
  # automáticamente antes de ejecutar el job.
  script:
    - cd apps/api
    - npm ci
    - npm test

  # TRIGGER: aquí se declara por job, no globalmente.
  rules:
    - if: $CI_PIPELINE_SOURCE == "push"

10.3. Qué cambia y qué no

Pon las dos al lado y verás que los conceptos son idénticos; solo cambia dónde se escribe cada uno:

Concepto (lección 01-01) GitHub Actions GitLab CI
Trigger on: [push], global al workflow rules: dentro de cada job
Job Clave bajo jobs: Clave de primer nivel
Stage / etapa Implícita; se ordena con needs: Explícita: stages: + stage:
Runner runs-on: ubuntu-latest image: node:20
Descarga del código Paso explícito actions/checkout@v4 Automático
Preparar el lenguaje Paso actions/setup-node@v4 Elegir la imagen adecuada
Ejecutar comandos - run: (un paso por comando) script: (lista de comandos)
Cómo se detecta el fallo Código de salida ≠ 0 Código de salida ≠ 0

Las dos diferencias filosóficas que explican casi todo lo demás:

  • GitHub Actions apuesta por acciones reutilizables del Marketplace (setup-node, checkout), que encapsulan trabajo. Escribes menos, pero dependes de terceros.
  • GitLab CI apuesta por imágenes Docker como unidad de entorno. Más explícito y con menos magia, pero eliges tú la imagen correcta.

Y lo que no cambia en ninguna herramienta del mundo:

  1. Un evento del repositorio dispara la ejecución.
  2. Se prepara una máquina limpia con el código.
  3. Se instalan dependencias de forma reproducible.
  4. Se ejecutan comandos.
  5. Si un comando devuelve un código de salida distinto de cero, el pipeline falla.

Ese último punto es especialmente liberador: la unidad universal de éxito o fracaso en CI/CD es el código de salida de un proceso. Todas las herramientas, sin excepción, se apoyan en él.

# Compruébalo en tu propia terminal.
# Todo comando deja su código de salida en la variable $?
# 0 = éxito; cualquier otro valor = fallo.

echo "hola"
echo $?        # → 0   ✅ el pipeline seguiría

ls /carpeta/que/no/existe
echo $?        # → 2   ❌ el pipeline se pondría rojo aquí

# Por eso `npm test` funciona igual en las 8 herramientas de esta lección:
# los frameworks de test devuelven 0 si todo pasa y ≠0 si algo falla.

Errores Comunes y Consejos

Error 1: comparar herramientas de categorías distintas. "¿Qué es mejor, Jenkins o Argo CD?" es una pregunta mal planteada: uno ejecuta pipelines y el otro sincroniza clústeres. Antes de comparar, sitúa cada herramienta en su casilla del mapa de la sección 1.

Error 2: elegir por popularidad. Que Kubernetes sea el estándar no significa que tu equipo de tres personas lo necesite. La mejor herramienta es la que tu equipo puede mantener sin dedicarle un tercio de su tiempo. Reservalia elige ECS Fargate por eso mismo.

Error 3: creer que la elección es irreversible. Como acabas de ver, migrar un pipeline entre herramientas es sobre todo un trabajo de traducción de sintaxis. Lo que sí cuesta migrar es lo que está mal hecho: pipelines configurados desde una interfaz web, scripts inmensos e imposibles de leer o secretos incrustados en el YAML. Invierte en que tu pipeline esté bien hecho, no en elegir la herramienta perfecta.

Error 4: configurar el pipeline desde la interfaz gráfica. Es tentador porque es rápido. Seis meses después nadie sabe quién cambió qué, no se puede revertir y recuperar el servidor es imposible. Todo pipeline debe vivir en el repositorio.

Error 5: acumular herramientas sin necesidad. Añadir Argo CD "porque es GitOps" a un proyecto que ni siquiera usa Kubernetes añade complejidad sin beneficio. Cada herramienta nueva es un sistema más que aprender, mantener, actualizar y depurar a las tres de la mañana.

Consejo 1: aprende una a fondo antes que cinco por encima. El conocimiento profundo de una herramienta se transfiere; el conocimiento superficial de cinco, no. Por eso este curso construye todo en GitHub Actions y solo al final, en el módulo 6, traduce.

Consejo 2: usa el criterio "dónde vive mi código". Es el filtro más eficaz. GitHub → GitHub Actions. GitLab → GitLab CI. Servidor Git interno → Jenkins o GitLab autoalojado. Este criterio simple acierta en la gran mayoría de casos.

Consejo 3: fija las versiones de las acciones y plugins que uses. actions/checkout@v4 en lugar de actions/checkout@main. Una acción de terceros es código ajeno ejecutándose con acceso a tu repositorio. Es una superficie de ataque real y le dedicaremos atención en la lección 04-03.

Consejo 4: al leer documentación, tradúcela mentalmente a los conceptos de 01-01. Cuando encuentres un término nuevo, pregúntate: ¿esto es un trigger, un job, una etapa, un runner o un artefacto? Casi siempre es una de esas cinco cosas con otro nombre, y esa traducción convierte la documentación de cualquier herramienta en algo familiar.

Ejercicios

Ejercicio 1: clasificar herramientas por categoría

Coloca cada herramienta en su categoría del mapa de la sección 1 (servidor de CI/CD, orquestador de contenedores, registro de artefactos, IaC o despliegue GitOps) e indica en una frase qué problema resuelve:

  1. Terraform
  2. Amazon ECR
  3. Flux
  4. Amazon ECS Fargate
  5. CircleCI
  6. Nexus
  7. Kubernetes
  8. Tekton

Ejercicio 2: traducir un workflow

Traduce el siguiente workflow de GitHub Actions a .gitlab-ci.yml. Añade después una tabla de equivalencias concepto a concepto.

name: Verificar la web
on: [push]
jobs:
  lint-y-build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm ci
        working-directory: apps/web
      - run: npm run lint
        working-directory: apps/web
      - run: npm run build
        working-directory: apps/web

Ejercicio 3: recomendar herramientas en tres escenarios

Para cada equipo, recomienda una combinación de herramientas (servidor de CI/CD + registro + destino de ejecución, y GitOps o IaC si procede) y justifica cada elección en una o dos frases. No hay una única respuesta correcta; se valora la justificación.

  1. Reservalia. Tres personas. Código en GitHub. Despliegan a AWS con ECS Fargate. Ninguna experiencia previa en CI/CD. Presupuesto muy ajustado.
  2. Banco Meridiano. Equipo de plataforma de 40 personas. El código está en un servidor Git interno que no puede salir de la red corporativa por normativa. Despliegan a un Kubernetes local. Necesitan aprobaciones registradas y auditables por cada despliegue a producción.
  3. Ludika. Estudio de videojuegos de 15 personas. Código en GitLab.com. Compilan builds para Windows, macOS y Linux en cada release. Los artefactos pesan varios gigabytes.

Soluciones

Solución al Ejercicio 1

Herramienta Categoría Problema que resuelve
Terraform Infraestructura como código Define recursos de nube (bases de datos, redes, balanceadores) en ficheros versionados, en lugar de crearlos a mano en una consola web
Amazon ECR Registro de artefactos Almacena de forma versionada e inmutable las imágenes de contenedor, para poder promocionar el mismo artefacto entre entornos
Flux Despliegue continuo GitOps Sincroniza continuamente un clúster de Kubernetes con el estado declarado en un repositorio Git, en modelo pull
Amazon ECS Fargate Orquestador de contenedores Ejecuta y mantiene vivos los contenedores (reinicio, escalado, salud) sin que tengas que administrar servidores
CircleCI Servidor de CI/CD Ejecuta el pipeline de build, test y despliegue en respuesta a eventos del repositorio
Nexus Registro de artefactos Almacena artefactos de múltiples formatos y actúa además como proxy caché de dependencias externas
Kubernetes Orquestador de contenedores Planifica, escala y mantiene contenedores en un clúster de máquinas
Tekton Servidor de CI/CD Ejecuta pipelines de forma nativa en Kubernetes, como base para construir una plataforma propia

Dos observaciones que conviene haber notado:

  • Flux y Tekton están ambos "en Kubernetes" pero no son la misma categoría. Tekton ejecuta pipelines (construye y prueba); Flux sincroniza el estado desplegado. Se usan juntos, no en lugar del otro.
  • ECR y Nexus están en la misma categoría aunque uno sea un servicio gestionado de AWS y el otro un producto instalable: la categoría la define la función, no el modelo de distribución.

Solución al Ejercicio 2

# .gitlab-ci.yml
stages:
  - verificar

lint-y-build:
  stage: verificar
  image: node:20          # sustituye a runs-on + setup-node
  script:
    - cd apps/web
    - npm ci
    - npm run lint
    - npm run build
  rules:
    - if: $CI_PIPELINE_SOURCE == "push"

Tabla de equivalencias:

Concepto GitHub Actions GitLab CI Comentario
Nombre del pipeline name: Verificar la web No hay equivalente directo; el nombre lo da el job o el fichero Detalle cosmético
Trigger on: [push] (global) rules: if $CI_PIPELINE_SOURCE == "push" (por job) GitHub lo declara arriba; GitLab, por job
Job jobs.lint-y-build lint-y-build: de primer nivel Mismo concepto
Etapa Implícita stages: + stage: verificar GitLab exige declararla; GitHub la deduce del orden y de needs:
Runner / entorno runs-on: ubuntu-latest image: node:20 GitLab define el entorno con la imagen
Descarga del código actions/checkout@v4 Automático GitLab clona siempre antes del job
Versión de Node actions/setup-node@v4 Incluida en node:20 Dos formas distintas de fijar la versión
Directorio de trabajo working-directory: por paso cd apps/web una vez En GitLab los comandos comparten shell
Comandos - run: uno por paso script: lista En GitHub cada paso se ve por separado en la interfaz

Un matiz sutil que merece la pena entender: en GitHub Actions cada run es un shell independiente, por eso hay que repetir working-directory en cada paso —un cd en un paso no afecta al siguiente. En GitLab, todos los comandos de script comparten el mismo shell, así que un solo cd basta. Esta diferencia sorprende a mucha gente al migrar en cualquiera de los dos sentidos.

Solución al Ejercicio 3

1. Reservalia

  • Servidor de CI/CD: GitHub Actions. El código ya está en GitHub: sin sistemas adicionales, sin credenciales cruzadas y con cuota gratuita suficiente para un equipo de tres. Coste de arranque prácticamente nulo, que es determinante sin experiencia previa ni presupuesto.
  • Registro: Amazon ECR. Está en la misma nube que la ejecución, la autenticación se resuelve con IAM y las descargas dentro de la misma región no generan tráfico saliente facturable.
  • Ejecución: ECS Fargate. Ya es su destino. Es la decisión correcta para tres personas: contenedores sin administrar un clúster. Kubernetes aquí sería sobreingeniería y consumiría el tiempo de Nuria.
  • IaC: Terraform, a partir del módulo 3, para que staging y prod sean reproducibles y no dependan de lo que Nuria recuerde haber clicado.
  • GitOps: no. No usan Kubernetes; Argo CD no aporta nada aquí y sí complejidad.

2. Banco Meridiano

  • Servidor de CI/CD: Jenkins autoalojado (o GitLab autogestionado). Es el criterio decisivo: el código no puede salir de la red. Cualquier SaaS queda descartado por normativa, no por preferencia. El tamaño del equipo (40 personas) justifica el coste de administración, que en Reservalia sería prohibitivo.
  • Registro: Artifactory o Nexus en la red interna, con función añadida de proxy de dependencias externas: útil cuando la salida a internet está restringida.
  • Ejecución: su Kubernetes local, ya existente.
  • GitOps: Argo CD, muy recomendable. Aquí encaja perfectamente por dos razones: ya tienen Kubernetes, y el modelo pull elimina la necesidad de que el sistema de CI tenga credenciales de producción, lo cual es un argumento de peso ante un auditor. Además, el repositorio Git de manifiestos se convierte en el registro auditable de qué se desplegó, cuándo y aprobado por quién.
  • Aprobaciones: puertas manuales obligatorias antes de producción. Es un caso claro de Entrega Continua y no de Despliegue Continuo, y esa puerta es un requisito regulatorio, no una carencia.

3. Ludika

  • Servidor de CI/CD: GitLab CI/CD. El código está en GitLab.com: aplica el criterio "dónde vive mi código". Además, el registro de paquetes y contenedores viene integrado en el mismo producto.
  • Registro: GitLab Package Registry, con una salvedad importante: builds de varios gigabytes por plataforma y por release consumen almacenamiento muy rápido. Hay que definir una política de retención desde el primer día (por ejemplo, conservar todas las builds de release y solo las últimas N de desarrollo) o la factura se descontrola.
  • Ejecución multiplataforma: runners propios. Aquí hay una restricción que mucha gente descubre tarde: compilar para macOS requiere hardware Apple, por licencia. Habrá que usar runners macOS propios o alojados de un proveedor especializado, y sabiendo que su coste por minuto es sensiblemente mayor.
  • Consideración adicional: con artefactos tan pesados, el tiempo y el coste de subida y bajada dominan el pipeline. Merece la pena invertir en caché de dependencias y en compilación incremental antes que en cualquier otra optimización (materia de la lección 04-04).
  • GitOps: no aplica. El producto no se despliega en un clúster; se distribuye a usuarios finales.

Conclusión

Esta lección ha ordenado el ruido del ecosistema:

  • Las herramientas se organizan en cinco categorías complementarias: servidores de CI/CD, orquestadores de contenedores, registros de artefactos, infraestructura como código y despliegue GitOps. No compiten entre categorías: se combinan.
  • Dentro de los servidores de CI/CD, las dos preguntas que más definen la experiencia son SaaS o autoalojado y dónde se define el pipeline. Y hay una respuesta que no admite matices: el pipeline debe vivir en el repositorio, nunca en formularios de una interfaz web.
  • Hemos situado GitHub Actions, GitLab CI/CD, Jenkins, CircleCI, Travis CI, Azure DevOps Pipelines, Argo CD y Tekton, cada una con su modelo de ejecución y su terreno natural.
  • El curso usará GitHub Actions por su cercanía al repositorio, su modelo declarativo legible y su coste nulo para empezar; el módulo 6 profundiza en cada herramienta y reexpresa el pipeline de Reservalia en varias de ellas.
  • Y lo más importante: al comparar el mismo trabajo en GitHub Actions y en GitLab CI hemos comprobado que lo que cambia es la sintaxis, no los conceptos. Trigger, job, etapa, runner, pasos y código de salida están en todas. Lo que aprendas aquí se transfiere.

Ya sabemos qué es CI/CD, por qué merece la pena y con qué se construye. Falta lo más concreto: qué vamos a automatizar exactamente. En la siguiente lección, El Proyecto del Curso: la Aplicación que Vamos a Automatizar, conoceremos Reservalia a fondo: su producto, su equipo, la estructura real del repositorio, los scripts que el pipeline invocará, sus tres entornos y la infraestructura AWS de destino. También veremos la hoja de ruta de qué habremos automatizado al final de cada módulo y qué necesitas instalado para seguir los ejemplos, uses Node.js o no.

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