Files
mohmdsdgandCursor e98831f0f9 feat: add npm run update for safe API deploys
Ship schema to replicas without the data repair that disables subscriptions and stalls replication.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-11-07 17:15:12 +03:30

78 lines
2.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# One-step API update.
#
# Master (deploy/replicas.env present): pull, install, ship DDL to replicas,
# generate, build, restart. Schema is applied on subscribers before the publisher
# migrates, then subscriptions are refreshed with copy_data=false.
#
# Replica (no replicas.env): pull, install, generate, build, restart.
# Does not migrate and does not touch the subscription.
#
# Never calls sync-replica-data.sh. That repair disables subscriptions and
# leaves the replication origin behind, so the apply worker dies on replay.
#
# Usage (inside the API directory, or from anywhere):
# bash deploy/update.sh # master if replicas.env exists, else replica
# bash deploy/update.sh --master
# bash deploy/update.sh --replica
# PM2_APP=superadmin-api bash deploy/update.sh
set -euo pipefail
API_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$API_DIR"
MODE="${1:-auto}"
case "$MODE" in
auto|--master|--replica) ;;
*)
echo "Usage: $0 [--master|--replica]" >&2
exit 1
;;
esac
if [[ "$MODE" == auto ]]; then
if [[ -f "$API_DIR/deploy/replicas.env" ]]; then
MODE=--master
else
MODE=--replica
fi
fi
if [[ "$MODE" == --master && ! -f "$API_DIR/deploy/replicas.env" ]]; then
echo "deploy/replicas.env is missing, so this host is not the publisher." >&2
exit 1
fi
APP="${PM2_APP:-superadmin-api}"
echo "== update $MODE app=$APP dir=$API_DIR"
git pull --ff-only
npm ci
if [[ "$MODE" == --master ]]; then
bash "$API_DIR/deploy/sync-replica-schema.sh"
fi
npx prisma generate
npm run build
restart_pm2() {
if pm2 describe "$APP" >/dev/null 2>&1; then
pm2 restart "$APP"
return
fi
local user
for user in montime ubuntu; do
if id "$user" >/dev/null 2>&1 && sudo -u "$user" pm2 describe "$APP" >/dev/null 2>&1; then
sudo -u "$user" pm2 restart "$APP"
return
fi
done
echo "pm2 process '$APP' not found. Set PM2_APP to the name from: pm2 list" >&2
pm2 list || true
exit 1
}
restart_pm2
echo "== update done ($MODE)"