Saltar al contenido

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

Proyecto práctico: Crea y ejecuta una pipeline completa para una app demo

Concepto claveUna pipeline CI/CD completa es un flujo automatizado que integra desarrollo, pruebas y despliegue en un solo proceso. Imagina una fábrica de coches: cada pieza (código) pasa por una línea de montaje (pipeline) donde.

Del concepto a la práctica

Taller de esta lección

El proyecto práctico debe producir evidencia completa, no solo un YAML que parece correcto. Una aplicación demo pequeña permite controlar entradas y provocar fallos conocidos. La revisión debe comparar el commit, el artefacto, los tests y el destino de staging para confirmar que pertenecen a la misma ejecución.

Ejemplo resuelto

Usa una app con src/, tests/ y un comando de empaquetado. El workflow genera demo-<identificador>.tar, ejecuta dos pruebas y descarga el archivo y lo copia a staging local del job o a un destino autorizado persistente, documentando cuál usa. Cada runner alojado puede ser nuevo: una carpeta creada en otro job no se comparte automáticamente. El identificador permite relacionar artefacto y commit sin inventar resultados.

Pruébalo

  1. Ejecuta una versión correcta y guarda los logs.

  2. Cambia una expectativa para provocar un fallo.

  3. Confirma que no se crea una entrega posterior válida.

  4. Revierte el cambio y repite la ejecución completa.

Comprueba tu resultado

Error frecuente: borrar la evidencia de la ejecución fallida. Corrección: conserva su identificador y anota la causa.

Ejercicio: añade una prueba que detecte una versión incorrecta. Resultado esperado: la ejecución correcta llega a staging; la incorrecta se detiene antes de deploy y ambas quedan diferenciadas por commit.

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

Una pipeline CI/CD completa es un flujo automatizado que integra desarrollo, pruebas y despliegue en un solo proceso. Imagina una fábrica de coches: cada pieza (código) pasa por una línea de montaje (pipeline) donde se verifica su calidad (tests), se ensambla (build) y finalmente se entrega al cliente (deploy). GitHub Actions actúa como el sistema de control de esa fábrica, orquestando cada etapa automáticamente cuando un desarrollador "empuja" cambios al repositorio.

En el contexto de aplicaciones modernas, esta pipeline no solo compila código, sino que ejecuta pruebas unitarias y de integración, analiza seguridad, genera artefactos y despliega en diferentes entornos (desarrollo, staging, producción). El valor real está en la retroalimentación inmediata: si un test falla, el desarrollador lo sabe en minutos, no días, reduciendo el tiempo de corrección de errores.

Cómo funciona en la práctica

Vamos a construir una pipeline para una aplicación Node.js con React frontend y API backend. El flujo tendrá estas etapas:

  1. Trigger: Se activa al hacer push a la rama main o abrir un pull request.
  2. Checkout: GitHub Actions descarga el código del repositorio.
  3. Setup: Configura Node.js y dependencias.
  4. Lint y Build: Verifica estilo de código y compila.
  5. Tests: Ejecuta pruebas unitarias y de integración.
  6. Security Scan: Analiza vulnerabilidades con CodeQL.
  7. Deploy: Despliega a un entorno de staging (Vercel para frontend, Heroku para backend).

Cada etapa es un job en GitHub Actions, que puede ejecutarse en paralelo o secuencialmente. Si una etapa falla, la pipeline se detiene, previniendo desplegar código defectuoso.

Código en acción

Aquí está el archivo .github/workflows/ci-cd-pipeline.yml que define nuestra pipeline:

name: CI/CD Pipeline

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

jobs:
  lint-and-build:
    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 ESLint
        run: npm run lint
      
      - name: Build application
        run: npm run build

  test:
    runs-on: ubuntu-latest
    needs: lint-and-build
    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
        env:
          CI: true

  security-scan:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      
      - name: Initialize CodeQL
        uses: github/codeql-action/init@v2
        with:
          languages: javascript
      
      - name: Perform CodeQL Analysis
        uses: github/codeql-action/analyze@v2

  deploy:
    runs-on: ubuntu-latest
    needs: [test, security-scan]
    if: github.ref == 'refs/heads/main'
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      
      - name: Deploy to Vercel (Frontend)
        run: |
          npm install -g vercel
          vercel --prod --token=${{ secrets.VERCEL_TOKEN }}
      
      - name: Deploy to Heroku (Backend)
        run: |
          git push https://heroku:${{ secrets.HEROKU_API_KEY }}@git.heroku.com/${{ secrets.HEROKU_APP_NAME }}.git main

Antes de refactorizar, teníamos jobs separados para frontend y backend. Después, los combinamos en una pipeline unificada con dependencias claras (needs). Esto mejora la eficiencia y visibilidad.

Errores comunes

  • No usar secrets correctamente: Exponer tokens en el código. Solución: Usa GitHub Secrets y referéncialos con ${{ secrets.NOMBRE }}.
  • Jobs sin dependencias: Ejecutar deploy antes de que pasen los tests. Solución: Define needs para controlar el orden.
  • Ignorar el cache: Reinstalar dependencias cada vez, ralentizando la pipeline. Solución: Implementa caching con actions/cache.
  • No manejar fallos: Si un job falla, la pipeline se detiene sin limpieza. Solución: Usa continue-on-error o steps de cleanup.
  • Desplegar en cada PR: Consumir recursos innecesarios. Solución: Usa condiciones como if: github.ref == 'refs/heads/main'.

Checklist de dominio

  1. ¿Puedes crear un workflow que se active en push y pull requests?
  2. ¿Sabes configurar jobs con dependencias usando needs?
  3. ¿Implementas caching para acelerar builds?
  4. ¿Usas GitHub Secrets para manejar credenciales de forma segura?
  5. ¿Incluyes etapas de lint, test, security y deploy?
  6. ¿Manejas condiciones para controlar cuándo ejecutar deploy?
  7. ¿Monitorizas la pipeline con badges en el README?

Implementa una pipeline CI/CD para una app demo de tareas

En este ejercicio, crearás una pipeline completa para una aplicación de lista de tareas (todo app) con frontend en React y backend en Node.js. Sigue estos pasos:

  1. Prepara el entorno:
    • Forkea este repositorio de ejemplo: https://github.com/example/todo-app-demo
    • Clona tu fork localmente y navega al directorio.
  2. Crea el workflow:
    • En tu repositorio, crea un archivo en .github/workflows/ci-cd.yml.
    • Define el trigger para activarse en push a main y pull requests.
  3. Configura los jobs:
    • Job 1: lint-build - Usa actions/checkout, setup-node, instala dependencias con npm ci, ejecuta ESLint y build.
    • Job 2: test - Depende de lint-build, ejecuta tests con npm test.
    • Job 3: deploy-staging - Depende de test, despliega a Vercel (frontend) y Heroku (backend) solo en la rama main.
  4. Agrega mejoras:
    • Implementa caching para node_modules usando actions/cache.
    • Añade un step de security scan con CodeQL para JavaScript.
  5. Prueba la pipeline:
    • Haz un push a tu rama main y verifica que todos los jobs pasen en la pestaña Actions de GitHub.
    • Abre un pull request y confirma que la pipeline se ejecute.

Entrega: Sube el archivo YAML a tu repositorio y comparte el link en la discusión del curso.

Pistas
  • Usa el ejemplo de código de la lección como base, adaptando los nombres de los jobs y steps.
  • Para caching, investiga la acción actions/cache con la clave 'node-modules-${{ hashFiles('package-lock.json') }}'.
  • Configura los secrets VERCEL_TOKEN y HEROKU_API_KEY en Settings > Secrets and variables > Actions de tu repositorio.

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.