OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-wallet-desktop / scripts / pear-deploy.sh

338 lines · bash ref:
#!/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 ""