#!/usr/bin/env bash # # Sprint 24: контракт-тест — diff /openapi.json между двумя # окружениями. Используется ПЕРЕД blue-green деплоем чтобы понять что # меняется в публичном API и не сломать клиентов (Web admin, POS WPF, # партнёрские интеграции). # # Usage: # deploy/swagger-diff.sh [--from URL] [--to URL] # # Default: # from = https://admin.food-market.kz (prod) # to = https://test.admin.food-market.kz (stage) # # Что показывает: # - removed endpoints (path+method) — BREAKING ⚠️ # - added endpoints — NEW (нормально) # - changed request/response schemas — нужен ручной обзор # # Без зависимости от swagger-diff CLI: парсим JSON через python3. # # Exit codes: # 0 — изменений нет ИЛИ только additions # 1 — есть removed (BREAKING) или changed schemas # 2 — ошибка получения swagger.json set -uo pipefail FROM_URL="${FM_SWAGGER_FROM:-https://admin.food-market.kz}" TO_URL="${FM_SWAGGER_TO:-https://test.admin.food-market.kz}" while [[ $# -gt 0 ]]; do case "$1" in --from) FROM_URL="$2"; shift 2 ;; --to) TO_URL="$2"; shift 2 ;; --help|-h) grep -E '^#( |$)' "$0" | sed 's/^# \?//'; exit 0 ;; *) echo "Unknown: $1" >&2; exit 2 ;; esac done TMP=$(mktemp -d) trap "rm -rf $TMP" EXIT # Пытаемся несколько канонических путей: Swashbuckle default + alt-routes. fetch_swagger() { local base="$1" out="$2" for path in /swagger/v1/swagger.json /v1/swagger.json /api/v1/swagger.json; do if curl -fsS --max-time 30 "$base$path" -o "$out" 2>/dev/null; then # Должен быть JSON, не HTML (фронт SPA отдаёт index.html на unknown path). if python3 -c 'import json,sys; json.load(open(sys.argv[1]))' "$out" 2>/dev/null; then echo " found at $path" >&2 return 0 fi fi done return 1 } echo "Fetching from $FROM_URL…" >&2 fetch_swagger "$FROM_URL" "$TMP/from.json" \ || { echo "FAIL: $FROM_URL не отдаёт swagger.json. Проверьте IncludeSwagger=true в appsettings или ASPNETCORE_ENVIRONMENT=Development." >&2; exit 2; } echo "Fetching from $TO_URL…" >&2 fetch_swagger "$TO_URL" "$TMP/to.json" \ || { echo "FAIL: $TO_URL не отдаёт swagger.json." >&2; exit 2; } python3 - <