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: Instalar Node.js manualmente (requerido por las acciones de GitHub) - name: 📦 Instalar Node.js shell: bash run: | echo "Verificando si Node.js está instalado..." if ! command -v node &> /dev/null; then echo "Node.js no encontrado, instalando..." # Detectar el sistema operativo if [ -f /etc/debian_version ]; then # Debian/Ubuntu curl -fsSL https://deb.nodesource.com/setup_20.x | bash - apt-get install -y nodejs elif [ -f /etc/redhat-release ]; then # RedHat/CentOS/Fedora curl -fsSL https://rpm.nodesource.com/setup_20.x | bash - yum install -y nodejs elif [ -f /etc/alpine-release ]; then # Alpine Linux apk add --no-cache nodejs npm else echo "Sistema operativo no soportado, intentando instalación genérica..." # Intentar con nvm como fallback curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" nvm install 20 fi else echo "Node.js ya está instalado: $(node --version)" fi # Verificar instalación node --version npm --version # PASO 2: Checkout del Código - name: 🚀 Checkout del Código uses: actions/checkout@v4 with: fetch-depth: 0 # PASO 3: Detener y eliminar contenedores anteriores - name: 🛑 Detener Contenedores Anteriores shell: bash 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 shell: bash 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 shell: bash 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 shell: bash 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 shell: bash 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() shell: bash 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