#!/usr/bin/env bash # Deploy Salary Benchmark to optical-dev.oliver.solutions under /salary-benchmark/. # Idempotent: safe to re-run for updates. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" # shellcheck disable=SC1091 if [[ ! -f "${SCRIPT_DIR}/config.sh" ]]; then echo "ERROR: ${SCRIPT_DIR}/config.sh not found. Copy config.sh.example to config.sh and edit." >&2 exit 1 fi source "${SCRIPT_DIR}/config.sh" : "${SSH_TARGET:?SSH_TARGET must be set in config.sh}" : "${REMOTE_APP_DIR:?REMOTE_APP_DIR must be set in config.sh}" : "${REMOTE_WEB_DIR:?REMOTE_WEB_DIR must be set in config.sh}" : "${REMOTE_VHOST_FILE:?REMOTE_VHOST_FILE must be set in config.sh}" : "${URL_SUBPATH:?URL_SUBPATH must be set in config.sh}" : "${PORT_SCAN_START:=8100}" : "${PORT_SCAN_END:=8199}" step() { printf "\n\033[1;33m==> %s\033[0m\n" "$*"; } info() { printf " %s\n" "$*"; } die() { printf "\033[1;31mERROR: %s\033[0m\n" "$*" >&2; exit 1; } # ---------------------------------------------------------------------------- step "Pre-flight checks" command -v rsync >/dev/null || die "rsync not installed locally" command -v ssh >/dev/null || die "ssh not installed locally" command -v npm >/dev/null || die "npm not installed locally" ssh -o BatchMode=yes -o ConnectTimeout=5 "${SSH_TARGET}" true \ || die "cannot ssh to ${SSH_TARGET}" info "SSH to ${SSH_TARGET} ok" # ---------------------------------------------------------------------------- step "Pick a free backend port on remote (range ${PORT_SCAN_START}-${PORT_SCAN_END})" APP_PORT=$(ssh "${SSH_TARGET}" bash -s </dev/null | awk '{print \$4}' | awk -F: '{print \$NF}' | sort -u) for p in \$(seq ${PORT_SCAN_START} ${PORT_SCAN_END}); do if ! grep -qx "\$p" <<<"\$used"; then echo "\$p"; exit 0; fi done exit 1 EOF ) [[ -n "${APP_PORT}" ]] || die "no free port in range ${PORT_SCAN_START}-${PORT_SCAN_END}" info "Selected APP_PORT=${APP_PORT}" # ---------------------------------------------------------------------------- step "Build frontend with VITE_BASE=${URL_SUBPATH}" pushd "${REPO_ROOT}/frontend" >/dev/null npm ci --prefer-offline --no-audit --no-fund VITE_BASE="${URL_SUBPATH}" npm run build popd >/dev/null info "Built: ${REPO_ROOT}/frontend/dist/" # ---------------------------------------------------------------------------- step "Prepare remote directories" ssh "${SSH_TARGET}" bash -s </dev/null | head -1 | cut -d= -f2- || true; } SERPER_API_KEY="${SERPER_API_KEY:-$(get_local SERPER_API_KEY)}" FIRECRAWL_API_KEY="${FIRECRAWL_API_KEY:-$(get_local FIRECRAWL_API_KEY)}" COHERE_API_KEY="${COHERE_API_KEY:-$(get_local COHERE_API_KEY)}" ANTHROPIC_API_KEY="${ANTHROPIC_API_KEY:-$(get_local ANTHROPIC_API_KEY)}" ssh "${SSH_TARGET}" bash -s <