#!/usr/bin/env bash # deploy.sh GitOps deployment for zulip-platform-plugins # Usage: ./deploy.sh [--ct=] [--dry-run] # ./deploy.sh v1.0.0 # Deploy to all 6 CTs # ./deploy.sh main # Deploy latest (staging only!) # ./deploy.sh --ct=tanko v1.0.0 # Deploy to single CT # ./deploy.sh --dry-run v1.0.0 # Preview deployment without making changes set -euo pipefail DEPLOY_LOG="deploy.log" TAG="" SINGLE_CT="" DRY_RUN=false # Parse args for arg in "$@"; do case "$arg" in --ct=*) SINGLE_CT="${arg#--ct=}" ;; --dry-run) DRY_RUN=true ;; *) TAG="$arg" ;; esac done if [[ -z "$TAG" ]]; then echo "Usage: $0 [--ct=] [--dry-run]" exit 1 fi # Agent CT registry (must match 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" ) # Platform paths per agent type declare -A PLUGIN_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" ) # Correcting the backslash artifacts from the original file PLUGIN_PATHS["koby"]="/opt/hermes-zulip-plugin" PLUGIN_PATHS["kagentz"]="/opt/agent-zero-plugin" PLUGIN_PATHS["abiba"]="/root/.pi/agent/extensions/zulip.ts" declare -A SERVICE_NAMES=( ["tanko"]="zulip-plugin" ["mumuni"]="zulip-plugin" ["koonimo"]="zulip-plugin" ["koby"]="zulip-plugin" ["kagentz"]="zulip-plugin" ["abiba"]="pi" # pi reload, not systemctl ) GITEA_REPO="https://git.sysloggh.net/SyslogSolution/zulip-platform-plugins.git" HEALTH_PORT=9200 log() { local prefix="" [[ "$DRY_RUN" == "true" ]] && prefix="[DRY-RUN] " echo "${prefix}[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$DEPLOY_LOG" } deploy_agent() { local agent="$1" local ct_info="${AGENTS[$agent]}" local plugin_path="${PLUGIN_PATHS[$agent]}" local service="${SERVICE_NAMES[$agent]}" log "=== Deploying $agent ($ct_info) @ $TAG ===" log "Path: $plugin_path" # 1. Git pull & checkout tag if [[ "$DRY_RUN" != "true" ]]; then cd "$plugin_path" || { log "ERROR: $agent path $plugin_path not found"; return 1; } git fetch --tags origin git checkout "$TAG" else log "Skipping Git checkout (Dry Run)" fi log "$agent: checked out $TAG" # 2. Install dependencies (platform-specific) if [[ "$DRY_RUN" != "true" ]]; then case "$agent" in tanko|mumuni|koonimo|koby) pip install -r requirements.txt --quiet ;; kagentz) pip install -r requirements.txt --quiet ;; abiba) log "$agent: pi extension skipping pip install" ;; esac else log "Skipping dependency installation (Dry Run)" fi # 3. Restart service if [[ "$DRY_RUN" != "true" ]]; then case "$agent" in abiba) log "$agent: triggering /reload" ;; *) systemctl restart "$service" log "$agent: restarted $service" ;; esac else log "Skipping service restart (Dry Run)" fi # 4. Health check log "Waiting for service to stabilize..." sleep 5 if [[ "$DRY_RUN" != "true" ]]; then if curl -sf "http://localhost:$HEALTH_PORT/health" > /dev/null 2>&1; then log "OK: $agent health check passed" else log "ERROR: $agent health check failed check logs" return 1 fi else log "Skipping health check (Dry Run)" fi } # --- Main ---\ log "Deploy started target: $TAG (Dry Run: $DRY_RUN)" if [[ -n "$SINGLE_CT" ]]; then deploy_agent "$SINGLE_CT" else FAILED="" for agent in tanko mumuni koonimo koby kagentz abiba; do if ! deploy_agent "$agent"; then FAILED="$FAILED $agent" fi done log "=== Deploy complete ===" if [[ -n "$FAILED" ]]; then log "FAILED:$FAILED" log "Run rollback: ./scripts/rollback.sh " exit 1 fi log "All 6 agents deployed successfully." fi