¿Qué es CI/CD? Guía completa con ejemplos prácticos

¿Has vivido esa pesadilla de hacer deploy de tu código un viernes en la tarde y que todo se rompa? Yo sí, varias veces. O tal vez has trabajado en equipos donde cada deploy era como jugar a la lotería: a veces funcionaba, a veces no. Pues déjame contarte sobre CI/CD, una metodología que cambió completamente mi forma de trabajar y que probablemente también transforme la tuya.
CI/CD: el superpoder que necesita tu código
CI/CD significa Continuous Integration (Integración Continua) y Continuous Deployment (Despliegue Continuo). Básicamente, es como tener un asistente súper eficiente que se encarga de probar tu código, empaquetarlo y desplegarlo automáticamente cada vez que haces un cambio.
Continuous Integration - Tu guardaespaldas automático
La integración continua es como tener un vigilante que revisa tu código cada vez que lo subes al repositorio. En mi experiencia, esto es un salvavidas porque:
Cada push activa automáticamente:
- Compilación del código (si algo está roto, te lo dice inmediatamente)
- Ejecución de pruebas unitarias (tu red de seguridad)
- Análisis de calidad de código (ese amigo honesto que te dice cuando tu código apesta)
- Validación de dependencias (para evitar sorpresas desagradables)
Continuous Deployment - Tu piloto automático
El despliegue continuo es la magia que toma tu código validado y lo pone en producción sin que tengas que tocar ni un botón. Incluye:
- Despliegue automático a entornos de staging
- Pruebas de integración en un ambiente real
- Despliegue a producción cuando todo está verde
¿Cómo funciona esta magia por dentro?
El flujo que me salvó la vida
- Haces commit y push → Tu código llega al repo
- CI despierta → "¡Oye, hay código nuevo!"
- Ejecuta todas las pruebas → Como un inspector muy minucioso
- Si todo está bien, hace el build → Prepara tu código para el mundo
- CD toma el control → Lo despliega automáticamente
- Monitorea que todo funcione → Como un doctor checando signos vitales
Mi pipeline favorito con GitHub Actions
# .github/workflows/ci-cd.yml
name: CI/CD Pipeline
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- 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: Run linter
run: npm run lint
deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v3
- name: Deploy to production
run: |
echo "Deploying to production..."
# Comandos de despliegue
Las herramientas que realmente uso (y por qué)
GitHub Actions - mi favorita actual
GitHub Actions es como tener todo integrado en tu casa. Si ya usas GitHub, es súper conveniente:
# Ejemplo de workflow para React
name: React App CI/CD
on:
push:
branches: [ main ]
jobs:
build-and-deploy:
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 and build
run: |
npm ci
npm run build
- name: Deploy to Vercel
uses: amondnet/vercel-action@v20
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
Jenkins - el veterano que sigue dando pelea
Jenkins es como ese carro viejo que siempre arranca. Puede ser un poco más complicado de configurar, pero es súper potente:
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'npm install'
sh 'npm run build'
}
}
stage('Test') {
steps {
sh 'npm test'
}
}
stage('Deploy') {
steps {
sh 'npm run deploy'
}
}
}
}
Otras opciones que he probado
- GitLab CI/CD: Excelente si ya estás en GitLab
- CircleCI: Rápido como un rayo
- Azure DevOps: La opción de Microsoft (bastante buena, la verdad)
- Travis CI: Clásico para proyectos open source
Por qué CI/CD cambió mi vida (no exagero)
1. Caza bugs antes de que me causen problemas
// Ejemplo de test que se ejecuta automáticamente
describe('Calculator', () => {
test('should add two numbers correctly', () => {
expect(add(2, 3)).toBe(5);
});
test('should handle edge cases', () => {
expect(add(0, 0)).toBe(0);
expect(add(-1, 1)).toBe(0);
});
});
2. Deploys sin estrés (la vida es hermosa)
Antes de CI/CD, cada deploy era un evento. Ahora:
- Cambios pequeños: Son más fáciles de entender y revertir
- Feedback constante: Los usuarios ven mejoras todo el tiempo
- Cero drama: Los deploys automáticos eliminan errores humanos
3. Código de mejor calidad (mi yo del pasado me lo agradece)
# Ejemplo de pipeline que incluye quality checks
- name: Code Quality Check
run: |
npm run lint
npm run test:coverage
npm run security-audit
Lo que he aprendido haciendo CI/CD
1. Las pruebas automáticas son tu mejor amigo
// Estructura de pruebas completa
describe('User Authentication', () => {
// Pruebas unitarias
test('should validate email format', () => {
expect(validateEmail('test@example.com')).toBe(true);
});
// Pruebas de integración
test('should authenticate user with valid credentials', async () => {
const response = await authenticateUser('user@test.com', 'password123');
expect(response.success).toBe(true);
});
});
2. Separa tus entornos (enserio, hazlo)
# Diferentes entornos en el pipeline
environments:
development:
url: https://dev.miapp.com
staging:
url: https://staging.miapp.com
production:
url: https://miapp.com
3. Ten un plan B (rollback automático)
- name: Deploy with rollback
run: |
docker deploy --stack production
./health-check.sh
if [ $? -ne 0 ]; then
docker rollback production
exit 1
fi
4. Monitorea todo como si fuera tu bebé
// Ejemplo de health check
app.get('/health', (req, res) => {
const healthStatus = {
status: 'healthy',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
memory: process.memoryUsage()
};
res.json(healthStatus);
});
Cómo empezar sin volverse loco
1. Lo básico primero
# Crear estructura de proyecto
mkdir mi-app-cicd
cd mi-app-cicd
npm init -y
# Instalar dependencias de testing
npm install --save-dev jest supertest
2. Configura tus scripts (esto es clave)
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"lint": "eslint src/",
"build": "npm run lint && npm run test && webpack --mode production",
"deploy": "npm run build && ./deploy.sh"
}
}
3. Tu primer pipeline (mantén la calma)
# .github/workflows/main.yml
name: CI/CD
on: [push, pull_request]
jobs:
ci-cd:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- run: npm ci
- run: npm run build
- run: npm test
- name: Deploy
if: github.ref == 'refs/heads/main'
run: npm run deploy
Mi reflexión personal sobre CI/CD
Después de años trabajando con CI/CD, puedo decir honestamente que es una de esas tecnologías que te cambian la forma de ver el desarrollo. Ya no es solo automatizar tareas; es crear un flujo de trabajo donde puedes tener confianza en tus cambios.
Lo importante es empezar simple. No trates de crear el pipeline perfecto desde el día uno. Comienza con pruebas automáticas, luego automatiza el build, y finalmente el despliegue. Cada paso te dará más confianza para el siguiente.
En mi experiencia, los equipos que adoptan CI/CD no solo entregan software más rápido, sino que duermen mejor por las noches. Y eso, amigos, no tiene precio.
CI/CD no es solo una herramienta técnica; es una filosofía de trabajo que te permite iterar rápido, fallar rápido, y aprender rápido. Una vez que lo pruebes, no vas a querer volver al caos de los deploys manuales.
¿Ya tienes experiencia con CI/CD? ¿Cuál ha sido tu mayor dolor de cabeza o tu mayor victoria? Me encantaría conocer tu historia con estas herramientas.