This episode discusses automating the agent service lifecycle: CI/CD for Docker and Cloud Run, multi-agent testing in the pipeline, agent card contract testing, and version governance, deprecation policy, and per-agent SLAs.

Episode 19 showed the commercial side of the A2A ecosystem: agents can request payment via x402, governed by mandate and approval, then settled through trust rails. But behind the scenes, all that capability is only useful if the service can be managed with discipline. Episode 20 brings A2A into the operational realm: automation and policy-as-code. We'll build a CI/CD pipeline that deploys an agent service to Docker and Cloud Run, write multi-agent tests that actually execute tasks in the pipeline, apply contract testing to the agent card, then arrange governance — agent versioning, deprecation policy, and measurable per-agent SLAs.
An agent service is no different from an ordinary web service: it needs an image, a pipeline, and a deployment target. Docker is the most neutral starting point — the same image can run locally, on staging, or in production.
FROM node:22-slim AS build
WORKDIR /app
COPY package.json bun.lock ./
RUN bun install --frozen-lockfile
COPY . .
FROM node:22-slim AS runtime
WORKDIR /app
ENV NODE_ENV=production
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
COPY --from=build /app/agent-card.json ./agent-card.json
EXPOSE 3000
CMD ["node", "dist/server.js"]The agent card is copied into the image because it's a release artifact, not a configuration file. When the card changes, the image version changes too — and clients caching the card get the signal via version metadata. For serverless platforms like Cloud Run, deployment happens after the build and tests are green, just one line in the pipeline:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t a2a-agent:${{ github.sha }} .
- name: Deploy to Cloud Run
run: |
gcloud run deploy a2a-agent --image gcr.io/my-project/a2a-agent:${{ github.sha }} \
--region asia-southeast1 --allow-unauthenticatedThe commit-SHA tag pattern guarantees every deploy can be traced back to its exact commit. For a quick local verification before pushing to the pipeline, run docker build -t a2a-agent:dev .. The principle is the same for Cloud Run, ECS, or Kubernetes — only the target changes.
A pipeline that only builds without running agents is false confidence. A valuable test for A2A must run two real agents and send real tasks between them — not mocks.
import pytest
@pytest.mark.asyncio
async def test_agent_ke_agent():
async with run_server(agent_analisa) as url_a, run_server(agent_ringkas) as url_b:
client = A2AClient(httpx.AsyncClient())
task = await client.send_task(url_a, {
"parts": [{"type": "text", "text": "Ringkas laporan ini"}],
})
assert task.status == "completed"
hasil = task.artifact.parts[0].text
assert len(hasil) > 0
task_b = await client.send_task(url_b, {
"parts": [{"type": "text", "text": f"Terjemahkan: {hasil}"}],
})
assert task_b.status == "completed"Several things that must be tested besides the happy path:
submitted to working, then to a terminal state — nothing hangs in working.failed with a message the client can read.These tests run on every pull request, so regressions between agents are caught before production — the difference between a pile of code and a system that genuinely collaborates.
When many clients rely on your agent card, a small change to the card can break all of them. Contract testing treats the agent card as a public contract that is explicitly tested.
import jsonschema
import pytest
SCHEMA = load_json("agent-card-schema.json")
def test_agent_card_valid():
card = load_json("agent-card.json")
jsonschema.validate(card, SCHEMA)
def test_skill_id_stabil():
card = load_json("agent-card.json")
for skill in card["skills"]:
assert skill["id"].startswith("a2a-agent:")
def test_breaking_change_terdeteksi():
lama = load_json("agent-card.v1.json")
baru = load_json("agent-card.json")
for skill in lama["skills"]:
if skill["id"] not in [s["id"] for s in baru["skills"]]:
pytest.fail("skill yang dideprekasi belum lewat masa transisi")Schema validation catches broken cards; id assertions catch silently missing skills. The most important is the third test: breaking changes must be deliberate and scheduled, not an accidental refactor that happens to remove a skill.
Versioning is the agreed language between an agent's owner and its clients. For A2A there are two things to version: the protocol version (handled by version negotiation, discussed in episodes 10 and 21) and the agent's capability version — the agent card version.
Healthy practices:
{
"agentName": "a2a-agent",
"cardVersion": "3.2.0",
"protocolVersion": "1.0",
"skills": [
{
"id": "a2a-agent:analisa-kredit",
"name": "Analisa Kredit",
"deprecated": true,
"sunset": "2026-12-31"
},
{
"id": "a2a-agent:analisa-kredit-v2",
"name": "Analisa Kredit v2",
"inputs": ["skor_kredit", "riwayat"]
}
]
}Smart clients read the deprecated and sunset markers and migrate before the deadline. A written deprecation policy is an agreement — not a sudden command.
Finally, agents need a measurable SLA. Without numbers, clients can't trust an agent with critical tasks. Four common metrics:
failed status — signaling quality problems, not just uptime problems.agent: a2a-agent
version: "3.2.0"
slo:
availability: "99.5%"
latency_p95: "4s"
error_rate: "0.5%"
throughput_per_sec: 500
windows:
- "1m"
- "7d"Publishing SLOs alongside the agent card lets clients read the promised capacity before sending a task. Because these SLOs are version-sensitive, performance improvements in a major release show up as improved numbers.
Episode 20 closes the gap between "an agent works on my laptop" and "an agent runs in production". CI/CD makes deploys repeatable and traceable, multi-agent tests prove real collaboration in the pipeline, contract testing protects the agent card as a public contract, and governance — versioning, deprecation, and SLAs — provides an agreed language between agent owners and consumers.
Here's the core takeaway:
In episode 21 we look to the horizon: modern features and the A2A roadmap — from the stable v1.0 with signed agent cards, multi-tenancy, and version negotiation, to the development direction of discovery and security. See you there!