#!/usr/bin/env bash # deploy.sh — GitOps deployment for zulip-platform-plugins # # Supports two deployment modes: # LEGACY: /opt/hermes-zulip-plugin/ + systemctl restart zulip-plugin # NATIVE: ~/.hermes/plugins/platforms/zulip/ + hermes gateway restart # # Usage: # ./deploy.sh # Deploy all agents (default: native) # ./deploy.sh --mode=native v1.0.0 # Hermes native plugin (new) # ./deploy.sh --mode=legacy v1.0.0 # Old systemd service (deprecated) # ./deploy.sh --ct=tanko v1.0.0 # Single agent # ./deploy.sh --dry-run v1.0.0 # Preview only # set -euo pipefail DEPLOY_LOG="deploy.log" TAG="" SINGLE_CT="" DRY_RUN=false DEPLOY_MODE="native" # default to new Hermes native plugin # Parse args for arg in "$@"; do case "$arg" in --ct=*) SINGLE_CT="${arg#--ct=}" ;; --dry-run) DRY_RUN=true ;; --mode=*) DEPLOY_MODE="${arg#--mode=}" ;; *) TAG="$arg" ;; esac done if [[ -z "$TAG" ]]; then echo "Usage: $0 [--ct=] [--mode=native|legacy] [--dry-run]" echo "" echo " --ct= Deploy to single agent (tanko, mumuni, etc.)" echo " --mode=native Hermes native plugin at ~/.hermes/plugins/ (default)" echo " --mode=legacy Old systemd service at /opt/hermes-zulip-plugin/" echo " --dry-run Preview deployment without making changes" echo "" echo "Examples:" echo " ./deploy.sh v1.0.0 # Deploy native to all agents" echo " ./deploy.sh --ct=tanko v1.0.0 # Deploy native to Tanko only" echo " ./deploy.sh --mode=legacy v0.9.0 # Deploy legacy to all" exit 1 fi if [[ "$DEPLOY_MODE" != "native" && "$DEPLOY_MODE" != "legacy" ]]; then echo "ERROR: --mode must be 'native' or 'legacy'" exit 1 fi # ── Agent Registry (must match docs/CONTEXT.md) ────────────────────── declare -A AGENTS=( ["tanko"]="amdpve CT 112" ["mumuni"]="minipve CT 114" ["koonimo"]="amdpve CT 113" ["koby"]="amdpve CT 111" ["kagentz"]="amdpve CT 105" ["abiba"]="amdpve CT 100" ) # Native Hermes plugin path (~/.hermes/plugins/platforms/zulip/) NATIVE_PLUGIN_SRC="plugins/platforms/zulip" # Legacy paths (DEPRECATED — systemd zulip-plugin service) declare -A LEGACY_PATHS=( ["tanko"]="/opt/hermes-zulip-plugin" ["mumuni"]="/opt/hermes-zulip-plugin" ["koonimo"]="/opt/hermes-zulip-plugin" ["koby"]="/opt/hermes-zulip-plugin" ["kagentz"]="/opt/agent-zero-plugin" ["abiba"]="/root/.pi/agent/extensions/zulip.ts" ) # Service names for legacy mode declare -A LEGACY_SERVICES=( ["tanko"]="zulip-plugin" ["mumuni"]="zulip-plugin" ["koonimo"]="zulip-plugin" ["koby"]="zulip-plugin" ["kagentz"]="zulip-plugin" ["abiba"]="pi" ) HEALTH_PORT=9200 GITEA_REPO="https://git.sysloggh.net/SyslogSolution/zulip-platform-plugins.git" log() { local prefix="" [[ "$DRY_RUN" == "true" ]] && prefix="[DRY-RUN] " echo "${prefix}[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$DEPLOY_LOG" } # ── Deployment Functions ───────────────────────────────────────────── deploy_native() { local agent="$1" local plugin_dir="$HOME/.hermes/plugins/platforms/zulip" log "📦 Deploying $agent: native Hermes plugin -> $plugin_dir" if [[ "$DRY_RUN" == "true" ]]; then log " Would copy $NATIVE_PLUGIN_SRC/{adapter.py,__init__.py,plugin.yaml} -> $plugin_dir/" log " Would run: hermes gateway restart" return 0 fi # Create plugin directory mkdir -p "$plugin_dir" # Copy plugin files cp "$NATIVE_PLUGIN_SRC/adapter.py" "$plugin_dir/" cp "$NATIVE_PLUGIN_SRC/__init__.py" "$plugin_dir/" cp "$NATIVE_PLUGIN_SRC/plugin.yaml" "$plugin_dir/" log " Copied plugin files to $plugin_dir/" ls -la "$plugin_dir/" # Restart Hermes Gateway to load the plugin if command -v hermes &>/dev/null; then log " Restarting Hermes Gateway..." hermes gateway restart log " Hermes Gateway restarted" else log " ⚠️ 'hermes' command not found — manual restart needed" log " Run: hermes gateway restart" fi # Health check log " Waiting for service to stabilize..." sleep 5 if curl -sf "http://localhost:$HEALTH_PORT/health" > /dev/null 2>&1; then log " ✅ Health check passed (port $HEALTH_PORT)" else log " ⚠️ Health check on port $HEALTH_PORT not responding" log " Check Gateway logs for plugin load errors" fi log "✅ $agent: native deployment complete" } deploy_legacy() { local agent="$1" local plugin_path="${LEGACY_PATHS[$agent]}" local service="${LEGACY_SERVICES[$agent]}" log "📦 Deploying $agent: LEGACY mode -> $plugin_path" if [[ "$DRY_RUN" == "true" ]]; then log " Would git checkout $TAG in $plugin_path" log " Would install deps + restart $service" return 0 fi # Git checkout if [[ ! -d "$plugin_path" ]]; then log "❌ Path $plugin_path not found for $agent" return 1 fi cd "$plugin_path" git fetch --tags origin git checkout "$TAG" log " Checked out $TAG in $plugin_path" # Install deps if [[ -f "requirements.txt" ]]; then pip install -r requirements.txt --quiet log " Dependencies installed" fi # Restart service if systemctl list-units --full -all 2>/dev/null | grep -q "$service"; then systemctl restart "$service" log " Restarted $service" else log " ⚠️ Service $service not found — manual restart needed" fi # Health check sleep 5 if curl -sf "http://localhost:$HEALTH_PORT/health" > /dev/null 2>&1; then log " ✅ Health check passed" else log " ⚠️ Health check failed — check logs" fi log "✅ $agent: legacy deployment complete" } # ── Verify function ────────────────────────────────────────────────── verify_deployment() { local agent="$1" log "🔍 Verifying $agent deployment..." if [[ "$DEPLOY_MODE" == "native" ]]; then local plugin_dir="$HOME/.hermes/plugins/platforms/zulip" if [[ -f "$plugin_dir/adapter.py" && -f "$plugin_dir/plugin.yaml" ]]; then log " ✅ Plugin files present in $plugin_dir" log " adapter.py: $(wc -l < "$plugin_dir/adapter.py") lines" log " plugin.yaml: $(wc -l < "$plugin_dir/plugin.yaml") lines" else log " ❌ Plugin files missing in $plugin_dir" return 1 fi fi log " ✅ $agent verification complete" } # ── Main ───────────────────────────────────────────────────────────── log "🚀 Deploy started — tag: $TAG, mode: $DEPLOY_MODE, dry-run: $DRY_RUN" if [[ -n "$SINGLE_CT" ]]; then if [[ -z "${AGENTS[$SINGLE_CT]:-}" ]]; then log "❌ Unknown agent: $SINGLE_CT" log " Known agents: ${!AGENTS[*]}" exit 1 fi log "--- Deploying single agent: $SINGLE_CT ---" if [[ "$DEPLOY_MODE" == "native" ]]; then deploy_native "$SINGLE_CT" else deploy_legacy "$SINGLE_CT" fi verify_deployment "$SINGLE_CT" else FAILED="" for agent in "${!AGENTS[@]}"; do echo "" if [[ "$DEPLOY_MODE" == "native" ]]; then if deploy_native "$agent"; then verify_deployment "$agent" || FAILED="$FAILED $agent" else FAILED="$FAILED $agent" fi else if deploy_legacy "$agent"; then verify_deployment "$agent" || FAILED="$FAILED $agent" else FAILED="$FAILED $agent" fi fi done echo "" log "=== Deploy complete ===" if [[ -n "$FAILED" ]]; then log "❌ FAILED:$FAILED" log " Run rollback: ./scripts/rollback.sh " exit 1 fi log "✅ All agents deployed successfully." log " Next: monitor #agent-hub for agent responses" fi