# Staggered Deployment Pipeline # # Release flow: # v*.*.*-rc.* → Tanko only (canary) e.g. v1.1.0-rc.1 # az-v*.*.* → kagentz only (A2A track) e.g. az-v1.0.0 # v*.*.* → all Hermes agents e.g. v1.1.0 # # Pi agents (Abiba) use a separate update mechanism. name: Deploy on: push: tags: - v*.*.* # Stable Hermes release → all agents - v*.*.*-rc.* # Release candidate → Tanko only - az-v*.*.* # Agent Zero release → kagentz only jobs: validate: runs-on: ubuntu-latest steps: - name: Checkout run: git clone --depth 1 http://192.168.68.17:3000/SyslogSolution/zulip-platform-plugins.git . - name: Python syntax run: | python3 -m py_compile plugins/platforms/zulip/adapter.py 2>/dev/null python3 -m py_compile agent-zero-zulip/src/agent_zero_zulip/adapter.py 2>/dev/null || true - name: Deploy script run: bash -n scripts/deploy.sh 2>/dev/null || true # ── Track 1: Tanko (Hermes canary) ───────────────────── deploy-tanko: if: startsWith(github.ref, 'refs/tags/v') runs-on: ubuntu-latest needs: [validate] environment: canary steps: - name: Checkout run: git clone --depth 1 http://192.168.68.17:3000/SyslogSolution/zulip-platform-plugins.git . - name: Deploy to Tanko env: TAG: ${{ github.ref_name }} run: | echo "🧪 Canary deploy $TAG → Tanko (CT 112)" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 jerome@192.168.68.122 \ "cd /root && bash -s" < scripts/deploy.sh --ct=tanko --mode=native "$TAG" 2>&1 - name: Canary health check run: | echo "⏳ Waiting 60s for canary to settle..." sleep 60 STATE=$(ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 jerome@192.168.68.122 \ "cat ~/.hermes/gateway_state.json 2>/dev/null" 2>/dev/null || echo '{}') ZULIP_STATE=$(echo $STATE | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('platforms',{}).get('zulip',{}).get('state','unknown'))" 2>/dev/null) echo "Tanko Zulip state: $ZULIP_STATE" if [ "$ZULIP_STATE" != "connected" ]; then echo "⚠️ Canary health check failed — promoting anyway (non-blocking)" fi # ── Track 2: Hermes agents (after canary passes) ────── deploy-hermes: if: startsWith(github.ref, 'refs/tags/v') && !startsWith(github.ref, 'refs/tags/v*.*.*-rc') && !startsWith(github.ref, 'refs/tags/az-') runs-on: ubuntu-latest needs: [deploy-tanko] environment: production steps: - name: Checkout run: git clone --depth 1 http://192.168.68.17:3000/SyslogSolution/zulip-platform-plugins.git . - name: Deploy to all Hermes agents env: TAG: ${{ github.ref_name }} run: | echo "🚀 Promoting $TAG to Hermes agents" # Mumuni echo "--- Mumuni (CT 114) ---" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 root@192.168.68.123 \ "cd /root && bash -s" < scripts/deploy.sh --ct=mumuni --mode=native "$TAG" 2>&1 - name: Production health check run: | sleep 30 for agent in "jerome@192.168.68.122" "root@192.168.68.123"; do STATE=$(ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 $agent \ "cat ~/.hermes/gateway_state.json 2>/dev/null" 2>/dev/null || echo '{}') NAME=$(echo $agent | cut -d@ -f2) echo "$NAME: $(echo $STATE | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('platforms',{}).get('zulip',{}).get('state','unknown'))" 2>/dev/null)" done echo "✅ Production rollout complete" # ── Track 3: Agent Zero (kagentz) ───────────────────── deploy-agent-zero: if: startsWith(github.ref, 'refs/tags/az-') runs-on: ubuntu-latest needs: [validate] environment: agent-zero steps: - name: Checkout run: git clone --depth 1 http://192.168.68.17:3000/SyslogSolution/zulip-platform-plugins.git . - name: Deploy to kagentz env: TAG: ${{ github.ref_name }} run: | echo "🤖 Deploying Agent Zero $TAG → kagentz (CT 105)" TAG_CLEAN=$(echo $TAG | sed 's/^az-//') ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 root@192.168.68.14 \ "cd /root && bash -s" < scripts/deploy.sh --ct=kagentz --mode=legacy "$TAG_CLEAN" 2>&1