ops: keep candidate preflight isolated from production

This commit is contained in:
2026-09-05 10:22:51 -03:00
parent afde214cbb
commit 97bf39be66
+24 -9
View File
@@ -16,6 +16,7 @@ PREV_SHA=""
TARGET_SHA=""
EXPECTED_API_VERSION=""
EXPECTED_WEB_VERSION=""
APP_TOUCHED=0
cd "$APP"
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 "api_version=${EXPECTED_API_VERSION:-unknown}"
echo "web_version=${EXPECTED_WEB_VERSION:-unknown}"
echo "app_touched=$APP_TOUCHED"
echo "backup=${BACKUP:-unknown}"
} > "$status_file"
@@ -90,21 +92,32 @@ rollback() {
echo "============================================================"
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
docker compose build 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
echo
echo "Estado tras rollback:"
echo "Estado actual:"
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 "Últimos logs:"
docker compose logs --tail=160 api web </dev/null || true
echo
echo "Backup PRE disponible en: $BACKUP"
echo "Las migraciones son forward-only; database-before.dump queda disponible para restauración manual si hiciera falta."
if [ -d "$BACKUP" ]; then
echo "Backup PRE disponible en: $BACKUP"
echo "Las migraciones son forward-only; database-before.dump queda disponible para restauración manual si hiciera falta."
else
echo "No fue necesario crear backup PRE: el fallo ocurrió durante el preflight del candidato, antes de tocar producción."
fi
exit "$rc"
}
trap rollback ERR
@@ -119,8 +132,9 @@ for cmd in git docker curl tar node; do
done
[ -f "$KEY" ] || { echo "ERROR: falta deploy key $KEY"; 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
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
PHASE="candidate-preflight"
mkdir -p "$STAGE"
rm -rf "$STAGE"
git worktree add --detach "$STAGE" "$TARGET_SHA" >/dev/null
EXPECTED_API_VERSION="$(node -p "require('$STAGE/api-v3/package.json').version")"
@@ -204,6 +218,7 @@ PHASE="fast-forward"
echo
echo "========== FAST-FORWARD =========="
git log --oneline --no-decorate "$PREV_SHA..$TARGET_SHA"
APP_TOUCHED=1
git merge --ff-only "origin/$DEPLOY_REF"
PHASE="build"