infra: endurecer preflight de deploy

Aísla el preflight candidato de producción y evita reinicios innecesarios antes de tocar la aplicación.
This commit is contained in:
2026-09-05 10:25:44 -03:00
committed by GitHub
parent afde214cbb
commit 8e2d0dfe19
+24 -9
View File
@@ -16,6 +16,7 @@ PREV_SHA=""
TARGET_SHA="" TARGET_SHA=""
EXPECTED_API_VERSION="" EXPECTED_API_VERSION=""
EXPECTED_WEB_VERSION="" EXPECTED_WEB_VERSION=""
APP_TOUCHED=0
cd "$APP" cd "$APP"
export GIT_SSH_COMMAND="ssh -i $KEY -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new" export GIT_SSH_COMMAND="ssh -i $KEY -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new"
@@ -52,6 +53,7 @@ publish_status() {
echo "current_sha=$current" echo "current_sha=$current"
echo "api_version=${EXPECTED_API_VERSION:-unknown}" echo "api_version=${EXPECTED_API_VERSION:-unknown}"
echo "web_version=${EXPECTED_WEB_VERSION:-unknown}" echo "web_version=${EXPECTED_WEB_VERSION:-unknown}"
echo "app_touched=$APP_TOUCHED"
echo "backup=${BACKUP:-unknown}" echo "backup=${BACKUP:-unknown}"
} > "$status_file" } > "$status_file"
@@ -90,21 +92,32 @@ rollback() {
echo "============================================================" echo "============================================================"
cd "$APP" cd "$APP"
if [ -n "${PREV_SHA:-}" ]; then if [ "$APP_TOUCHED" -eq 1 ] && [ -n "${PREV_SHA:-}" ]; then
echo "Restaurando aplicación al commit previo: $PREV_SHA"
git reset --hard "$PREV_SHA" || true git reset --hard "$PREV_SHA" || true
docker compose build api web </dev/null || true docker compose build api web </dev/null || true
docker compose up -d --no-deps --force-recreate api web </dev/null || true docker compose up -d --no-deps --force-recreate api web </dev/null || true
else
echo "El candidato falló antes de modificar producción; no se reconstruye ni reinicia la aplicación activa."
fi fi
echo echo
echo "Estado tras rollback:" echo "Estado actual:"
docker compose ps -a </dev/null || true docker compose ps -a </dev/null || true
if [ "$APP_TOUCHED" -eq 1 ]; then
echo
echo "Últimos logs:"
docker compose logs --tail=160 api web </dev/null || true
fi
echo echo
echo "Últimos logs:" if [ -d "$BACKUP" ]; then
docker compose logs --tail=160 api web </dev/null || true echo "Backup PRE disponible en: $BACKUP"
echo echo "Las migraciones son forward-only; database-before.dump queda disponible para restauración manual si hiciera falta."
echo "Backup PRE disponible en: $BACKUP" else
echo "Las migraciones son forward-only; database-before.dump queda disponible para restauración manual si hiciera falta." echo "No fue necesario crear backup PRE: el fallo ocurrió durante el preflight del candidato, antes de tocar producción."
fi
exit "$rc" exit "$rc"
} }
trap rollback ERR trap rollback ERR
@@ -119,8 +132,9 @@ for cmd in git docker curl tar node; do
done done
[ -f "$KEY" ] || { echo "ERROR: falta deploy key $KEY"; false; } [ -f "$KEY" ] || { echo "ERROR: falta deploy key $KEY"; false; }
[ -d .git ] || { echo "ERROR: $APP no es repositorio Git"; false; } [ -d .git ] || { echo "ERROR: $APP no es repositorio Git"; false; }
[ -f .env ] || { echo "ERROR: falta $APP/.env"; false; }
git config --global --add safe.directory "$APP" >/dev/null 2>&1 || true git config --global --get-all safe.directory 2>/dev/null | grep -Fxq "$APP" || git config --global --add safe.directory "$APP"
if [ -n "$(git status --porcelain --untracked-files=no)" ]; then if [ -n "$(git status --porcelain --untracked-files=no)" ]; then
echo "ERROR: hay cambios locales versionados en producción." echo "ERROR: hay cambios locales versionados en producción."
@@ -148,7 +162,7 @@ if ! git merge-base --is-ancestor "$PREV_SHA" "$TARGET_SHA"; then
fi fi
PHASE="candidate-preflight" PHASE="candidate-preflight"
mkdir -p "$STAGE" rm -rf "$STAGE"
git worktree add --detach "$STAGE" "$TARGET_SHA" >/dev/null git worktree add --detach "$STAGE" "$TARGET_SHA" >/dev/null
EXPECTED_API_VERSION="$(node -p "require('$STAGE/api-v3/package.json').version")" EXPECTED_API_VERSION="$(node -p "require('$STAGE/api-v3/package.json').version")"
@@ -204,6 +218,7 @@ PHASE="fast-forward"
echo echo
echo "========== FAST-FORWARD ==========" echo "========== FAST-FORWARD =========="
git log --oneline --no-decorate "$PREV_SHA..$TARGET_SHA" git log --oneline --no-decorate "$PREV_SHA..$TARGET_SHA"
APP_TOUCHED=1
git merge --ff-only "origin/$DEPLOY_REF" git merge --ff-only "origin/$DEPLOY_REF"
PHASE="build" PHASE="build"