name: Optimized Build and Deploy with Maintenance Window on: push: branches: - main jobs: remote-build-and-deploy: runs-on: ubuntu-latest steps: - name: Run Optimized CI/CD Process on Host via SSH run: | set -e apt-get update -qq && apt-get install -y openssh-client git mkdir -p ~/.ssh echo "${{ secrets.PROD_SERVER_SSH_KEY }}" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa ssh-keyscan -H ${{ secrets.PROD_SERVER_HOST }} >> ~/.ssh/known_hosts ssh ${{ secrets.PROD_SERVER_USER }}@${{ secrets.PROD_SERVER_HOST }} " export UPTIME_KUMA_URL='${{ secrets.UPTIME_KUMA_URL }}' export UPTIME_KUMA_API_KEY='${{ secrets.UPTIME_KUMA_API_KEY }}' export UPTIME_KUMA_MAINTENANCE_ID='${{ secrets.UPTIME_KUMA_MAINTENANCE_ID }}' export DB_SA_PASSWORD='${{ secrets.DB_SA_PASSWORD_SECRET }}' export GITEA_SHA='${{ gitea.sha }}' bash -s " << 'EOSSH' set -e echo "--- INICIO DEL DESPLIEGUE OPTIMIZADO ---" # --- SECCIÓN DE MONITOREO (VERSIÓN CANÓNICA) --- if ! command -v curl &> /dev/null || ! command -v jq &> /dev/null; then echo "Instalando curl y jq..." sudo apt-get update -qq && sudo apt-get install -y curl jq fi # Función que obtiene la LISTA, busca, modifica y envía el objeto de vuelta set_maintenance_status() { local id=$1 local active_state=$2 # 'true' o 'false' echo "Intentando establecer el estado de mantenimiento para ID:${id} a ${active_state}..." # 1. GET LIST: Obtener la lista COMPLETA de todas las ventanas de mantenimiento local maintenance_list=$(curl -s -X GET "${UPTIME_KUMA_URL}/api/maintenances" \ -H "Authorization: Bearer ${UPTIME_KUMA_API_KEY}") # 2. FIND: Usar jq para buscar en la lista nuestro objeto por ID local current_config=$(echo "$maintenance_list" | jq --argjson id "$id" '.[] | select(.id == $id)') if [ -z "$current_config" ]; then echo "Error: No se pudo encontrar una ventana de mantenimiento con ID ${id} en la lista." return 1 fi # 3. MODIFY: Usar jq para cambiar el valor de "active" en el objeto encontrado local modified_config=$(echo "$current_config" | jq --argjson state "${active_state}" '.active = $state') # 4. PUT: Enviar el objeto completo y modificado de vuelta local response=$(curl -s -w "%{http_code}" -X PUT "${UPTIME_KUMA_URL}/api/maintenances/${id}" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${UPTIME_KUMA_API_KEY}" \ --data-raw "$modified_config") local http_code=$(tail -n1 <<< "$response") if [ "$http_code" -ne 200 ]; then echo "Error al actualizar el estado de mantenimiento. Código HTTP: $http_code" echo "Cuerpo de la respuesta: $(head -n -1 <<< "$response")" return 1 fi echo "Estado de mantenimiento actualizado con éxito." } trap 'echo "--- Limpiando: Reanudando monitoreo ---"; set_maintenance_status "$UPTIME_KUMA_MAINTENANCE_ID" false' EXIT echo "--- Pausando monitoreo en Uptime Kuma ---" set_maintenance_status "$UPTIME_KUMA_MAINTENANCE_ID" true # --- FIN SECCIÓN DE MONITOREO --- # 1. Preparar entorno TEMP_DIR=$(mktemp -d) REPO_OWNER="dmolinari" REPO_NAME="gestionintegralweb" GITEA_REPO_PATH="/var/lib/docker/volumes/gitea-stack_gitea-data/_data/git/repositories/${REPO_OWNER}/${REPO_NAME}.git" echo "Clonando repositorio..." git clone "$GITEA_REPO_PATH" "$TEMP_DIR" cd "$TEMP_DIR" git checkout "$GITEA_SHA" # 2. Construcción paralela build_image() { local dockerfile=$1 local image_name=$2 local context=$3 echo "Construyendo $image_name..." docker build -t "$image_name" -f "$dockerfile" "$context" } echo "Construyendo imágenes..." (build_image "Backend/GestionIntegral.Api/Dockerfile" "dmolinari/gestionintegralweb-backend:latest" ".") & (build_image "Frontend/Dockerfile" "dmolinari/gestionintegralweb-frontend:latest" ".") & wait # 3. Despliegue con Docker Compose cd /opt/gestion-integral echo "Recreando servicios..." docker compose up -d --force-recreate # 4. Limpieza echo "Realizando limpieza de imágenes..." rm -rf "$TEMP_DIR" docker image prune -af --filter "until=24h" echo "--- DESPLIEGUE COMPLETADO CON ÉXITO ---" EOSSH