fix(ci): staging smoke test添加版本号校验,防止部署假绿 #334

Merged
xiaoxia merged 2 commits from fix/ci-staging-version-check into develop 2026-07-14 22:11:37 +08:00
+1 -1
View File
@@ -639,7 +639,7 @@ jobs:
run: "set -eu\nREGISTRY=\"git.xiaoxiajianji.com/xiaoxia/xiaoxia-saas\"\n\nfor svc in api worker web; do\n echo \"Pulling ${REGISTRY}/xiaoxia-saas-${svc}:${GITHUB_SHA} ...\"\n docker pull \"${REGISTRY}/xiaoxia-saas-${svc}:${GITHUB_SHA}\"\n docker tag \"${REGISTRY}/xiaoxia-saas-${svc}:${GITHUB_SHA}\" \"${REGISTRY}/xiaoxia-saas-${svc}:staging\"\n docker push \"${REGISTRY}/xiaoxia-saas-${svc}:staging\"\n echo \"$svc :staging tagged and pushed\"\ndone\necho \"All :staging images pushed. Watchtower will auto-deploy within 60s.\"\n"
- name: Wait for Watchtower update + smoke test
shell: sh
run: "set -eu\necho \"Waiting 90s for Watchtower to detect new image and restart containers...\"\nsleep 90\n\necho \"--- Smoke test 1: Health check ---\"\nfor i in $(seq 1 12); do\n HEALTH=$(curl -sf --max-time 10 https://staging-api.xiaoxiajianji.com/health) && break\n echo \" Attempt $i/12: not ready yet, waiting 5s...\"\n sleep 5\ndone\nif [ -z \"$HEALTH\" ]; then\n echo \"FAIL: health endpoint unreachable after 60s\"\n exit 1\nfi\necho \"Health OK: $HEALTH\"\n\necho \"--- Smoke test 2: Login API (expect 401) ---\"\nHTTP_CODE=$(curl -s -o /dev/null -w \"%{http_code}\" --max-time 10 -X POST \\\n https://staging-api.xiaoxiajianji.com/api/v1/auth/login \\\n -H \"Content-Type: application/json\" \\\n -d '{\"email\":\"smoke@test.com\",\"password\":\"wrong\"}')\nif [ \"$HTTP_CODE\" != \"401\" ] && [ \"$HTTP_CODE\" != \"422\" ]; then\n echo \"FAIL: login returned HTTP $HTTP_CODE (expected 401 or 422)\"\n exit 1\nfi\necho \"Login API OK: HTTP $HTTP_CODE\"\n\necho \"--- Smoke\
run: "set -eu\necho \"Waiting 90s for Watchtower to detect new image and restart containers...\"\nsleep 90\n\necho \"--- Smoke test 1: Health check + version verification ---\"\nEXPECTED_VERSION=\"${GITHUB_SHA:0:7}\"\nHEALTH=\"\"\nfor i in $(seq 1 30); do\n HEALTH=$(curl -sf --max-time 10 https://staging-api.xiaoxiajianji.com/health) && break\n echo \" Attempt $i/30: not ready yet, waiting 5s...\"\n sleep 5\ndone\nif [ -z \"$HEALTH\" ]; then\n echo \"FAIL: health endpoint unreachable after 150s\"\n exit 1\nfi\necho \"Health OK: $HEALTH\"\n\n# 验证版本号匹配\nACTUAL_VERSION=$(echo \"$HEALTH\" | python3 -c \"import sys,json; print(json.load(sys.stdin).get('version','')[:7])\")\nif [ \"$ACTUAL_VERSION\" != \"$EXPECTED_VERSION\" ]; then\n echo \"WARN: version mismatch - expected $EXPECTED_VERSION, got $ACTUAL_VERSION\"\n echo \"Waiting for Watchtower to finish updating...\"\n VERSION_MATCH=0\n for i in $(seq 1 36); do\n sleep 5\n HEALTH=$(curl -sf --max-time 10 https://staging-api.xiaoxiajianji.com/health) || continue\n ACTUAL_VERSION=$(echo \"$HEALTH\" | python3 -c \"import sys,json; print(json.load(sys.stdin).get('version','')[:7])\")\n if [ \"$ACTUAL_VERSION\" = \"$EXPECTED_VERSION\" ]; then\n VERSION_MATCH=1\n echo \"Version updated: $ACTUAL_VERSION\"\n break\n fi\n echo \" Attempt $i/36: still $ACTUAL_VERSION, waiting...\"\n done\n if [ $VERSION_MATCH -eq 0 ]; then\n echo \"FAIL: staging version not updated after 3 minutes (still $ACTUAL_VERSION, expected $EXPECTED_VERSION)\"\n exit 1\n fi\nelse\n echo \"Version OK: $ACTUAL_VERSION\"\nfi\n\necho \"--- Smoke test 2: Login API (expect 401) ---\"\nHTTP_CODE=$(curl -s -o /dev/null -w \"%{http_code}\" --max-time 10 -X POST \\\n https://staging-api.xiaoxiajianji.com/api/v1/auth/login \\\n -H \"Content-Type: application/json\" \\\n -d '{\"email\":\"smoke@test.com\",\"password\":\"wrong\"}')\nif [ \"$HTTP_CODE\" != \"401\" ] && [ \"$HTTP_CODE\" != \"422\" ]; then\n echo \"FAIL: login returned HTTP $HTTP_CODE (expected 401 or 422)\"\n exit 1\nfi\necho \"Login API OK: HTTP $HTTP_CODE\"\n\necho \"--- Smoke test 3: API docs endpoint ---\"\nHTTP_CODE=$(curl -s -o /dev/null -w \"%{http_code}\" --max-time 10 https://staging-api.xiaoxiajianji.com/docs)\nif [ \"$HTTP_CODE\" != \"200\" ]; then\n echo \"FAIL: /docs returned HTTP $HTTP_CODE (expected 200)\"\n exit 1\nfi\necho \"Docs endpoint OK: HTTP $HTTP_CODE\"\n\necho \"--- Smoke test 4: Web frontend ---\"\nHTTP_CODE=$(curl -s -o /dev/null -w \"%{http_code}\" --max-time 10 https://staging.xiaoxiajianji.com/)\nif [ \"$HTTP_CODE\" != \"200\" ]; then\n echo \"FAIL: web frontend returned HTTP $HTTP_CODE (expected 200)\"\n exit 1\nfi\necho \"Web frontend OK: HTTP $HTTP_CODE\"\n\necho \"\"\necho \"=== All smoke tests passed! ===\"\necho \"Branch: ${GITHUB_REF_NAME}\"\necho \"Commit: ${GITHUB_SHA}\"\necho \"Staging Version: ${ACTUAL_VERSION}\"\n"
\ test 3: API docs endpoint ---\"\nHTTP_CODE=$(curl -s -o /dev/null -w \"%{http_code}\" --max-time 10 https://staging-api.xiaoxiajianji.com/docs)\nif [ \"$HTTP_CODE\" != \"200\" ]; then\n echo \"FAIL: /docs returned HTTP $HTTP_CODE (expected 200)\"\n exit 1\nfi\necho \"Docs endpoint OK: HTTP $HTTP_CODE\"\n\necho \"--- Smoke test 4: Web frontend ---\"\nHTTP_CODE=$(curl -s -o /dev/null -w \"%{http_code}\" --max-time 10 https://staging.xiaoxiajianji.com/)\nif [ \"$HTTP_CODE\" != \"200\" ]; then\n echo \"FAIL: web frontend returned HTTP $HTTP_CODE (expected 200)\"\n exit 1\nfi\necho \"Web frontend OK: HTTP $HTTP_CODE\"\n\necho \"\"\necho \"=== All smoke tests passed! ===\"\necho \"Branch: ${GITHUB_REF_NAME}\"\necho \"Commit: ${GITHUB_SHA}\"\n"
- name: Job duration summary
if: always()