72890e37d9
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
93 lines
3.7 KiB
Bash
Executable File
93 lines
3.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Ejecuta el update real: lo dispara el backend (POST /api/updater/apply) via un proceso
|
|
# separado y detached, nunca corre inline en el request HTTP (el propio backend se reinicia
|
|
# al final).
|
|
#
|
|
# IMPORTANTE: este script se ejecuta desde una copia FUERA de source/ (normalmente
|
|
# $APP_DIR/scripts/apply-update.sh) — nunca desde dentro de source/, porque el propio script
|
|
# hace `git reset --hard` sobre source/ mientras corre. Si se ejecutara desde ahi, se
|
|
# sobreescribiria a si mismo a mitad de ejecucion (comportamiento indefinido en bash).
|
|
#
|
|
# Variables requeridas en el entorno (via EnvironmentFile del backend, ya cargadas por el
|
|
# proceso Node que invoca este script):
|
|
# APP_DIR ej. /opt/apps/project.exilaser.net
|
|
# BACKEND_SERVICE ej. project-exilaser-backend
|
|
# FRONTEND_SERVICE ej. project-exilaser-frontend
|
|
# DB_HOST / DB_USER / DB_PASSWORD / DB_NAME (ya vienen del .env del backend)
|
|
set -euo pipefail
|
|
|
|
: "${APP_DIR:?falta APP_DIR}"
|
|
: "${BACKEND_SERVICE:?falta BACKEND_SERVICE}"
|
|
: "${FRONTEND_SERVICE:?falta FRONTEND_SERVICE}"
|
|
: "${TARGET_VERSION:?falta TARGET_VERSION}"
|
|
|
|
LOG="$APP_DIR/logs/update.log"
|
|
mkdir -p "$APP_DIR/logs" "$APP_DIR/backups"
|
|
exec >>"$LOG" 2>&1
|
|
|
|
PHASE=backup
|
|
write_status() {
|
|
printf '%s|%s|%s\n' "$1" "$PHASE" "$TARGET_VERSION" > "$APP_DIR/logs/update.status.tmp"
|
|
mv "$APP_DIR/logs/update.status.tmp" "$APP_DIR/logs/update.status"
|
|
}
|
|
trap 'write_status failed' ERR
|
|
write_status running
|
|
|
|
echo ""
|
|
echo "=== update start $(date -Iseconds) ==="
|
|
|
|
echo "-- backup de base de datos --"
|
|
mysqldump --single-transaction -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASSWORD" "$DB_NAME" \
|
|
> "$APP_DIR/backups/pre_update_$(date +%Y%m%d_%H%M%S).sql"
|
|
|
|
echo "-- git fetch + reset --"
|
|
PHASE=source
|
|
write_status running
|
|
cd "$APP_DIR/source"
|
|
git fetch origin main
|
|
git reset --hard origin/main
|
|
NEW_VERSION="$(cat VERSION)"
|
|
echo "version objetivo: $NEW_VERSION"
|
|
[[ "$NEW_VERSION" == "$TARGET_VERSION" ]] || { echo "version remota distinta de la solicitada: $TARGET_VERSION"; false; }
|
|
|
|
echo "-- backend: npm install + migraciones --"
|
|
PHASE=backend
|
|
write_status running
|
|
cd "$APP_DIR/source/backend"
|
|
npm install --omit=dev
|
|
node src/scripts/migrate-db.js
|
|
|
|
echo "-- frontend: npm install + build --"
|
|
PHASE=frontend
|
|
write_status running
|
|
cd "$APP_DIR/source/frontend"
|
|
# --include=dev es necesario a la fuerza: este script hereda NODE_ENV=production del backend
|
|
# (via EnvironmentFile), y con eso npm salta devDependencies por defecto -- incluido vite, que
|
|
# es la unica forma de hacer el build. Sin esto, "npm install" queda "up to date" sin instalar
|
|
# nada realmente y el build falla con "vite: not found".
|
|
npm install --include=dev
|
|
npm run build
|
|
|
|
echo "-- publicando build de frontend --"
|
|
PHASE=publish
|
|
write_status running
|
|
rm -rf "$APP_DIR/frontend/dist"
|
|
cp -r dist "$APP_DIR/frontend/dist"
|
|
|
|
echo "-- reiniciando servicios --"
|
|
PHASE=restart
|
|
write_status running
|
|
# Dos llamadas separadas a proposito: el sudoers NOPASSWD (ver DEPLOY_WEB.md) whitelistea cada
|
|
# "systemctl restart <servicio>" por separado -- un solo "systemctl restart back front" junto no
|
|
# matchea ninguna de las dos reglas, sudo pide contraseña, falla en este contexto sin terminal, y
|
|
# el restart nunca pasa (el resto del update ya corrio bien, pero los servicios quedan con el
|
|
# codigo viejo sin que nada avise del error). Bug real encontrado el 2026-09-30.
|
|
# Frontend primero y backend AL FINAL: este script corre dentro del cgroup del backend, asi que
|
|
# reiniciarlo lo mata. Por eso se marca "done" antes; el popup confirma igual que el backend nuevo
|
|
# este arriba (runningVersion) antes de recargar.
|
|
sudo systemctl restart "$FRONTEND_SERVICE"
|
|
PHASE=complete
|
|
write_status done
|
|
echo "=== update done $(date -Iseconds) -- v$NEW_VERSION (reiniciando backend) ==="
|
|
sudo systemctl restart "$BACKEND_SERVICE"
|