¿Qué aprenderás en este post?

Cómo automatizar completamente el proceso de integración y despliegue de una aplicación Node.js usando Azure DevOps, desde cero y paso a paso.

🎬 ¿Prefieres verlo en vídeo?

Si quieres ver el proceso en acción antes de leer el post, aquí tienes el videotutorial completo.

▶ Ver en YouTube

🔴 El problema

Imagina un equipo de desarrollo donde cada persona trabaja en su parte del código de forma independiente. Llega el momento de unirlo todo y lanzar una nueva versión… y empieza el caos. Conflictos entre archivos, errores que no aparecían en local, despliegues manuales que fallan a mitad. Horas perdidas en algo que debería ser rutinario.

Este es uno de los problemas más comunes en el desarrollo de software profesional: la falta de automatización en el proceso de integración y despliegue. Cada vez que hay que lanzar una nueva versión, alguien tiene que revisar el código manualmente, ejecutar los tests, construir la aplicación y subirla al servidor. Un proceso lento, repetitivo y propenso a errores humanos.

La solución a este problema tiene nombre: CI/CD, Integración Continua y Despliegue Continuo. La idea es simple pero poderosa: automatizar todo ese proceso para que cada vez que un desarrollador suba código, el sistema lo compruebe, lo pruebe y lo prepare para producción de forma completamente automática.

📌 Conceptos clave

Integración Continua (CI)

Fusionar el código de forma frecuente verificando automáticamente que todo funciona con cada cambio.

Despliegue Continuo (CD)

Una vez que el código pasa las verificaciones automáticas, se empaqueta y queda listo para producción.

Azure DevOps

Plataforma de Microsoft que integra repositorio, pipelines y gestión del ciclo de vida del software.

💡 Cómo lo vamos a resolver

Vamos a construir desde cero un sistema de CI/CD completo usando Azure DevOps. Para demostrar el proceso usaremos una API REST sencilla hecha con Node.js, con tests automáticos incluidos. El objetivo es que al final de este post, cualquier persona pueda replicar exactamente el mismo sistema con su propia aplicación.

🛠️ Herramientas utilizadas

  • Azure DevOps → dev.azure.com (cuenta gratuita)
  • Azure Repos → repositorio de código
  • Azure Pipelines → automatización del pipeline
  • Node.js → entorno de ejecución de la aplicación
  • Jest y Supertest → tests automáticos
  • Git → control de versiones

🔧 Desarrollo paso a paso

PASO 1 — Crear una cuenta en Azure DevOps

Si ya tienes una cuenta de Microsoft o Azure, puedes usarla directamente. Ve a dev.azure.com e inicia sesión. Si es la primera vez, el sistema te pedirá crear una organización, que es tu espacio de trabajo en Azure DevOps.

Una vez dentro verás el panel principal con tus organizaciones y proyectos.

PASO 2 — Crear el proyecto

Dentro de tu organización haz clic en New project. Rellena los campos:

  • Nombre: CI-CD-Demo
  • Visibility: Private
  • Version control: Git

Pulsa Create y en segundos tendrás el proyecto listo. En el menú de la izquierda verás las secciones principales: Repos, Pipelines, Boards y Artifacts.

PASO 3 — Inicializar el repositorio

Ve a Repos → Files. El repositorio estará vacío. Pulsa el botón Initialize para crear la rama main con un README inicial. Esto es necesario antes de poder clonar el repositorio en local.

Una vez inicializado verás el repositorio con el archivo README.md y la rama main activa.

PASO 4 — Clonar el repositorio en tu ordenador

Pulsa el botón Clone en la parte superior derecha. Verás la URL del repositorio y el botón Generate Git Credentials. Pulsa ese botón para obtener las credenciales que usarás en la terminal.

Abre una terminal en tu ordenador y ejecuta:

git clone https://TUORGANIZACION@dev.azure.com/TUORGANIZACION/CI-CD-Demo/_git/CI-CD-Demo
cd CI-CD-Demo

Cuando te pida la contraseña, pega la que acabas de generar en Azure DevOps.

PASO 5 — Crear la aplicación

Vamos a crear una API REST sencilla con Node.js. Crea los siguientes archivos dentro de la carpeta del repositorio:

app.js — Lógica principal de la API:

const express = require('express');
const app = express();

app.get('/bienvenida', (req, res) => {
    res.json({
        mensaje: 'Esta es la primera version de mi aplicacion implementando CI/CD',
        version: '1.0.0',
        status: 'ok'
    });
});

module.exports = app;

server.js — Arranque del servidor:

const app = require('./app');
const PORT = process.env.PORT || 3000;

app.listen(PORT, () => {
    console.log(`Servidor corriendo en puerto ${PORT}`);
});

app.test.js — Tests automáticos con Jest:

const request = require('supertest');
const app = require('./app');

describe('GET /bienvenida', () => {
    it('debe devolver status 200', async () => {
        const res = await request(app).get('/bienvenida');
        expect(res.statusCode).toBe(200);
    });
    it('debe devolver el mensaje correcto', async () => {
        const res = await request(app).get('/bienvenida');
        expect(res.body.mensaje).toBe('Esta es la primera version de mi aplicacion implementando CI/CD');
    });
    it('debe devolver version 1.0.0', async () => {
        const res = await request(app).get('/bienvenida');
        expect(res.body.version).toBe('1.0.0');
    });
    it('debe devolver status ok', async () => {
        const res = await request(app).get('/bienvenida');
        expect(res.body.status).toBe('ok');
    });
});

package.json — Dependencias del proyecto:

{
  "name": "ci-cd-demo",
  "version": "1.0.0",
  "description": "API demo para CI/CD con Azure DevOps",
  "main": "server.js",
  "scripts": {
    "start": "node server.js",
    "test": "jest --forceExit"
  },
  "dependencies": {
    "express": "^4.18.2"
  },
  "devDependencies": {
    "jest": "^29.7.0",
    "supertest": "^6.3.4"
  }
}

PASO 6 — Subir el código al repositorio

Con los archivos creados, súbelos a Azure Repos con estos tres comandos:

git add .
git commit -m "Primera versión de la aplicación"
git push

Si vuelves a Azure Repos verás los archivos ya disponibles en el repositorio.

PASO 7 — Crear el Pipeline

Este es el paso más importante. Ve a Pipelines en el menú de la izquierda y pulsa New Pipeline. El asistente te guiará:

  • ¿Dónde está tu código? → Selecciona Azure Repos Git
  • Selecciona el repositorio → Elige CI-CD-Demo
  • Configura el pipeline → Selecciona la plantilla Node.js

⭐ El corazón del CI/CD

Azure generará automáticamente el archivo azure-pipelines.yml. Este archivo es el cerebro del pipeline, el que orquesta absolutamente todo el proceso automático. Sin él no hay CI/CD. Vive dentro del propio repositorio junto al código y podemos modificarlo para adaptarlo a nuestro proyecto.

trigger:
  - main

pool:
  vmImage: 'ubuntu-latest'

steps:
  - task: NodeTool@0
    inputs:
      versionSpec: '18.x'
    displayName: 'Instalar Node.js'

  - script: npm install
    displayName: 'Instalar dependencias'

  - script: npm test
    displayName: 'Ejecutar tests'

  - task: ArchiveFiles@2
    inputs:
      rootFolderOrFile: '$(Build.SourcesDirectory)'
      includeRootFolder: false
    displayName: 'Empaquetar aplicación'

  - task: PublishBuildArtifacts@1
    displayName: 'Publicar artefacto'
  • trigger: main → El pipeline se activa automáticamente con cada push a la rama main
  • pool: ubuntu-latest → Azure usa una máquina virtual Ubuntu en la nube
  • npm install → Descarga todas las dependencias
  • npm test → Ejecuta los tests. Si alguno falla, el pipeline se detiene aquí
  • ArchiveFiles → Empaqueta la aplicación en un ZIP
  • PublishBuildArtifacts → Publica el artefacto final

Pulsa Save and Run para guardar el archivo y lanzar la primera ejecución.

PASO 8 — Verificar el pipeline

Una vez lanzado verás el pipeline ejecutándose en tiempo real. Cada paso aparece con su estado. Si todo va bien verás todos los pasos en verde y el mensaje 1 published indicando que el artefacto se ha generado correctamente.

PASO 9 — Comprobar el trigger automático

Para demostrar que el CI/CD funciona de verdad, haz un cambio en el código y súbelo:

git add .
git commit -m "Actualización a versión 2"
git push

Vuelve a Azure Pipelines y observa cómo el pipeline se ha disparado automáticamente sin que hayas tocado nada en Azure DevOps. Eso es el CI/CD funcionando en la práctica.

⚠️ Problemas encontrados y recomendaciones

Conflicto al hacer git push

Cuando Azure guarda el archivo azure-pipelines.yml en el repositorio remoto, tu copia local no lo tiene todavía. Si intentas hacer push recibirás un error. La solución es ejecutar siempre git pull antes de git push.

Adopta siempre este flujo de trabajo:

git pull
git add .
git commit -m "descripción del cambio"
git push

El YAML es sensible a la indentación

Un espacio mal puesto en el archivo azure-pipelines.yml puede hacer que el pipeline falle con un error poco descriptivo. Si el pipeline no arranca correctamente, lo primero que hay que revisar es la indentación del archivo.

🤔 Posibles debates y puntos de vista

¿CI/CD solo para equipos grandes?

No. Incluso trabajando en solitario, un pipeline automático te protege de subir código roto y te obliga a mantener una disciplina de tests que ahorra muchas horas de depuración.

¿Azure DevOps o GitHub Actions?

GitHub Actions está integrado directamente en GitHub. Azure DevOps ofrece un ecosistema más completo para equipos empresariales. Ambas son válidas según el contexto del proyecto.

¿Se puede extender este pipeline?

Absolutamente. Se puede añadir análisis de calidad de código, notificaciones por Slack, despliegue automático a Azure, o protección de ramas para que ningún merge se haga sin pasar el pipeline.

¿Qué pasa si un test falla?

El pipeline se detiene automáticamente y el código no avanza. Pero los tests son tan buenos como lo que el desarrollador haya escrito. Un pipeline con tests incompletos da una falsa sensación de seguridad.

🔗 Recursos

Autor: Arturo Yáñez Gómez

Máster: Desarrollo Full Stack + Arquitecturas Cloud

Centro: Tajamar Tech

Año académico: 2025-2026

Código: github.com/arturoyz/CI-CD-Demo

LinkedIn: linkedin.com/in/arturoyanez

Leave a Comment

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.