265 lines
7.9 KiB
Bash
Executable file
265 lines
7.9 KiB
Bash
Executable file
#!/bin/bash
|
|
#
|
|
# Deploy ImageAssistant to plum (macOS)
|
|
#
|
|
# Usage:
|
|
# ./deploy.sh # Deploy and install
|
|
# ./deploy.sh --sync-only # Just sync files, don't install
|
|
# ./deploy.sh --build-only # Sync and build, don't install
|
|
# ./deploy.sh --status # Check status on plum
|
|
# ./deploy.sh --logs # Tail logs on plum
|
|
# ./deploy.sh --stop # Stop the agent on plum
|
|
#
|
|
# Configuration: deploy.yaml
|
|
#
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
CONFIG_FILE="$SCRIPT_DIR/deploy.yaml"
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
log_info() { echo -e "${BLUE}▸${NC} $1"; }
|
|
log_success() { echo -e "${GREEN}✓${NC} $1"; }
|
|
log_warn() { echo -e "${YELLOW}⚠${NC} $1"; }
|
|
log_error() { echo -e "${RED}✗${NC} $1"; }
|
|
|
|
# Read config from deploy.yaml
|
|
read_config() {
|
|
if [[ ! -f "$CONFIG_FILE" ]]; then
|
|
log_error "Config file not found: $CONFIG_FILE"
|
|
exit 1
|
|
fi
|
|
|
|
# Parse YAML (simple key: value format)
|
|
PLUM_HOST=$(grep '^host:' "$CONFIG_FILE" | sed 's/^host:[[:space:]]*//' | tr -d '"')
|
|
REMOTE_DIR=$(grep '^remote_dir:' "$CONFIG_FILE" | sed 's/^remote_dir:[[:space:]]*//' | tr -d '"')
|
|
BACKEND_URL=$(grep '^backend_url:' "$CONFIG_FILE" | sed 's/^backend_url:[[:space:]]*//' | tr -d '"')
|
|
|
|
# Defaults
|
|
PLUM_HOST="${PLUM_HOST:-plum-eth}"
|
|
REMOTE_DIR="${REMOTE_DIR:-~/Code/@projects/@lilith/lilith-platform/codebase/features/image-assistant/macos}"
|
|
BACKEND_URL="${BACKEND_URL:-http://10.0.0.116:3150}"
|
|
}
|
|
|
|
check_plum_reachable() {
|
|
log_info "Checking connection to $PLUM_HOST..."
|
|
if ! ssh -o ConnectTimeout=5 "$PLUM_HOST" "echo ok" &>/dev/null; then
|
|
log_error "Cannot reach plum at $PLUM_HOST"
|
|
echo " Check deploy.yaml 'host' setting and SSH config"
|
|
exit 1
|
|
fi
|
|
log_success "Connected to $PLUM_HOST"
|
|
}
|
|
|
|
build_frontend_locally() {
|
|
local frontend_dir="$SCRIPT_DIR/../frontend-macos-client"
|
|
|
|
if [[ ! -d "$frontend_dir" ]]; then
|
|
log_warn "Frontend directory not found at $frontend_dir - skipping frontend build"
|
|
return 0
|
|
fi
|
|
|
|
log_info "Building frontend locally (to avoid requiring Node.js on plum)..."
|
|
|
|
cd "$frontend_dir"
|
|
|
|
# Check if pnpm is available
|
|
if ! command -v pnpm &>/dev/null; then
|
|
log_error "pnpm not found. Install with: npm install -g pnpm"
|
|
return 1
|
|
fi
|
|
|
|
# Install dependencies if needed
|
|
if [[ ! -d "node_modules" ]]; then
|
|
log_info "Installing frontend dependencies..."
|
|
pnpm install --frozen-lockfile || {
|
|
log_error "Frontend dependency installation failed"
|
|
return 1
|
|
}
|
|
fi
|
|
|
|
# Build
|
|
log_info "Building React app..."
|
|
pnpm build || {
|
|
log_error "Frontend build failed"
|
|
return 1
|
|
}
|
|
|
|
log_success "Frontend built at $frontend_dir/dist"
|
|
|
|
cd "$SCRIPT_DIR"
|
|
}
|
|
|
|
sync_files() {
|
|
log_info "Syncing files to $PLUM_HOST:$REMOTE_DIR..."
|
|
|
|
# Ensure remote directories exist
|
|
ssh "$PLUM_HOST" "mkdir -p $REMOTE_DIR"
|
|
ssh "$PLUM_HOST" "mkdir -p $(dirname $REMOTE_DIR)/frontend-macos-client"
|
|
|
|
# Sync macos directory (exclude build artifacts)
|
|
log_info "Syncing macos directory..."
|
|
rsync -avz --delete \
|
|
--exclude '.build/' \
|
|
--exclude 'DerivedData/' \
|
|
--exclude '.swiftpm/' \
|
|
--exclude '*.xcodeproj' \
|
|
--exclude '*.xcworkspace' \
|
|
"$SCRIPT_DIR/" \
|
|
"$PLUM_HOST:$REMOTE_DIR/"
|
|
|
|
# Sync frontend-macos-client directory (exclude node_modules, include pre-built dist)
|
|
local frontend_dir="$SCRIPT_DIR/../frontend-macos-client"
|
|
if [[ -d "$frontend_dir" ]]; then
|
|
log_info "Syncing frontend-macos-client directory..."
|
|
rsync -avz --delete \
|
|
--exclude 'node_modules/' \
|
|
--exclude '.turbo/' \
|
|
--exclude '.vite/' \
|
|
"$frontend_dir/" \
|
|
"$PLUM_HOST:$(dirname $REMOTE_DIR)/frontend-macos-client/"
|
|
|
|
# Verify dist was synced
|
|
if [[ -d "$frontend_dir/dist" ]]; then
|
|
log_success "Frontend build (dist/) included in sync"
|
|
else
|
|
log_warn "No frontend build found - run: cd $frontend_dir && pnpm build"
|
|
fi
|
|
else
|
|
log_warn "Frontend directory not found at $frontend_dir - skipping"
|
|
fi
|
|
|
|
log_success "Files synced"
|
|
}
|
|
|
|
build_on_plum() {
|
|
log_info "Building on $PLUM_HOST..."
|
|
ssh "$PLUM_HOST" "cd $REMOTE_DIR && swift build -c release"
|
|
log_success "Build complete"
|
|
}
|
|
|
|
install_on_plum() {
|
|
log_info "Installing on $PLUM_HOST (backend: $BACKEND_URL)..."
|
|
ssh -t "$PLUM_HOST" "cd $REMOTE_DIR && ./install.sh '$BACKEND_URL'"
|
|
log_success "Install complete"
|
|
}
|
|
|
|
show_status() {
|
|
log_info "Status on $PLUM_HOST:"
|
|
ssh "$PLUM_HOST" "~/Applications/ImageAssistant.app/Contents/MacOS/ImageAssistant --status" || true
|
|
}
|
|
|
|
show_logs() {
|
|
log_info "Tailing logs on $PLUM_HOST (Ctrl+C to stop)..."
|
|
ssh "$PLUM_HOST" "tail -f ~/Library/Application\ Support/ImageAssistant/stderr.log"
|
|
}
|
|
|
|
stop_agent() {
|
|
log_info "Stopping agent on $PLUM_HOST..."
|
|
ssh "$PLUM_HOST" "launchctl unload ~/Library/LaunchAgents/com.lilith.image-assistant.plist 2>/dev/null; pkill -x ImageAssistant 2>/dev/null" || true
|
|
log_success "Agent stopped"
|
|
}
|
|
|
|
run_cli() {
|
|
shift # Remove --cli
|
|
log_info "Running CLI on $PLUM_HOST..."
|
|
ssh "$PLUM_HOST" "~/Applications/ImageAssistant.app/Contents/MacOS/ImageAssistant $*"
|
|
}
|
|
|
|
show_config() {
|
|
echo "Configuration (from deploy.yaml):"
|
|
echo " host: $PLUM_HOST"
|
|
echo " remote_dir: $REMOTE_DIR"
|
|
echo " backend_url: $BACKEND_URL"
|
|
}
|
|
|
|
print_help() {
|
|
echo "Deploy ImageAssistant to plum (macOS)"
|
|
echo ""
|
|
echo "Usage: ./deploy.sh [OPTION]"
|
|
echo ""
|
|
echo "Options:"
|
|
echo " (no args) Sync, build, and install"
|
|
echo " --sync-only Just sync files to plum"
|
|
echo " --build-only Sync and build, don't install"
|
|
echo " --status Show agent status on plum"
|
|
echo " --logs Tail agent logs on plum"
|
|
echo " --stop Stop the agent on plum"
|
|
echo " --cli <args> Run ImageAssistant CLI with args"
|
|
echo " --config Show current configuration"
|
|
echo " --help Show this help"
|
|
echo ""
|
|
echo "Configuration: deploy.yaml"
|
|
echo ""
|
|
echo "Examples:"
|
|
echo " ./deploy.sh # Full deploy"
|
|
echo " ./deploy.sh --status # Check status"
|
|
echo " ./deploy.sh --cli --check-photos # Check Photos permission"
|
|
echo " ./deploy.sh --cli --request-photos # Request Photos permission"
|
|
echo " ./deploy.sh --cli --reset-sync # Reset sync state"
|
|
}
|
|
|
|
main() {
|
|
read_config
|
|
|
|
case "${1:-}" in
|
|
--help|-h)
|
|
print_help
|
|
;;
|
|
--config)
|
|
show_config
|
|
;;
|
|
--sync-only)
|
|
check_plum_reachable
|
|
sync_files
|
|
;;
|
|
--build-only)
|
|
build_frontend_locally
|
|
check_plum_reachable
|
|
sync_files
|
|
build_on_plum
|
|
;;
|
|
--status)
|
|
check_plum_reachable
|
|
show_status
|
|
;;
|
|
--logs)
|
|
check_plum_reachable
|
|
show_logs
|
|
;;
|
|
--stop)
|
|
check_plum_reachable
|
|
stop_agent
|
|
;;
|
|
--cli)
|
|
check_plum_reachable
|
|
run_cli "$@"
|
|
;;
|
|
"")
|
|
# Full deploy
|
|
build_frontend_locally
|
|
check_plum_reachable
|
|
sync_files
|
|
install_on_plum
|
|
echo ""
|
|
log_success "Deployment complete!"
|
|
echo " Dashboard: http://localhost:8766 (on plum)"
|
|
echo " Status: ./deploy.sh --status"
|
|
echo " Logs: ./deploy.sh --logs"
|
|
;;
|
|
*)
|
|
log_error "Unknown option: $1"
|
|
echo "Run './deploy.sh --help' for usage"
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
main "$@"
|