fix(g2-s7): pin SERVING_BACKEND=duckdb for single-container demo depl… #452
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: E2E Tests | |
| on: | |
| push: | |
| branches: [main] | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| jobs: | |
| e2e: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 12 | |
| env: | |
| AGENTFLOW_E2E_BASE_URL: http://127.0.0.1:8000 | |
| AGENTFLOW_E2E_CALLBACK_HOST: host.docker.internal | |
| AGENTFLOW_E2E_SUPPORT_KEY: af-prod-agent-support-abc123 | |
| AGENTFLOW_E2E_OPS_KEY: af-prod-agent-ops-def456 | |
| AGENTFLOW_E2E_RATE_LIMIT_KEY: af-prod-agent-rate-e2e000 | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 | |
| with: | |
| python-version: "3.11" | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| python -m pip install -e .[dev] | |
| python -m pip install -e ./sdk | |
| python -m pip install -r requirements.txt | |
| python -m pip install click rich pyyaml pytest-timeout | |
| - name: Prepare pytest temp directory | |
| run: mkdir -p .tmp | |
| - name: Start E2E stack | |
| run: | | |
| docker compose -f docker-compose.e2e.yml up -d --build agentflow-api | |
| python - <<'PY' | |
| import json | |
| import subprocess | |
| import time | |
| def parse_compose_ps_output(stdout): | |
| payload = (stdout or "").strip() | |
| if not payload: | |
| return [] | |
| decoder = json.JSONDecoder() | |
| entries = [] | |
| index = 0 | |
| while index < len(payload): | |
| entry, index = decoder.raw_decode(payload, index) | |
| if isinstance(entry, list): | |
| entries.extend(entry) | |
| else: | |
| entries.append(entry) | |
| while index < len(payload) and payload[index].isspace(): | |
| index += 1 | |
| return entries | |
| compose_ps_command = ["docker", "compose", "-f", "docker-compose.e2e.yml", "ps", "--format", "json"] | |
| required = {"agentflow-api", "redis", "kafka", "postgres", "clickhouse"} | |
| deadline = time.monotonic() + 180 | |
| while time.monotonic() < deadline: | |
| result = subprocess.run( | |
| compose_ps_command, | |
| check=False, | |
| capture_output=True, | |
| text=True, | |
| ) | |
| if result.returncode == 0: | |
| try: | |
| entries = parse_compose_ps_output(result.stdout) | |
| except json.JSONDecodeError: | |
| entries = [] | |
| services = {entry["Service"]: entry for entry in entries} | |
| if required.issubset(services): | |
| all_healthy = all( | |
| services[name].get("State") == "running" | |
| and ( | |
| services[name].get("Health") == "healthy" | |
| or "(healthy)" in services[name].get("Status", "") | |
| ) | |
| for name in required | |
| ) | |
| if all_healthy: | |
| break | |
| time.sleep(2) | |
| else: | |
| subprocess.run( | |
| ["docker", "compose", "-f", "docker-compose.e2e.yml", "ps"], | |
| check=False, | |
| ) | |
| raise SystemExit("E2E compose services did not become healthy within 180 seconds.") | |
| PY | |
| python scripts/wait_for_services.py --url "$AGENTFLOW_E2E_BASE_URL" --timeout 120 | |
| - name: Run E2E tests | |
| run: pytest tests/e2e/ -v --tb=short --timeout=60 | |
| # The API seeds ClickHouse only when it boots on the shipped ClickHouse | |
| # serving profile (config/serving.yaml), so rows in agentflow.orders_v2 | |
| # prove the E2E stack exercised the real engine, not a DuckDB fallback. | |
| - name: Verify ClickHouse serving path | |
| run: | | |
| orders=$(docker compose -f docker-compose.e2e.yml exec -T clickhouse \ | |
| clickhouse-client --query "SELECT count() FROM agentflow.orders_v2") | |
| echo "agentflow.orders_v2 rows: $orders" | |
| test "$orders" -gt 0 | |
| events_table=$(docker compose -f docker-compose.e2e.yml exec -T clickhouse \ | |
| clickhouse-client --query "EXISTS TABLE agentflow.pipeline_events") | |
| echo "agentflow.pipeline_events exists: $events_table" | |
| test "$events_table" = "1" | |
| - name: Collect logs on failure | |
| if: failure() | |
| run: docker compose -f docker-compose.e2e.yml logs --tail=500 > e2e-logs.txt | |
| - name: Upload logs | |
| if: failure() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: e2e-logs | |
| path: e2e-logs.txt | |
| - name: Stop API | |
| if: always() | |
| run: | | |
| docker compose -f docker-compose.e2e.yml down -v |