Saltar al contenido

Lección 15 de 19 · Lectura y práctica

Diseña la arquitectura de tu pipeline CI/CD

Concepto claveDiseñar la arquitectura de un pipeline CI/CD es como planificar una línea de montaje en una fábrica moderna. En lugar de piezas físicas, procesas código, pruebas y despliegues de manera automatizada. Un pipeline es.

Del concepto a la práctica

Taller de esta lección

Diseñar la arquitectura significa decidir el flujo antes de escribir todos los steps. Cada etapa debe tener entradas, salidas, criterio de éxito y dependencia. Una forma compacta es build -> test -> artefacto -> staging; si dos trabajos no comparten datos, pueden ejecutarse en paralelo, pero no conviene paralelizar por costumbre.

Ejemplo resuelto

Para una app demo, build produce app.tar, test valida el código fuente y deploy-staging consume el artefacto cuando ambos son correctos. Ese diseño asegura la puerta, pero probar solo el código fuente no demuestra el artefacto empaquetado. Añade una comprobación de la salida de build descargada y relaciona ambos con el mismo commit antes de promoverla.

Pruébalo

  1. Lista archivos de entrada y salida de cada etapa.

  2. Dibuja las dependencias entre jobs.

  3. Marca dónde se detiene el flujo ante cada fallo.

  4. Decide qué evidencia guardarás por etapa.

Comprueba tu resultado

Error frecuente: conectar deploy solo con build y olvidar test. Corrección: haz que deploy dependa de todas las validaciones requeridas.

Ejercicio: añade una comprobación de tamaño del artefacto. Resultado esperado: el diseño identifica el archivo, su productor, su consumidor y la condición que lo rechaza si supera el límite definido.

Secuencia de código, imagen de contenedor, pruebas, registro y despliegue de instancias idénticas.
CursaloMapa de práctica
Del código al despliegue

El código se empaqueta en una imagen y se prueba antes de publicarlo. Esa misma imagen se guarda en un registro y se usa en el despliegue. Comprobar la salud de las instancias permite detectar un fallo sin reconstruir el artefacto.

Ver la infografía en tamaño completo ↗

Concepto clave

Diseñar la arquitectura de un pipeline CI/CD es como planificar una línea de montaje en una fábrica moderna. En lugar de piezas físicas, procesas código, pruebas y despliegues de manera automatizada. Un pipeline es una secuencia de etapas que transforma tu código fuente en una aplicación desplegada, con validaciones en cada paso para garantizar calidad y seguridad. La arquitectura define cómo fluye este proceso, qué herramientas se usan y cómo se manejan los errores.

En el contexto de GitHub Actions, la arquitectura se materializa en archivos YAML que describen workflows, jobs y steps. Un workflow es el proceso completo, los jobs son tareas paralelas o secuenciales (como build, test y deploy), y los steps son acciones individuales dentro de un job. Pensar en arquitectura te ayuda a evitar cuellos de botella, como pruebas lentas que retrasan el despliegue, y a crear pipelines escalables que crecen con tu aplicación.

Cómo funciona en la práctica

Imagina una aplicación web moderna con frontend en React y backend en Node.js. Tu pipeline debe manejar ambos componentes. Primero, define las etapas clave: 1) Build - compilar el código, 2) Test - ejecutar pruebas unitarias y de integración, 3) Deploy - desplegar en un entorno de staging o producción. En GitHub Actions, esto se traduce en un workflow que se dispara en eventos como push a main o pull request.

Paso a paso: Crea un archivo .github/workflows/ci-cd.yml. Configura el trigger para que se ejecute en push a la rama main. Define jobs: uno para build y test del frontend, otro para el backend, y un job de deploy que dependa de que ambos pasen. Usa acciones predefinidas de GitHub Marketplace, como actions/setup-node, para agilizar el setup. Asegúrate de que los jobs compartan artefactos, como el código compilado, usando actions/upload-artifact y actions/download-artifact.

Codigo en accion

Aquí tienes un ejemplo funcional de un pipeline básico para una aplicación Node.js. Este workflow hace build, test y deploy a un entorno de staging en Heroku.

name: CI/CD Pipeline

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout code
      uses: actions/checkout@v3
    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '18'
    - name: Install dependencies
      run: npm ci
    - name: Run tests
      run: npm test
    - name: Build application
      run: npm run build
    - name: Upload build artifacts
      uses: actions/upload-artifact@v3
      with:
        name: app-build
        path: build/

  deploy-staging:
    runs-on: ubuntu-latest
    needs: build-and-test
    if: github.ref == 'refs/heads/main'
    steps:
    - name: Download artifacts
      uses: actions/download-artifact@v3
      with:
        name: app-build
    - name: Deploy to Heroku
      uses: akhileshns/heroku-deploy@v3.12.12
      with:
        heroku_api_key: ${{secrets.HEROKU_API_KEY}}
        heroku_app_name: "myapp-staging"
        heroku_email: ${{secrets.HEROKU_EMAIL}}

Ahora, mejora este pipeline añadiendo un job para linting y otro para pruebas de integración. Esto muestra el "antes y después" de refactorizar para mayor robustez.

name: Enhanced CI/CD Pipeline

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - uses: actions/setup-node@v3
      with:
        node-version: '18'
    - run: npm ci
    - run: npm run lint

  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - uses: actions/setup-node@v3
      with:
        node-version: '18'
    - run: npm ci
    - run: npm test
    - run: npm run test:integration

  build:
    runs-on: ubuntu-latest
    needs: [lint, test]
    steps:
    - uses: actions/checkout@v3
    - uses: actions/setup-node@v3
      with:
        node-version: '18'
    - run: npm ci
    - run: npm run build
    - uses: actions/upload-artifact@v3
      with:
        name: app-build
        path: build/

  deploy-staging:
    runs-on: ubuntu-latest
    needs: build
    if: github.ref == 'refs/heads/main'
    steps:
    - uses: actions/download-artifact@v3
      with:
        name: app-build
    - uses: akhileshns/heroku-deploy@v3.12.12
      with:
        heroku_api_key: ${{secrets.HEROKU_API_KEY}}
        heroku_app_name: "myapp-staging"
        heroku_email: ${{secrets.HEROKU_EMAIL}}

Errores comunes

  • No usar secrets de forma segura: Exponer claves API en el código. Solución: Usa GitHub Secrets para almacenar credenciales y referenciarlas con ${{secrets.NOMBRE}}.
  • Jobs bloqueantes innecesarios: Hacer que todos los jobs se ejecuten en serie, ralentizando el pipeline. Solución: Paraleliza jobs independientes, como lint y test unitario, usando needs solo para dependencias reales.
  • Ignorar el cache: No cachear dependencias, lo que aumenta el tiempo de ejecución. Solución: Usa actions/cache para almacenar node_modules o otros archivos recurrentes.
  • Despliegues sin rollback: Desplegar directamente a producción sin plan de contingencia. Solución: Implementa un job de deploy con aprobación manual y configura rollback automático en caso de fallo.
  • No probar en entorno similar a producción: Ejecutar pruebas solo en entornos de desarrollo. Solución: Usa contenedores Docker o servicios como GitHub Actions para simular producción en etapas de test.

Checklist de dominio

  1. He definido un trigger adecuado (push, pull request) para mi workflow.
  2. He organizado jobs en etapas logicas: lint, test, build, deploy.
  3. Uso GitHub Secrets para manejar credenciales de forma segura.
  4. He configurado dependencias entre jobs usando needs para optimizar el flujo.
  5. Incluyo cache de dependencias para acelerar ejecuciones.
  6. Tengo un plan de rollback o aprobacion manual para despliegues a produccion.
  7. He probado el pipeline en un repositorio real y verificado que pasa todas las etapas.

Diseña y ejecuta un pipeline CI/CD para una app simple

En este ejercicio, crearás un pipeline CI/CD desde cero para una aplicación web básica. Sigue estos pasos:

  1. Crea un nuevo repositorio en GitHub llamado mi-pipeline-cicd.
  2. Inicializa un proyecto Node.js simple con un archivo index.js que contenga un servidor Express y un test unitario usando Jest.
  3. En la raíz del repositorio, crea un archivo .github/workflows/pipeline.yml.
  4. Diseña el pipeline con tres jobs: test (ejecuta pruebas), build (crea un artefacto), y deploy-staging (simula despliegue subiendo a GitHub Pages o mostrando un log).
  5. Configura los jobs para que se ejecuten en secuencia: test debe pasar antes de build, y build antes de deploy-staging.
  6. Añade un trigger para que el pipeline se ejecute en cada push a la rama main.
  7. Usa GitHub Secrets si necesitas credenciales (p.ej., para un despliegue real), o simula con un echo en el deploy.
  8. Ejecuta el pipeline haciendo un push a main y verifica que todos los jobs pasen.
Pistas
  • Usa actions/setup-node@v3 para configurar Node.js en los jobs.
  • Para simular deploy, puedes usar un step con run: echo 'Desplegando a staging...' en lugar de una acción real.
  • Asegúrate de que el job de deploy-staging tenga needs: [build] para depender del job anterior.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.

Sigue con GitHub Actions para CI/CD: Automatización de Builds, Tests y Deploys

Esta lección forma parte de un curso de Cursalo. Revisa su programa y elige entre la compra individual o el acceso a toda la escuela.

Si ya tenías acceso a este curso, entra con tu cuenta: tus derechos y tu progreso se conservan. No necesitas comprarlo de nuevo.

01 / ELEGIR UNA RUTA

El próximo paso

Aprende IA mientras construyes algo que sí necesitas.

Empieza por el curso inicial o explora el catálogo para encontrar una práctica alineada con tu trabajo.