From dc57168d96474f4748730f99cd1e2ac72d412e8b Mon Sep 17 00:00:00 2001 From: Kpa-clawbot <259247574+Kpa-clawbot@users.noreply.github.com> Date: Fri, 27 Mar 2026 14:57:21 -0700 Subject: [PATCH] ci: add proto validation step to catch API contract drift Added a CI step that: - Refreshes Node fixtures from the staging container after deployment - Runs tools/validate-protos.py to validate proto definitions match actual API responses - Fails the pipeline if proto drift is detected This ensures nobody can merge a Node change that breaks the Go proto contract without updating the .proto definitions. The step runs after the Node staging healthcheck, capturing fresh responses from 19 API endpoints (stats, health, nodes, analytics/*, config/*, etc.). Endpoints requiring parameters (node-detail, packet-detail) use existing fixtures and aren't auto-refreshed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/deploy.yml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 1b4f49f9..d7931c70 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -364,6 +364,42 @@ jobs: curl -f http://localhost:81/api/nodes || exit 1 echo "Node staging smoke tests passed ✅" + - name: Validate API contract (proto vs Node fixtures) + run: | + set -e + echo "Refreshing Node fixtures from staging container..." + mkdir -p proto/testdata/node-fixtures + + # Capture fresh API responses from staging container + # Only refresh endpoints that don't require parameters + ENDPOINTS=( + "stats" "health" "perf" "nodes" "packets" "observers" "channels" + "analytics/rf" "analytics/topology" "analytics/channels" + "analytics/hash-sizes" "analytics/distance" "analytics/subpaths" + "config/theme" "config/regions" "config/client" "config/cache" "config/map" + "iata-coords" + ) + + for endpoint in "${ENDPOINTS[@]}"; do + # Convert /api/analytics/rf → analytics-rf.json + fixture_name=$(echo "$endpoint" | tr '/' '-') + echo " Fetching $endpoint → ${fixture_name}.json" + docker exec meshcore-staging wget -qO- "http://localhost:3000/api/$endpoint" \ + > "proto/testdata/node-fixtures/${fixture_name}.json" 2>/dev/null || { + echo " ⚠ Failed to fetch $endpoint (container may not have data yet)" + } + done + + echo "" + echo "Running proto validator..." + python3 tools/validate-protos.py || { + echo "❌ Proto validation failed — API contract drift detected" + echo "This means a Node.js API response doesn't match the proto definition." + echo "Fix by updating the .proto files in proto/ to match the actual API responses." + exit 1 + } + echo "✅ Proto validation passed — API contract is consistent" + # ─────────────────────────────────────────────────────────────── # 6. Deploy Go Staging — start on port 82, healthcheck, smoke test # ───────────────────────────────────────────────────────────────