#!/bin/zsh set -euo pipefail ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)" REMOTE_USER="${BOSS_SERVER_USER:-ubuntu}" REMOTE_HOSTNAME="${BOSS_SERVER_HOST:-106.53.170.158}" REMOTE_HOST="${BOSS_REMOTE_HOST:-${REMOTE_USER}@${REMOTE_HOSTNAME}}" REMOTE_DIR="${BOSS_REMOTE_DIR:-/opt/boss}" SSH_OPTS="-o StrictHostKeyChecking=no" KEYCHAIN_SERVICE="${BOSS_KEYCHAIN_SERVICE:-boss-server-debug-ssh}" BUILD_MODE="${BOSS_DEPLOY_BUILD_MODE:-auto}" resolve_password() { if [[ -n "${BOSS_SERVER_PASS:-}" ]]; then printf '%s' "${BOSS_SERVER_PASS}" return 0 fi if command -v security >/dev/null 2>&1; then local keychain_pass="" keychain_pass="$(security find-generic-password -a "${REMOTE_USER}" -s "${KEYCHAIN_SERVICE}" -w 2>/dev/null || true)" if [[ -n "${keychain_pass}" ]]; then printf '%s' "${keychain_pass}" return 0 fi fi return 1 } PASSWORD="$(resolve_password || true)" if [[ -n "${PASSWORD}" ]]; then export SSHPASS="${PASSWORD}" RSYNC_RSH="sshpass -e ssh ${SSH_OPTS}" SSH_PREFIX=(sshpass -e ssh ${=SSH_OPTS}) else RSYNC_RSH="ssh ${SSH_OPTS}" SSH_PREFIX=(ssh ${=SSH_OPTS}) fi run_local_build() { BOSS_RUNTIME_ROOT="$ROOT_DIR" BOSS_STATE_FILE="$ROOT_DIR/data/boss-state.json" npm run build } use_remote_build=false build_log="$(mktemp)" cleanup() { rm -f "$build_log" } trap cleanup EXIT case "$BUILD_MODE" in local) run_local_build ;; remote) use_remote_build=true ;; auto|"") if ! run_local_build 2>&1 | tee "$build_log"; then if grep -q "ENOSPC" "$build_log"; then echo "Local build hit ENOSPC, falling back to remote build." >&2 use_remote_build=true else exit 1 fi fi ;; *) echo "Unsupported BOSS_DEPLOY_BUILD_MODE: $BUILD_MODE" >&2 exit 1 ;; esac "${SSH_PREFIX[@]}" "$REMOTE_HOST" "sudo mkdir -p $REMOTE_DIR && sudo chown -R ${REMOTE_USER}:${REMOTE_USER} $REMOTE_DIR && sudo rm -rf $REMOTE_DIR/.next" RSYNC_EXCLUDES=( --exclude ".git" --exclude "node_modules" --exclude "data/" --exclude "android/app/build" --exclude ".DS_Store" ) if [[ "$use_remote_build" == true ]]; then RSYNC_EXCLUDES+=(--exclude ".next") fi rsync -az --delete \ "${RSYNC_EXCLUDES[@]}" \ -e "$RSYNC_RSH" \ "$ROOT_DIR/" "$REMOTE_HOST:$REMOTE_DIR/" if [[ "$use_remote_build" == true ]]; then REMOTE_INSTALL_AND_BUILD_CMD="npm install && BOSS_RUNTIME_ROOT=$REMOTE_DIR BOSS_STATE_FILE=$REMOTE_DIR/data/boss-state.json npm run build && npm prune --omit=dev" else REMOTE_INSTALL_AND_BUILD_CMD="npm install --omit=dev" fi POST_SYNC_REMOTE_CMD=" sudo bash $REMOTE_DIR/scripts/bootstrap-server.sh && sudo chown -R ${REMOTE_USER}:${REMOTE_USER} $REMOTE_DIR && cd $REMOTE_DIR && $REMOTE_INSTALL_AND_BUILD_CMD && sudo systemctl restart boss-web && sudo systemctl restart caddy && sleep 2 && curl -fsS http://127.0.0.1:3000/api/health " "${SSH_PREFIX[@]}" "$REMOTE_HOST" "$POST_SYNC_REMOTE_CMD"