Uecko_ERP/scripts/build-factuges.sh

267 lines
8.7 KiB
Bash
Raw Permalink Normal View History

2025-11-03 19:45:03 +00:00
#!/usr/bin/env bash
set -euo pipefail
2025-12-01 11:38:42 +00:00
SCRIPT_VERSION="1.2.4"
2025-11-03 19:45:03 +00:00
# =====================================================
# FACTUGES Build Script
# -----------------------------------------------------
2025-11-27 19:07:30 +00:00
# Build + Export de la API y/o WEB (por compañía)
2025-11-03 19:45:03 +00:00
# =====================================================
# Uso:
2025-11-27 19:07:30 +00:00
# ./build_factuges.sh <company> [--api|web|all] [--load]
2025-11-03 19:45:03 +00:00
#
# Ejemplos:
2025-11-27 19:07:30 +00:00
# ./build_factuges.sh acme --api --load # solo API + carga en Docker local
# ./build_factuges.sh acme --web # solo web
# ./build_factuges.sh acme # API + web (por defecto)
2025-11-03 19:45:03 +00:00
#
# Funcionalidades:
# - Detecta automáticamente el nombre, versión y puerto de la API
# - Compila la web React (Vite)
# - Copia los estáticos a out/<company>/web/dist
# - Genera imagen Docker etiquetada por compañía + versión + latest
# - Guarda la imagen .tar en out/<company>/api/
# - Carga la imagen en Docker (opcional)
# =====================================================
# --- Configuración base ---
2025-11-27 19:07:30 +00:00
COMPANY=""
2025-11-03 19:45:03 +00:00
MODE="all" # api | web | all
LOAD=false
2025-11-27 19:07:30 +00:00
# --- Validar que el primer argumento existe y no es un flag ---
if [[ $# -eq 0 || "$1" == --* ]]; then
echo "❌ ERROR: Falta el parámetro <company>"
echo "Uso: ./build_factuges.sh <company> [--api|--web|--all] [--load]"
echo "Ejemplos:"
echo " ./build_factuges.sh acme --api"
echo " ./build_factuges.sh acme --web"
exit 1
fi
COMPANY="$1"
2025-12-15 18:21:09 +00:00
SSH_USER="rodax"
SSH_HOST="vps-2.rodax-software.com"
SSH_PORT="49152"
# Override por compañía específica
if [[ "$COMPANY" == "rodax" ]]; then
SSH_USER="rodax"
SSH_HOST="factuges.rodax-software.local"
SSH_PORT="22"
fi
2025-11-03 19:45:03 +00:00
# --- Parseo de flags ---
2025-11-27 19:07:30 +00:00
shift # quitamos el <company>, ahora solo quedan flags
for arg in "$@"; do
2025-11-03 19:45:03 +00:00
case "$arg" in
--api) MODE="api" ;;
--web) MODE="web" ;;
--all) MODE="all" ;;
--load) LOAD=true ;;
*) echo "⚠️ Argumento desconocido: $arg" ;;
esac
done
# --- Paths base ---
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(realpath "${SCRIPT_DIR}/..")"
SERVER_DIR="${PROJECT_DIR}/apps/server"
WEB_DIR="${PROJECT_DIR}/apps/web"
OUT_API_DIR="${PROJECT_DIR}/out/${COMPANY}/api"
OUT_WEB_DIR="${PROJECT_DIR}/out/${COMPANY}/web"
if [[ -z "$COMPANY" ]]; then
2025-11-27 19:07:30 +00:00
echo "❌ Error: debes indicar la compañía. Ejemplo: ./build_factuges.sh acme [--api|--web|--all] [--load]"
exit 1
fi
if [[ $COMPANY =~ --.* ]]; then
echo "❌ Error: debes indicar la compañía. Ejemplo: ./build_factuges.sh acme [--api|--web|--all] [--load]"
2025-11-03 19:45:03 +00:00
exit 1
fi
# --- Verificaciones mínimas ---
[[ -d "$SERVER_DIR" ]] || { echo "❌ Falta ${SERVER_DIR}"; exit 1; }
[[ -d "$WEB_DIR" ]] || { echo "❌ Falta ${WEB_DIR}"; exit 1; }
# --- Detectar nombre y versión de la API ---
IMAGE_NAME=$(node -p "require('${SERVER_DIR}/package.json').name.replace(/^@.*\\//, '')" 2>/dev/null || echo "api")
API_VERSION=$(node -p "require('${SERVER_DIR}/package.json').version" 2>/dev/null || echo "0.0.0")
# --- Detectar versión de la web ---
WEB_VERSION=$(node -p "require('${WEB_DIR}/package.json').version" 2>/dev/null || echo "0.0.0")
# --- Detectar puerto ---
PORT=""
if [[ -f "${SERVER_DIR}/.env" ]]; then
PORT=$(grep -E '^PORT=' "${SERVER_DIR}/.env" | cut -d'=' -f2 | tr -d '"')
fi
if [[ -z "$PORT" && -f "${PROJECT_DIR}/Dockerfile" ]]; then
PORT=$(grep -E '^EXPOSE ' "${PROJECT_DIR}/Dockerfile" | awk '{print $2}' | head -n1)
fi
PORT="${PORT:-3002}" # valor por defecto
# --- 3. Etiquetas e información ---
DATE=$(date +'%Y%m%d-%H%M%S')
ISO_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
USER_NAME=$(whoami)
GIT_HASH=$(git -C "$PROJECT_DIR" rev-parse --short HEAD 2>/dev/null || echo "unknown")
GIT_BRANCH=$(git -C "$PROJECT_DIR" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
IMAGE_TAG_V="${IMAGE_NAME}:${COMPANY}-v${API_VERSION}"
IMAGE_TAG_LATEST="${IMAGE_NAME}:${COMPANY}-latest"
mkdir -p "$OUT_API_DIR" "$OUT_WEB_DIR"
rm -rf "${OUT_API_DIR:?}/"*
rm -rf "${OUT_WEB_DIR:?}/"*
echo ""
echo "-------------------------------------------------------"
echo " FACTUGES Build Script v${SCRIPT_VERSION}"
echo " Construyendo entorno para compañía '${COMPANY}'"
echo " Proyecto: ${IMAGE_NAME}"
echo " Versión API: ${API_VERSION}"
echo " Versión Web: ${WEB_VERSION}"
echo " Puerto API: ${PORT}"
echo " Etiquetas: ${IMAGE_TAG_V}, ${IMAGE_TAG_LATEST}"
echo " API out: ${OUT_API_DIR}"
echo " WEB out: ${OUT_WEB_DIR}"
echo " Modo: ${MODE}"
echo " Cargar: ${LOAD}"
echo "-------------------------------------------------------"
# =====================================================
# 1⃣ WEB
# =====================================================
if [[ "$MODE" == "web" || "$MODE" == "all" ]]; then
echo "🌐 Compilando web con Vite..."
cd "${WEB_DIR}"
# Puedes pasar variables específicas por compañía
# Ejemplo: VITE_COMPANY=acme VITE_API_BASE=https://acme.localhost/api
2025-11-27 19:07:30 +00:00
VITE_COMPANY="${COMPANY}" pnpm build:${COMPANY}
2025-11-03 19:45:03 +00:00
# Carpeta versionada
VERSION_DIR="${OUT_WEB_DIR}/versions/v${WEB_VERSION}-${DATE}"
mkdir -p "${VERSION_DIR}/dist"
rm -rf "${VERSION_DIR}/dist"/*
cp -r "${WEB_DIR}/dist/"* "${VERSION_DIR}/dist/"
# Enlace simbólico 'latest' → versión recién compilada
ln -sfn "${VERSION_DIR}" "${OUT_WEB_DIR}/latest"
# Manifest JSON de la web
cat > "${VERSION_DIR}/manifest.json" <<EOF
{
"type": "web",
"company": "${COMPANY}",
"version": "${WEB_VERSION}",
"buildTime": "${ISO_DATE}",
"user": "${USER_NAME}",
"git": {
"branch": "${GIT_BRANCH}",
"commit": "${GIT_HASH}"
},
"source": "${PROJECT_DIR}/apps/web",
"dist": "${VERSION_DIR}/dist"
}
EOF
echo "✅ Web v${WEB_VERSION} compilada y copiada a ${VERSION_DIR}"
echo " 🔗 Enlace 'latest' actualizado a ${OUT_WEB_DIR}/latest"
fi
# =====================================================
# 2⃣ API
# =====================================================
if [[ "$MODE" == "api" || "$MODE" == "all" ]]; then
2025-11-27 19:07:30 +00:00
# Recopilar plantillas
2025-12-01 11:38:42 +00:00
${SCRIPT_DIR}/build-templates.sh ${COMPANY}
TEMPLATES_DIR="${PROJECT_DIR}/out/${COMPANY}/templates"
2025-11-27 19:07:30 +00:00
2025-11-03 19:45:03 +00:00
cd "${PROJECT_DIR}"
echo "🐳 Construyendo imagen Docker..."
2025-12-01 11:38:42 +00:00
#docker build --no-cache --debug -t "${IMAGE_TAG_V}" -t "${IMAGE_TAG_LATEST}" \
docker build \
-t "${IMAGE_TAG_V}" -t "${IMAGE_TAG_LATEST}" \
2025-11-27 19:07:30 +00:00
--build-arg PORT="${PORT}" --build-arg COMPANY="${COMPANY}" \
2025-11-03 19:45:03 +00:00
-f "${PROJECT_DIR}/Dockerfile" "${PROJECT_DIR}"
echo "✅ Imagen Docker construida correctamente"
TAR_FILE_V="${OUT_API_DIR}/${IMAGE_NAME}-${COMPANY}-v${API_VERSION}-${DATE}.tar"
TAR_FILE_LATEST="${OUT_API_DIR}/${IMAGE_NAME}-${COMPANY}-latest.tar"
docker save "${IMAGE_TAG_V}" "${IMAGE_TAG_LATEST}" -o "${TAR_FILE_V}"
cp -f "${TAR_FILE_V}" "${TAR_FILE_LATEST}"
echo "📦 Imagen guardada:"
echo " ${TAR_FILE_V}"
echo " ${TAR_FILE_LATEST}"
# Manifest JSON de la API
cat > "${OUT_API_DIR}/${IMAGE_NAME}-${COMPANY}-v${API_VERSION}-${DATE}-manifest.json" <<EOF
{
"type": "api",
"company": "${COMPANY}",
"image": "${IMAGE_TAG_V}",
"version": "${API_VERSION}",
"buildTime": "${ISO_DATE}",
"user": "${USER_NAME}",
"git": {
"branch": "${GIT_BRANCH}",
"commit": "${GIT_HASH}"
},
"port": "${PORT}",
"files": {
2025-12-01 11:38:42 +00:00
"versioned": "$(basename ${TAR_FILE_V})",
"latest": "$(basename ${TAR_FILE_LATEST})"
2025-11-03 19:45:03 +00:00
}
}
EOF
echo "📦 API manifest generado en ${OUT_API_DIR}/manifest-v${API_VERSION}-${DATE}.json"
2025-11-28 15:00:18 +00:00
fi
2025-11-03 19:45:03 +00:00
2025-12-15 18:21:09 +00:00
2025-11-28 15:00:18 +00:00
if [[ "$LOAD" == true ]]; then
2025-12-15 18:21:09 +00:00
echo "📥 Cargando imagen en producción ${SSH_HOST}..."
[[ "$MODE" == "web" || "$MODE" == "all" ]] && scp -r -P "${SSH_PORT}" "${OUT_WEB_DIR}" "${SSH_USER}@${SSH_HOST}:/opt/factuges/${COMPANY}/"
[[ "$MODE" == "api" || "$MODE" == "all" ]] && scp -r -P "${SSH_PORT}" "${OUT_API_DIR}" "${SSH_USER}@${SSH_HOST}:/opt/factuges/${COMPANY}/"
[[ "$MODE" == "api" || "$MODE" == "all" ]] && scp -r -P "${SSH_PORT}" "${TEMPLATES_DIR}" "${SSH_USER}@${SSH_HOST}:/opt/factuges/${COMPANY}/"
if [[ "$MODE" == "api" || "$MODE" == "all" ]]; then
RESULT=$(ssh -p "${SSH_PORT}" "${SSH_USER}@${SSH_HOST}" \
"docker load -i /opt/factuges/${COMPANY}/api/$(basename "${TAR_FILE_LATEST}")")
echo "${RESULT}"
fi
2025-11-28 15:00:18 +00:00
echo "✅ Imagen cargada en producción"
2025-11-03 19:45:03 +00:00
fi
2025-11-28 15:00:18 +00:00
2025-12-15 18:21:09 +00:00
2025-11-03 19:45:03 +00:00
# =====================================================
# 3⃣ Resumen
# =====================================================
echo "-------------------------------------------------------"
echo "🎯 Resultado final para '${COMPANY}'"
[[ "$MODE" == "web" || "$MODE" == "all" ]] && echo " 🌐 Web: v${WEB_VERSION}${OUT_WEB_DIR}/versions/v${WEB_VERSION}-${DATE}"
[[ "$MODE" == "api" || "$MODE" == "all" ]] && echo " 🐳 API: v${API_VERSION}${OUT_API_DIR}"
echo "🧩 Script version: ${SCRIPT_VERSION} - FIN"
echo "-------------------------------------------------------"
echo ""
echo ""
echo ""