#!/bin/bash
# Pear Deployment Script for Hyper Wallet Desktop
#
# Usage:
# ./scripts/pear-deploy.sh --testing "commit message"
# ./scripts/pear-deploy.sh --production "commit message"
#
# Workflow:
# 1. Pre-flight checks (node_modules, critical files)
# 2. Git commit + push
# 3. Pear stage
# 4. Pear release
# 5. Restart seeder in tmux (NOT background)
# 6. Verify seeder started
# 7. Update deployment history
#
# Note: Run tests separately before deployment: bare test/all.cjs
set -e # Exit on error
# ============================================================================
# CONFIGURATION
# ============================================================================
PROJECT_DIR="/storage/projects/code/hypercore-kb/hyper-fleeky/hyper-wallet-desktop"
TMUX_SESSION="pear-seed"
TMUX_WINDOW="5" # hyper-wallet-desktop window
# Channel configuration
TESTING_CHANNEL="hyper-wallet-desktop-test"
TESTING_BRANCH="testing"
PRODUCTION_CHANNEL="hyper-wallet-desktop"
PRODUCTION_BRANCH="stable"
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# ============================================================================
# PARSE ARGUMENTS
# ============================================================================
MODE=""
COMMIT_MSG=""
show_usage() {
echo "Usage:"
echo " ./scripts/pear-deploy.sh --testing \"commit message\""
echo " ./scripts/pear-deploy.sh --production \"commit message\""
echo ""
echo "Options:"
echo " --testing, -t Deploy to testing channel (branch: $TESTING_BRANCH)"
echo " --production, -p Deploy to production channel (branch: $PRODUCTION_BRANCH)"
echo ""
echo "Channels:"
echo " Testing: $TESTING_CHANNEL"
echo " Production: $PRODUCTION_CHANNEL"
echo ""
echo "Note: Run tests separately before deployment with: bare test/all.cjs"
echo ""
exit 1
}
# Parse flags
while [[ $# -gt 0 ]]; do
case $1 in
--testing|-t)
MODE="testing"
shift
;;
--production|-p)
MODE="production"
shift
;;
-*)
echo -e "${RED}Unknown option: $1${NC}"
show_usage
;;
*)
COMMIT_MSG="$1"
shift
;;
esac
done
if [ -z "$MODE" ]; then
echo -e "${RED}Error: Must specify --testing or --production${NC}"
echo ""
show_usage
fi
if [ -z "$COMMIT_MSG" ]; then
echo -e "${RED}Error: Commit message required${NC}"
echo ""
show_usage
fi
# Set channel and branch based on mode
if [ "$MODE" == "testing" ]; then
CHANNEL="$TESTING_CHANNEL"
EXPECTED_BRANCH="$TESTING_BRANCH"
else
CHANNEL="$PRODUCTION_CHANNEL"
EXPECTED_BRANCH="$PRODUCTION_BRANCH"
fi
cd "$PROJECT_DIR"
# ============================================================================
# HEADER
# ============================================================================
echo ""
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${BLUE} Hyper Wallet Desktop - Pear Deployment${NC}"
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
echo " Mode: $MODE"
echo " Channel: $CHANNEL"
echo " Branch: $EXPECTED_BRANCH"
echo ""
# ============================================================================
# STEP 1: PRE-FLIGHT CHECKS
# ============================================================================
echo -e "${YELLOW}Step 1: Pre-flight Checks${NC}"
# Check we're on the correct branch
CURRENT_BRANCH=$(git branch --show-current)
if [ "$CURRENT_BRANCH" != "$EXPECTED_BRANCH" ]; then
echo -e "${RED} Error: Must be on '$EXPECTED_BRANCH' branch for $MODE deployment${NC}"
echo " Current branch: $CURRENT_BRANCH"
echo " Run: git checkout $EXPECTED_BRANCH"
exit 1
fi
echo -e " ${GREEN}✓ On correct branch: $CURRENT_BRANCH${NC}"
# Check node_modules
if [ ! -d "node_modules" ]; then
echo -e "${RED} ✗ node_modules not found!${NC}"
echo " Run: npm install"
exit 1
fi
echo -e " ${GREEN}✓ node_modules exists ($(du -sh node_modules 2>/dev/null | cut -f1))${NC}"
# Check critical files
CRITICAL_FILES=("index.cjs" "wallet-server.cjs" "pear.json" "desktop/index.html" "desktop/wallet.js")
for file in "${CRITICAL_FILES[@]}"; do
if [ ! -f "$file" ]; then
echo -e "${RED} ✗ Missing: $file${NC}"
exit 1
fi
done
echo -e " ${GREEN}✓ All critical files present${NC}"
# ============================================================================
# STEP 2: GIT COMMIT + PUSH
# ============================================================================
echo ""
echo -e "${YELLOW}Step 2: Git Commit + Push${NC}"
if [ -n "$(git status --porcelain)" ]; then
echo " Changes to commit:"
git status --short | sed 's/^/ /'
# Stage all changes
git add -A
# Commit with co-authorship
git commit -m "$(cat <<EOF
$COMMIT_MSG
Deployment: $MODE ($CHANNEL)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
EOF
)"
echo -e " ${GREEN}✓ Committed${NC}"
else
echo -e " ${GREEN}✓ No uncommitted changes${NC}"
fi
# Push to remote
echo " Pushing to origin/$CURRENT_BRANCH..."
if git push origin "$CURRENT_BRANCH" 2>&1; then
echo -e " ${GREEN}✓ Pushed to remote${NC}"
else
echo -e "${YELLOW} ⚠ Push failed (continuing anyway)${NC}"
fi
# ============================================================================
# STEP 4: PEAR STAGE
# ============================================================================
echo ""
echo -e "${YELLOW}Step 3: Pear Stage${NC}"
echo " Running: pear stage $CHANNEL ."
STAGE_OUTPUT=$(pear stage "$CHANNEL" . 2>&1)
echo "$STAGE_OUTPUT" | sed 's/^/ /'
# Extract version
LATEST=$(echo "$STAGE_OUTPUT" | grep -oP 'Latest:\s+\K\d+' || echo "unknown")
echo -e " ${GREEN}✓ Staged version: $LATEST${NC}"
# ============================================================================
# STEP 5: PEAR RELEASE
# ============================================================================
echo ""
echo -e "${YELLOW}Step 4: Pear Release${NC}"
echo " Running: pear release $CHANNEL"
pear release "$CHANNEL" 2>&1 | sed 's/^/ /'
echo -e " ${GREEN}✓ Released as default${NC}"
# ============================================================================
# STEP 6: RESTART SEEDER IN TMUX
# ============================================================================
echo ""
echo -e "${YELLOW}Step 5: Restart Seeder in Tmux${NC}"
# Check tmux session exists
if ! tmux has-session -t "$TMUX_SESSION" 2>/dev/null; then
echo -e "${RED} ✗ Tmux session '$TMUX_SESSION' not found!${NC}"
echo " Create it with: tmux new-session -d -s $TMUX_SESSION"
exit 1
fi
echo -e " ${GREEN}✓ Tmux session exists: $TMUX_SESSION${NC}"
# Check window exists
if ! tmux list-windows -t "$TMUX_SESSION" -F "#{window_index}" | grep -q "^${TMUX_WINDOW}$"; then
echo -e "${YELLOW} ⚠ Window $TMUX_WINDOW not found, creating...${NC}"
tmux new-window -t "$TMUX_SESSION:$TMUX_WINDOW" -n "hyper-wallet-desktop"
fi
echo -e " ${GREEN}✓ Tmux window exists: $TMUX_SESSION:$TMUX_WINDOW${NC}"
# Stop existing seeder
echo " Stopping existing seeder..."
tmux send-keys -t "$TMUX_SESSION:$TMUX_WINDOW" C-c 2>/dev/null || true
sleep 2
# Start new seeder
echo " Starting seeder: pear seed $CHANNEL ."
tmux send-keys -t "$TMUX_SESSION:$TMUX_WINDOW" "cd $PROJECT_DIR && pear seed $CHANNEL ." Enter
echo -e " ${GREEN}✓ Seeder command sent to $TMUX_SESSION:$TMUX_WINDOW${NC}"
# ============================================================================
# STEP 7: VERIFY SEEDER
# ============================================================================
echo ""
echo -e "${YELLOW}Step 6: Verify Seeder${NC}"
sleep 3
PANE_CONTENT=$(tmux capture-pane -t "$TMUX_SESSION:$TMUX_WINDOW" -p 2>/dev/null | tail -10)
if echo "$PANE_CONTENT" | grep -qi "seed\|swarm\|listen"; then
echo -e " ${GREEN}✓ Seeder appears to be running${NC}"
else
echo -e "${YELLOW} ⚠ Could not verify seeder started${NC}"
echo " Check manually: tmux attach -t $TMUX_SESSION"
fi
# Get pear key
PEAR_KEY=$(pear info "$CHANNEL" --json 2>/dev/null | grep -oP '"key":"pear://\K[^"]+' || echo "unknown")
# ============================================================================
# STEP 8: UPDATE DEPLOYMENT HISTORY
# ============================================================================
echo ""
echo -e "${YELLOW}Step 7: Update Deployment History${NC}"
HISTORY_FILE="$PROJECT_DIR/.claude/deployment-history.json"
mkdir -p "$(dirname "$HISTORY_FILE")"
cat > "$HISTORY_FILE" << EOF
{
"mode": "$MODE",
"channel": "$CHANNEL",
"branch": "$CURRENT_BRANCH",
"version": "$LATEST",
"pear_key": "pear://$PEAR_KEY",
"deployed_at": "$(date -Iseconds)",
"commit_message": "$COMMIT_MSG",
"tmux": "$TMUX_SESSION:$TMUX_WINDOW"
}
EOF
echo -e " ${GREEN}✓ History updated: .claude/deployment-history.json${NC}"
# ============================================================================
# SUMMARY
# ============================================================================
echo ""
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${GREEN} Deployment Complete!${NC}"
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
echo " Mode: $MODE"
echo " Channel: $CHANNEL"
echo " Branch: $CURRENT_BRANCH"
echo " Version: $LATEST"
if [ "$PEAR_KEY" != "unknown" ]; then
echo " Key: pear://$PEAR_KEY"
fi
echo " Seeder: $TMUX_SESSION:$TMUX_WINDOW"
echo ""
if [ "$MODE" == "testing" ]; then
echo -e "${YELLOW}Next Steps (Testing):${NC}"
echo " 1. Test on ashatron.local:"
echo " pear run --checkout=latest pear://$PEAR_KEY"
echo ""
echo " 2. After testing verified, deploy to production:"
echo " git checkout stable"
echo " git merge testing"
echo " ./scripts/pear-deploy.sh --production \"$COMMIT_MSG\""
else
echo -e "${YELLOW}Next Steps (Production):${NC}"
echo " 1. Verify on ashatron.local:"
echo " pear run --checkout=latest pear://$PEAR_KEY"
echo ""
echo " 2. Monitor seeder:"
echo " tmux attach -t $TMUX_SESSION"
fi
echo ""