CI/CD de este portfolio
GitHub Actions en acción
Introducción: ¿Por qué CI/CD?
Continuous Integration / Continuous Deployment no es solo automatización. Es un cambio de mentalidad sobre cómo desarrollamos y desplegamos software.
Antes del CI/CD (el caos manual)
❌ Deploy manual: FTP, SCP, copiar archivos uno por uno
❌ Tests locales: "Funciona en mi máquina" ™
❌ Validación humana: Esperar que alguien revise antes de mergear
❌ Bugs en producción: Descubiertos por usuarios, no por tests
❌ Miedo a deployear: Especialmente viernes o antes de vacaciones
❌ Rollbacks manuales: Pánico, SSH, git reset, rezar
Resultado: Deploys lentos, bugs frecuentes, estrés constante.
Después del CI/CD (confianza y velocidad)
✅ Push a master = producción: Automático en minutos
✅ Tests en cada PR: Validación automática antes de mergear
✅ Validación estricta: PHPStan, tests unitarios, E2E, todo automático
✅ Deploy 10+ veces/día: Sin miedo, sin estrés
✅ Rollback en 1 click: Si algo falla, volver atrás es trivial
Resultado: Velocidad, confianza, calidad.
El pipeline completo
CI: Continuous Integration
Qué se ejecuta automáticamente en cada PR:
- Tests unitarios (PHPUnit): 148 tests validando dominio e infraestructura
- Análisis estático (PHPStan level 9): Detecta bugs sin ejecutar código
- CS Fixer (dry-run): Valida estilo PSR-12
- ESLint: TypeScript y Playwright
Resultado: PR no se puede mergear sin QA en verde.
CD: Continuous Deployment
Qué ocurre al hacer merge a master:
1. Bump versión semántica
Lee commits desde último tag
feat: → MINOR | fix: → PATCH
2. Deploy SSH al VPS de producción
git pull en /var/www/portfolio
3. Build de producción
composer install --no-dev --optimize-autoloader
cache:clear + cache:warmup
reload php-fpm
4. E2E Tests contra producción
Playwright contra https://josemoreupeso.es
continue-on-error: true
5. Back-merge automático master → develop
chore: back-merge from master after deploy [skip ci]
6. Sync al repositorio público
Mantiene el repo open-source actualizado
Tiempo total: ~7 minutos de commit a producción.
Estrategia de branching: GitFlow simplificado
master (producción)
↑
└─ Pull Requests con QA obligatorio
↑
└─ develop (integración)
↑
└─ feature/t{num}_{desc}
- master: Código en producción. Solo merges via PR con QA en verde. Deploy automático.
- develop: Integración. Recibe merges de features.
- **feature/***: Una feature por rama, PR a develop cuando está lista.
Semantic versioning automático
El script bump-version.sh analiza los commits desde el último tag:
feat!:→ MAJORfeat:→ MINORfix:,docs:,chore:,refactor:,test:→ PATCH
Cada merge a master es una versión nueva. Actualmente en v18.0.0. El footer de la página siempre muestra la versión correcta.
Métricas reales
- CI duration: ~4 minutos (PHPUnit + PHPStan + CS Fixer + ESLint)
- CD duration: ~3 minutos (deploy + E2E + back-merge + sync)
- Total: ~7 minutos de commit a producción
- Deploys: más de 18 releases en producción
- Failed deploys: 0 desde implementación del pipeline
- Bugs en producción detectados post-deploy: 0
Conclusión
Cada vez que hago merge a master y veo los 7 pasos ejecutarse en GitHub Actions, con el version bump automático, el deploy SSH, la E2E en producción, el back-merge y el sync al repo público... entiendo por qué los equipos que tienen esto no quieren volver atrás.
CI/CD no es para proyectos grandes. Es para cualquier proyecto que quieras mantener con confianza.