diff --git a/.gitea/workflows/deployment.yml b/.gitea/workflows/deployment.yml new file mode 100644 index 0000000..2749654 --- /dev/null +++ b/.gitea/workflows/deployment.yml @@ -0,0 +1,111 @@ +name: CI/CD - Francia Ocupada (La Resistencia) +run-name: Build & Deploy por ${{ gitea.actor }} + +on: + push: + branches: + - main + - master + workflow_dispatch: + +# Otorga permiso de lectura al token del workflow (necesario para el checkout) +permissions: + contents: read + +jobs: + build-and-deploy: + # Usamos la etiqueta que configuramos en el runner (production-ready:host) + runs-on: [production-ready] + + steps: + # PASO 1: Checkout del Código + - name: 🚀 Checkout del Código + uses: actions/checkout@v4 + with: + server-url: ${{ gitea.server_url }} + repository: ${{ gitea.repository }} + token: ${{ gitea.token }} + fetch-depth: 0 + + # PASO 2: Configurar Node.js (necesario para ejecutar las acciones de checkout/setup) + - name: ⚙️ Configurar Node.js (Necesario para las acciones) + uses: actions/setup-node@v4 + with: + node-version: '20' + + # PASO 3: Detener y eliminar contenedores anteriores + - name: 🛑 Detener Contenedores Anteriores + run: | + echo "Deteniendo contenedores existentes..." + docker compose -f docker-compose_prod.yml down || true + + # Limpieza de contenedores huérfanos + docker container prune -f || true + + echo "Contenedores anteriores detenidos y eliminados" + + # PASO 4: Limpiar imágenes antiguas (opcional pero recomendado) + - name: 🧹 Limpiar Imágenes Antiguas + run: | + echo "Limpiando imágenes sin usar..." + docker image prune -f || true + echo "Limpieza completada" + + # PASO 5: Construir las imágenes Docker + - name: 🔨 Construir Imágenes Docker + run: | + echo "Construyendo imágenes con docker-compose_prod.yml..." + docker compose -f docker-compose_prod.yml build --no-cache + + # Etiquetar con el SHA del commit para trazabilidad + TAG_VERSION="${{ gitea.sha }}" + + docker tag resistencia-client:latest resistencia-client:${TAG_VERSION} + docker tag resistencia-server:latest resistencia-server:${TAG_VERSION} + + echo "✅ Imágenes construidas:" + echo " - resistencia-client:latest (${TAG_VERSION})" + echo " - resistencia-server:latest (${TAG_VERSION})" + + # PASO 6: Desplegar los contenedores + - name: 📦 Desplegar Aplicación + run: | + echo "Desplegando aplicación con docker-compose_prod.yml..." + docker compose -f docker-compose_prod.yml up -d + + echo "✅ Aplicación desplegada exitosamente" + echo "" + echo "📊 Estado de los contenedores:" + docker compose -f docker-compose_prod.yml ps + + # PASO 7: Verificar que los contenedores están corriendo + - name: ✅ Verificar Despliegue + run: | + echo "Esperando 10 segundos para que los contenedores inicien..." + sleep 10 + + echo "Verificando estado de los contenedores..." + docker compose -f docker-compose_prod.yml ps + + # Verificar que los contenedores están corriendo + if [ $(docker compose -f docker-compose_prod.yml ps -q | wc -l) -eq 0 ]; then + echo "❌ ERROR: No hay contenedores corriendo" + docker compose -f docker-compose_prod.yml logs + exit 1 + fi + + echo "✅ Verificación completada" + echo "" + echo "🌐 Aplicación disponible en:" + echo " - Frontend: https://franciaocupada.martivich.es" + echo " - API: https://api.franciaocupada.martivich.es" + + # PASO 8: Mostrar logs recientes (útil para debugging) + - name: 📋 Mostrar Logs Recientes + if: always() + run: | + echo "Logs del cliente (últimas 50 líneas):" + docker compose -f docker-compose_prod.yml logs --tail=50 client || true + echo "" + echo "Logs del servidor (últimas 50 líneas):" + docker compose -f docker-compose_prod.yml logs --tail=50 server || true diff --git a/CAMBIOS_SESION_2025-12-08.md b/CAMBIOS_SESION_2025-12-08.md deleted file mode 100644 index 38e4bf5..0000000 --- a/CAMBIOS_SESION_2025-12-08.md +++ /dev/null @@ -1,171 +0,0 @@ -RESUMEN DE CAMBIOS - SESIÓN 2025-12-08 -======================================== - -## 1. CORRECCIÓN DE PANTALLAS DE VICTORIA (ALLIED_WIN y NAZIS_WIN) - -### Problema inicial: -- Las pantallas de victoria mostraban el tablero de juego encima de la imagen de fondo -- Había imágenes duplicadas y rutas incorrectas (.jpg vs .png) - -### Solución implementada: - -#### GameBoard.tsx: -- **Fondo dinámico según fase**: El fondo del componente GameBoard ahora cambia según la fase: - * ALLIED_WIN → muestra `/assets/images/tokens/mission_success.png` - * NAZIS_WIN → muestra `/assets/images/tokens/mission_fail.png` - * Otras fases → muestra `/assets/images/ui/bg_game.png` - -- **Área del tablero oculta en victorias**: El div del tablero (con las cartas de misión, tablero táctico, etc.) - se oculta completamente cuando `gameState.phase === ALLIED_WIN || gameState.phase === NAZIS_WIN` - -#### VictoryScreen.tsx: -- **Eliminada imagen de fondo redundante**: Se eliminó el div con la imagen de fondo que intentaba cargar - `mission_fail.jpg` y `mission_success.jpg`, ya que el GameBoard ahora maneja estos fondos. - -### Archivos modificados: -- `client/src/components/GameBoard.tsx` (líneas 293-307, 309-442) -- `client/src/components/VictoryScreen.tsx` (líneas 39-50 eliminadas) - -### Commit: -- Hash: 6e65152 -- Mensaje: "feat: Fix victory screens background images" - ---- - -## 2. MEJORA DE CARTAS DE MISIÓN (Fase MISSION) - -### Problema inicial: -- Las cartas solo se opacaban cuando se seleccionaba la otra -- Si solo había una carta (jugadores aliados), no había feedback visual de que se había seleccionado - -### Solución implementada: - -#### Cambio de lógica de opacidad: -**ANTES:** -- Sin voto: todas las cartas al 100% de opacidad -- Con voto: la carta NO seleccionada se opaca al 50% - -**DESPUÉS:** -- Sin voto: todas las cartas al 50% de opacidad (opacadas por defecto) -- Con voto: solo la carta seleccionada se pone al 100%, las demás permanecen al 50% - -#### Implementación: -```tsx -// Carta de Éxito -className={`group transition-opacity ${missionVote === true ? 'opacity-100' : 'opacity-50'}`} - -// Carta de Sabotaje (solo alemanes) -className={`group transition-opacity ${missionVote === false ? 'opacity-100' : 'opacity-50'}`} -``` - -### Archivos modificados: -- `client/src/components/GameBoard.tsx` (líneas 628-678) - -### Beneficio: -- Ahora es fácil ver qué carta has seleccionado, incluso cuando solo tienes una opción disponible - ---- - -## 3. INTENTO DE MEJORA DEL HISTORIAL DE MISIONES (NO FUNCIONAL) - -### Objetivo: -- Mostrar los participantes de cada misión al hacer clic en el número del historial - -### Implementación intentada: - -#### Estado añadido: -```tsx -const [expandedMission, setExpandedMission] = useState(null); -``` - -#### Lógica implementada: -- Click en número de misión → expande mostrando nombres de participantes -- Click de nuevo → colapsa la lista -- Solo una misión puede estar expandida a la vez -- Indicador visual: anillo amarillo alrededor del número cuando está expandido - -#### Código añadido en GameBoard.tsx (líneas 856-899): -```tsx -{gameState.missionHistory.map((mission, idx) => { - const isExpanded = expandedMission === idx; - - return ( -
-
{ - e.stopPropagation(); - console.log('Click en misión', idx, 'Estado actual:', expandedMission); - setExpandedMission(isExpanded ? null : idx); - }} - > - {mission.round} -
- - {isExpanded && ( -
- {mission.team.map((playerId) => { - const player = gameState.players.find(p => p.id === playerId); - return ( -
- {player?.name || playerId} -
- ); - })} -
- )} -
- ); -})} -``` - -### Archivos modificados: -- `client/src/components/GameBoard.tsx` (líneas 26, 856-899) - -### Estado: -⚠️ **NO FUNCIONAL** - El click no dispara la expansión de la lista de participantes. -Posibles causas a investigar: -- Conflicto con otros event handlers -- Problema con el z-index o posicionamiento -- Estado no actualizándose correctamente -- Necesidad de reiniciar servicios Docker - ---- - -## RESUMEN DE COMMITS - -1. **6e65152** - "feat: Fix victory screens background images" - - Corregidas pantallas de victoria - - Eliminadas imágenes redundantes - - Fondo dinámico según fase - ---- - -## ARCHIVOS PRINCIPALES MODIFICADOS - -1. `client/src/components/GameBoard.tsx` - - Fondo dinámico para fases de victoria - - Área del tablero oculta en victorias - - Opacidad de cartas de misión mejorada - - Intento de historial expandible (no funcional) - -2. `client/src/components/VictoryScreen.tsx` - - Eliminada imagen de fondo redundante - ---- - -## PENDIENTES / PROBLEMAS CONOCIDOS - -1. ❌ **Historial de misiones expandible no funciona** - - El código está implementado pero el click no dispara la acción - - Requiere investigación adicional - -2. ⚠️ **Errores de lint** - - Múltiples errores de tipo "JSX element implicitly has type 'any'" - - Son falsos positivos del IDE en entorno Dockerizado - - No afectan la funcionalidad de la aplicación - ---- - -Fecha: 2025-12-08 -Hora: 22:59 diff --git a/CI-CD-README.md b/CI-CD-README.md new file mode 100644 index 0000000..03f328a --- /dev/null +++ b/CI-CD-README.md @@ -0,0 +1,167 @@ +# 🚀 CI/CD con Gitea Actions - Francia Ocupada + +## 📋 Configuración Actual + +### Runner Configurado +- **Nombre**: `runner-01-ci-vm` +- **Etiqueta**: `production-ready:host` +- **URL Gitea**: `http://gitea.local:3000` +- **Estado**: ✅ Corriendo sin problemas + +### Workflow Creado +- **Ubicación**: `.gitea/workflows/deployment.yml` +- **Trigger**: Push a `main` o `master`, o ejecución manual +- **Acciones**: Build y deploy automático con Docker Compose + +## 🔄 Flujo de Despliegue + +El workflow ejecuta los siguientes pasos: + +1. **🚀 Checkout del Código**: Descarga el código del repositorio +2. **⚙️ Configurar Node.js**: Instala Node.js 20 para las acciones +3. **🛑 Detener Contenedores Anteriores**: Para y elimina los contenedores existentes +4. **🧹 Limpiar Imágenes Antiguas**: Elimina imágenes Docker sin usar +5. **🔨 Construir Imágenes Docker**: Construye las imágenes con `docker-compose_prod.yml` +6. **📦 Desplegar Aplicación**: Levanta los contenedores en modo producción +7. **✅ Verificar Despliegue**: Comprueba que los contenedores están corriendo +8. **📋 Mostrar Logs Recientes**: Muestra logs para debugging + +## 🧪 Cómo Hacer Pruebas de Despliegue + +### Opción 1: Push a la rama principal (Automático) + +```bash +# Hacer algún cambio en el código +echo "# Test CI/CD" >> README.md + +# Commit y push +git add . +git commit -m "test: Prueba de CI/CD automático" +git push origin main # o master, según tu rama principal +``` + +### Opción 2: Ejecución Manual desde Gitea + +1. Ve a tu repositorio en Gitea: `http://gitea.local:3000/[tu-usuario]/resistencia` +2. Navega a la pestaña **Actions** +3. Selecciona el workflow **"CI/CD - Francia Ocupada (La Resistencia)"** +4. Haz clic en **"Run workflow"** +5. Selecciona la rama y confirma + +### Opción 3: Forzar un push vacío (sin cambios) + +```bash +# Esto dispara el workflow sin hacer cambios reales +git commit --allow-empty -m "test: Trigger CI/CD workflow" +git push origin main +``` + +## 📊 Monitorear el Despliegue + +### Desde Gitea Web UI +1. Ve a **Actions** en tu repositorio +2. Verás el workflow ejecutándose en tiempo real +3. Haz clic en el workflow para ver los logs detallados de cada paso + +### Desde el Servidor (SSH) +```bash +# Ver estado de los contenedores +docker compose -f docker-compose_prod.yml ps + +# Ver logs en tiempo real +docker compose -f docker-compose_prod.yml logs -f + +# Ver logs de un servicio específico +docker compose -f docker-compose_prod.yml logs -f client +docker compose -f docker-compose_prod.yml logs -f server +docker compose -f docker-compose_prod.yml logs -f db + +# Ver imágenes Docker +docker images | grep resistencia +``` + +## 🔧 Solución de Problemas + +### El workflow falla en el checkout +**Problema**: Error de autenticación con Gitea + +**Solución**: +- Verifica que el token de registro del runner sea correcto +- Asegúrate de que el runner tenga acceso al repositorio + +### El workflow falla en la construcción +**Problema**: Error al construir las imágenes Docker + +**Solución**: +```bash +# En el servidor, construir manualmente para ver el error +cd /ruta/al/proyecto +docker compose -f docker-compose_prod.yml build --no-cache +``` + +### Los contenedores no inician +**Problema**: Los contenedores se detienen inmediatamente + +**Solución**: +```bash +# Ver logs de error +docker compose -f docker-compose_prod.yml logs + +# Verificar configuración +docker compose -f docker-compose_prod.yml config +``` + +### Puerto ya en uso +**Problema**: Los puertos 3000, 4000 o 5432 están ocupados + +**Solución**: +```bash +# Ver qué está usando los puertos +sudo lsof -i :3000 +sudo lsof -i :4000 +sudo lsof -i :5432 + +# Detener contenedores anteriores +docker compose -f docker-compose_prod.yml down +``` + +## 🎯 Verificación Post-Despliegue + +Después de un despliegue exitoso, verifica: + +1. **Frontend accesible**: https://franciaocupada.martivich.es +2. **API accesible**: https://api.franciaocupada.martivich.es +3. **Contenedores corriendo**: + ```bash + docker compose -f docker-compose_prod.yml ps + ``` + Deberías ver 3 contenedores: `client`, `server`, `db` + +4. **Logs sin errores**: + ```bash + docker compose -f docker-compose_prod.yml logs --tail=100 + ``` + +## 📝 Notas Importantes + +- **Rama principal**: El workflow se activa en push a `main` o `master` +- **Etiqueta del runner**: Debe ser `production-ready` (configurada en tu runner) +- **Docker Compose**: Usa `docker-compose_prod.yml` para producción +- **Variables de entorno**: Configuradas en `docker-compose_prod.yml`: + - `NEXT_PUBLIC_API_URL=https://api.franciaocupada.martivich.es` + - `CORS_ORIGIN=https://franciaocupada.martivich.es` + +## 🔐 Seguridad + +- El workflow usa el token de Gitea automáticamente (`${{ gitea.token }}`) +- No es necesario configurar secrets adicionales para este workflow básico +- Si necesitas secrets (API keys, passwords), agrégalos en: + - Gitea → Repositorio → Settings → Secrets + +## 🚀 Próximos Pasos Recomendados + +1. **Pruebas automatizadas**: Agregar tests antes del deploy +2. **Notificaciones**: Configurar notificaciones de éxito/fallo +3. **Rollback automático**: Implementar rollback si el deploy falla +4. **Health checks**: Verificar que la app responde correctamente +5. **Backup de DB**: Hacer backup antes de cada deploy