feat: Configuración CI/CD con Gitea Actions
Some checks failed
CI/CD - Francia Ocupada (La Resistencia) / build-and-deploy (push) Failing after 40s
Some checks failed
CI/CD - Francia Ocupada (La Resistencia) / build-and-deploy (push) Failing after 40s
- Agregado workflow de deployment automático (.gitea/workflows/deployment.yml) - Workflow configurado para runner 'production-ready' - Build y deploy automático con docker-compose_prod.yml - Verificación de estado post-despliegue - Documentación completa en CI-CD-README.md
This commit is contained in:
111
.gitea/workflows/deployment.yml
Normal file
111
.gitea/workflows/deployment.yml
Normal file
@@ -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
|
||||
@@ -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<number | null>(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 (
|
||||
<div key={idx} className="relative">
|
||||
<div
|
||||
className={`... ${isExpanded ? 'ring-2 ring-yellow-400' : ''}`}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
console.log('Click en misión', idx, 'Estado actual:', expandedMission);
|
||||
setExpandedMission(isExpanded ? null : idx);
|
||||
}}
|
||||
>
|
||||
{mission.round}
|
||||
</div>
|
||||
|
||||
{isExpanded && (
|
||||
<div className="absolute top-10 right-0 bg-black/95 p-2 rounded border border-white/30 min-w-max z-[100]">
|
||||
{mission.team.map((playerId) => {
|
||||
const player = gameState.players.find(p => p.id === playerId);
|
||||
return (
|
||||
<div key={playerId} className="text-xs text-white whitespace-nowrap">
|
||||
{player?.name || playerId}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
```
|
||||
|
||||
### 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
|
||||
167
CI-CD-README.md
Normal file
167
CI-CD-README.md
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user