macsync/deploy/deploy-remote.sh

224 lines
8.2 KiB
Bash
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
set -euo pipefail
# Deploy MacSync client to plum (MacBook) via rsync + SSH.
#
# Usage:
# ./deploy-remote.sh # use default SERVER_URL
# ./deploy-remote.sh http://10.0.0.11:3201 # override server URL
# ./deploy-remote.sh uninstall # uninstall from plum
# ./deploy-remote.sh frontend # re-sync webapp only (preserves TCC)
PLUM_HOST="${PLUM_HOST:-plum}"
SERVER_URL="${MAC_SYNC_SERVER_URL:-http://10.0.0.11:3201}"
STAGING_DIR="mac-sync-staging"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MAC_SYNC_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
print_step() { echo -e "${GREEN}${NC} $1"; }
print_info() { echo -e "${BLUE}${NC} $1"; }
print_warning() { echo -e "${YELLOW}${NC} $1"; }
print_error() { echo -e "${RED}${NC} $1"; }
print_success() { echo -e "${GREEN}${NC} $1"; }
KEEP_STAGING=false
for arg in "$@"; do
case "$arg" in
uninstall|frontend|--uninstall|--frontend|--skip-app) ;;
--keep-staging) KEEP_STAGING=true ;;
http://*|https://*) SERVER_URL="$arg" ;;
--*) ;;
*) SERVER_URL="$arg" ;;
esac
done
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${BLUE} MacSync — Remote Deploy to $PLUM_HOST${NC}"
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
check_plum() {
print_step "Checking SSH to $PLUM_HOST..."
if ! ssh -o ConnectTimeout=5 "$PLUM_HOST" 'echo ok' >/dev/null 2>&1; then
print_error "Cannot reach $PLUM_HOST — check SSH config"
exit 1
fi
print_success "Connected"
}
cmd_install() {
check_plum
local remote_root="$STAGING_DIR/@applications/@mac-sync"
# Sync mac-sync source
print_step "Syncing @mac-sync source to $PLUM_HOST:~/$remote_root/..."
ssh "$PLUM_HOST" "mkdir -p ~/$remote_root"
# Exclude generated + VCS + dev-tool noise. plum regenerates Swift/node deps
# as needed (Swift via `swift build` in install.sh; no node deps needed on plum).
rsync -az --delete \
--exclude '.build/' \
--exclude 'DerivedData/' \
--exclude '.swiftpm/' \
--exclude 'node_modules/' \
--exclude '.git/' \
--exclude '.github/' \
--exclude '.vscode/' \
--exclude '.idea/' \
--exclude '.DS_Store' \
--exclude '*.log' \
--exclude 'dist/' \
--exclude 'coverage/' \
--exclude '.cache/' \
--exclude '.next/' \
--exclude '.turbo/' \
--exclude '.parcel-cache/' \
--exclude '__pycache__/' \
--exclude '*.pyc' \
--exclude '.venv/' \
"$MAC_SYNC_ROOT/" \
"$PLUM_HOST:~/$remote_root/"
# Sync local Swift package dependencies (referenced via relative paths in Package.swift)
local swift_root
swift_root="$(cd "$MAC_SYNC_ROOT/../../@packages/@swift" && pwd 2>/dev/null)" || true
local tray_root
tray_root="$(cd "$MAC_SYNC_ROOT/../../@packages/@tray" && pwd 2>/dev/null)" || true
if [[ -d "${swift_root:-}" ]]; then
print_step "Syncing Swift packages..."
for pkg in "@macos/agent-core" "@macos/menu-bar" "@macos/sync-framework" "@foundations/logging" "@foundations/settings"; do
local local_pkg="$swift_root/$pkg"
[[ -d "$local_pkg" ]] || continue
local remote_pkg="$STAGING_DIR/@packages/@swift/$pkg"
ssh "$PLUM_HOST" "mkdir -p ~/$remote_pkg"
rsync -az --delete \
--exclude '.build/' --exclude '.swiftpm/' --exclude 'DerivedData/' \
--exclude 'node_modules/' --exclude '.git/' --exclude '.DS_Store' \
"$local_pkg/" "$PLUM_HOST:~/$remote_pkg/"
done
print_success "Swift packages synced"
fi
if [[ -d "${tray_root:-}" ]]; then
for pkg in "tray-resources"; do
local local_pkg="$tray_root/$pkg"
[[ -d "$local_pkg" ]] || continue
local remote_pkg="$STAGING_DIR/@packages/@tray/$pkg"
ssh "$PLUM_HOST" "mkdir -p ~/$remote_pkg"
rsync -az --delete \
--exclude '.build/' --exclude '.swiftpm/' --exclude 'DerivedData/' \
--exclude 'node_modules/' --exclude '.git/' --exclude '.DS_Store' \
"$local_pkg/" "$PLUM_HOST:~/$remote_pkg/"
done
fi
# Build webapp locally (plum may not have bun/pnpm)
local web_src="$MAC_SYNC_ROOT/web"
if [[ -d "$web_src" ]]; then
print_step "Building webapp locally..."
(cd "$web_src" && bun install --frozen-lockfile && bun run build) 2>&1
if [[ -d "$web_src/dist" ]]; then
print_step "Syncing web/dist to $PLUM_HOST..."
rsync -az --delete \
"$web_src/dist/" \
"$PLUM_HOST:~/$remote_root/web/dist/"
print_success "Webapp built and synced"
else
print_error "web/dist not produced"
exit 1
fi
fi
# Sync VERSION.json
local version_file="$MAC_SYNC_ROOT/VERSION.json"
[[ -f "$version_file" ]] && rsync -az "$version_file" "$PLUM_HOST:~/$remote_root/VERSION.json"
# Run install.sh on plum
print_step "Building and installing on $PLUM_HOST..."
ssh -t "$PLUM_HOST" "cd ~/$remote_root && chmod +x deploy/install.sh && ./deploy/install.sh '$SERVER_URL'"
# Verify
print_step "Verifying agent status..."
ssh "$PLUM_HOST" bash <<'CHECK'
sleep 2
if pgrep -x MacSyncApp >/dev/null; then
echo "Agent is running"
tail -5 ~/Library/Application\ Support/MacSync/stderr.log 2>/dev/null || true
else
echo "Agent not running — grant Full Disk Access in System Settings"
fi
CHECK
# Clean staging (unless --keep-staging)
if [[ "$KEEP_STAGING" == "true" ]]; then
print_info "Staging kept at ~/$STAGING_DIR (per --keep-staging)"
else
print_step "Cleaning staging..."
ssh "$PLUM_HOST" "rm -rf ~/$STAGING_DIR"
print_success "Staging cleaned"
fi
echo ""
print_success "Deploy complete"
print_info "Logs: ssh $PLUM_HOST 'tail -f ~/Library/Application\\ Support/MacSync/stderr.log'"
}
cmd_uninstall() {
check_plum
print_step "Uninstalling MacSync from $PLUM_HOST..."
ssh -t "$PLUM_HOST" bash <<'UNINSTALL'
set -e
PLIST="$HOME/Library/LaunchAgents/com.lilith.mac-sync.plist"
APP="$HOME/Applications/MacSync.app"
if [[ -f "$PLIST" ]]; then
launchctl unload "$PLIST" 2>/dev/null || true
rm "$PLIST"
echo "LaunchAgent removed"
fi
pkill -x MacSyncApp 2>/dev/null || true
[[ -d "$APP" ]] && rm -rf "$APP" && echo "App bundle removed"
echo "Uninstall complete"
UNINSTALL
}
cmd_frontend() {
check_plum
local web_src="$MAC_SYNC_ROOT/web"
local remote_webapp="Applications/MacSync.app/Contents/Resources/webapp"
print_step "Building webapp locally..."
(cd "$web_src" && bun install --frozen-lockfile && bun run build)
[[ -d "$web_src/dist" ]] || { print_error "web/dist not produced"; exit 1; }
print_step "Syncing to $PLUM_HOST:~/$remote_webapp/..."
rsync -az --delete "$web_src/dist/" "$PLUM_HOST:~/$remote_webapp/"
print_success "Frontend synced"
print_step "Re-signing app bundle (webapp update invalidates sealed resources)..."
ssh "$PLUM_HOST" "codesign --remove-signature ~/Applications/MacSync.app 2>/dev/null; codesign -s - --force --deep ~/Applications/MacSync.app" \
&& print_success "App re-signed (ad-hoc)" \
|| print_warning "Re-signing failed — app may not launch"
print_step "Restarting agent..."
ssh "$PLUM_HOST" "pkill -x MacSyncApp 2>/dev/null || true"
sleep 2
ssh "$PLUM_HOST" "/usr/bin/open ~/Applications/MacSync.app 2>/dev/null; sleep 3 && pgrep -x MacSyncApp >/dev/null" \
&& print_success "Agent restarted" \
|| print_warning "Agent did not restart"
echo ""
print_success "Frontend deploy complete (TCC preserved)"
}
case "${1:-}" in
uninstall) cmd_uninstall ;;
frontend) cmd_frontend ;;
*) cmd_install ;;
esac