Skip to content

Commit 4733ed9

Browse files
committed
feat: Add cloud deployment example with event replication
Add Kubernetes deployment example demonstrating multi-instance A2A agents with database persistence and Kafka-based event replication.
1 parent 5f4a277 commit 4733ed9

File tree

20 files changed

+2224
-1
lines changed

20 files changed

+2224
-1
lines changed
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
name: Cloud Deployment Example Test
2+
3+
on:
4+
push:
5+
pull_request:
6+
workflow_dispatch:
7+
8+
# Only run the latest job
9+
concurrency:
10+
group: '${{ github.workflow }} @ ${{ github.head_ref || github.ref }}'
11+
cancel-in-progress: true
12+
13+
jobs:
14+
test-cloud-deployment:
15+
runs-on: ubuntu-latest
16+
timeout-minutes: 30
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
21+
- name: Set up JDK 17
22+
uses: actions/setup-java@v5
23+
with:
24+
java-version: '17'
25+
distribution: 'temurin'
26+
cache: maven
27+
28+
- name: Start Minikube
29+
uses: medyagh/setup-minikube@latest
30+
with:
31+
cpus: 4
32+
memory: 8192
33+
kubernetes-version: v1.30.0
34+
driver: docker
35+
addons: ingress
36+
insecure-registry: '192.168.49.1:5001'
37+
38+
- name: Build project
39+
run: mvn -B clean install -DskipTests -f pom.xml
40+
41+
- name: Build and package server
42+
working-directory: examples/cloud-deployment/server
43+
run: mvn clean package -DskipTests
44+
45+
- name: Build Docker image
46+
working-directory: examples/cloud-deployment/server
47+
run: |
48+
docker build -t localhost:5001/a2a-cloud-deployment:latest .
49+
docker tag localhost:5001/a2a-cloud-deployment:latest 192.168.49.1:5001/a2a-cloud-deployment:latest
50+
51+
- name: Deploy infrastructure (skip agent)
52+
working-directory: examples/cloud-deployment/scripts
53+
env:
54+
SKIP_AGENT_DEPLOY: "true"
55+
run: |
56+
chmod +x deploy.sh
57+
./deploy.sh
58+
59+
- name: Load image into minikube and deploy agent
60+
working-directory: examples/cloud-deployment
61+
run: |
62+
# Load image into minikube
63+
echo "Loading image into minikube..."
64+
minikube image load 192.168.49.1:5001/a2a-cloud-deployment:latest
65+
66+
# Verify image is in minikube
67+
echo "Verifying image in minikube:"
68+
minikube ssh -- docker images | grep a2a-cloud-deployment
69+
70+
# Modify deployment YAML to use imagePullPolicy: Never before applying
71+
echo "Deploying agent with imagePullPolicy: Never..."
72+
cat k8s/04-agent-deployment.yaml | \
73+
sed 's/imagePullPolicy: Always/imagePullPolicy: Never/' | \
74+
kubectl apply -f -
75+
76+
# Wait for rollout to complete
77+
echo "Waiting for deployment rollout to complete..."
78+
kubectl rollout status deployment/a2a-agent -n a2a-demo --timeout=120s
79+
80+
echo "Waiting for agent pods to be ready..."
81+
kubectl wait --for=condition=Ready pod -l app=a2a-agent -n a2a-demo --timeout=120s
82+
83+
- name: Verify deployment
84+
working-directory: examples/cloud-deployment/scripts
85+
run: |
86+
chmod +x verify.sh
87+
./verify.sh
88+
89+
- name: Start minikube tunnel in background
90+
run: |
91+
minikube tunnel > /tmp/minikube-tunnel.log 2>&1 &
92+
echo $! > /tmp/minikube-tunnel.pid
93+
sleep 10 # Wait for tunnel to establish
94+
95+
- name: Wait for external IP
96+
run: |
97+
echo "Waiting for LoadBalancer external IP..."
98+
for i in {1..30}; do
99+
EXTERNAL_IP=$(kubectl get svc a2a-agent-service -n a2a-demo -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
100+
if [ ! -z "$EXTERNAL_IP" ]; then
101+
echo "External IP assigned: $EXTERNAL_IP"
102+
echo "AGENT_IP=$EXTERNAL_IP" >> $GITHUB_ENV
103+
break
104+
fi
105+
echo "Attempt $i/30: Waiting for external IP..."
106+
sleep 2
107+
done
108+
kubectl get svc a2a-agent-service -n a2a-demo
109+
110+
- name: Verify agent card is accessible
111+
run: |
112+
echo "Testing agent card endpoint at http://${{ env.AGENT_IP }}:8080/.well-known/agent-card.json"
113+
curl -f http://${{ env.AGENT_IP }}:8080/.well-known/agent-card.json || (echo "Agent card not accessible" && exit 1)
114+
115+
- name: Run test client
116+
working-directory: examples/cloud-deployment/server
117+
run: |
118+
mvn test-compile exec:java \
119+
-Dexec.mainClass="io.a2a.examples.cloud.A2ACloudExampleClient" \
120+
-Dexec.classpathScope=test \
121+
-Dagent.url=http://${{ env.AGENT_IP }}:8080
122+
123+
- name: Show diagnostics on failure
124+
if: failure()
125+
run: |
126+
echo "=== Agent Pod Status ==="
127+
kubectl get pods -n a2a-demo -l app=a2a-agent -o wide
128+
129+
echo ""
130+
echo "=== Agent Pod Descriptions ==="
131+
for pod in $(kubectl get pods -n a2a-demo -l app=a2a-agent -o jsonpath='{.items[*].metadata.name}'); do
132+
echo "--- Pod: $pod ---"
133+
kubectl describe pod $pod -n a2a-demo | tail -30
134+
done
135+
136+
echo ""
137+
echo "=== Recent Events ==="
138+
kubectl get events -n a2a-demo --sort-by='.lastTimestamp' | tail -20
139+
140+
echo ""
141+
echo "=== Agent Pod Logs ==="
142+
for pod in $(kubectl get pods -n a2a-demo -l app=a2a-agent -o jsonpath='{.items[*].metadata.name}'); do
143+
echo "--- Logs for $pod ---"
144+
kubectl logs -n a2a-demo $pod --tail=100 || true
145+
done
146+
147+
echo ""
148+
echo "=== PostgreSQL Logs ==="
149+
kubectl logs -n a2a-demo postgres-0 --tail=50 || true
150+
151+
echo ""
152+
echo "=== Kafka Logs ==="
153+
kubectl logs -n kafka -l strimzi.io/cluster=a2a-kafka --tail=50 || true
154+
155+
- name: Cleanup
156+
if: always()
157+
run: |
158+
# Kill minikube tunnel if running
159+
if [ -f /tmp/minikube-tunnel.pid ]; then
160+
kill $(cat /tmp/minikube-tunnel.pid) || true
161+
fi
162+
# Cleanup resources
163+
cd examples/cloud-deployment/scripts
164+
echo "y" | ./cleanup.sh || true
165+
166+

0 commit comments

Comments
 (0)