文件
hyb-oa/scripts/qa/run-live-smoke-readiness.sh
T

204 行
6.7 KiB
Bash
可执行文件
原始文件 Blame 文件历史

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
#!/usr/bin/env bash
set -u -o pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
CLIENT_DIR="$ROOT_DIR/client"
PUBLIC_BASE_URL="${LIVE_SMOKE_BASE_URL:-https://oa.hyinda.com}"
REPORT_DIR="${LIVE_SMOKE_READINESS_DIR:-$ROOT_DIR/artifacts/qa-flow/live-smoke-readiness-$(date +%Y%m%d-%H%M%S)}"
REPORT_TOOL="$ROOT_DIR/scripts/qa/live-smoke-readiness-report.mjs"
STATUS=0
SOURCE_COMMIT="$(git -C "$ROOT_DIR" rev-parse HEAD 2>/dev/null || printf 'unknown')"
SOURCE_SHORT_COMMIT="${SOURCE_COMMIT:0:12}"
EXPECTED_BUILD_SHA="${LIVE_SMOKE_EXPECTED_BUILD_SHA:-$SOURCE_SHORT_COMMIT}"
FORBIDDEN_FULL_BUILD_SHA=""
if [[ "$SOURCE_COMMIT" =~ ^[0-9a-fA-F]{40,64}$ && "${EXPECTED_BUILD_SHA:0:12}" == "$SOURCE_SHORT_COMMIT" ]]; then
FORBIDDEN_FULL_BUILD_SHA="$SOURCE_COMMIT"
fi
mkdir -p "$REPORT_DIR"
write_step() {
local name="$1"
local status="$2"
local kind="$3"
local code="$4"
local finding_count="$5"
local detail="$6"
local artifact_file="${7:-}"
node "$REPORT_TOOL" write-step \
"$ROOT_DIR" "$REPORT_DIR" "$name" "$status" "$kind" "$code" "$finding_count" "$detail" "$artifact_file"
}
apply_step_status() {
local status="$1"
local kind="$2"
if [[ "$kind" == "required" && "$status" =~ FAIL|ERROR|BLOCKED ]]; then
STATUS=1
fi
}
run_command_step() {
local name="$1"
local kind="$2"
local detail="$3"
shift 3
local log_file="$REPORT_DIR/${name}.log"
local code=0
local status="PASS"
local finding_count=0
echo ">>> [live-readiness] $name"
if "$@" > >(tee "$log_file") 2>&1; then
echo "[live-readiness][PASS] $name"
else
code="$?"
status="FAIL"
finding_count=1
echo "[live-readiness][FAIL] $name exit=$code"
fi
write_step "$name" "$status" "$kind" "$code" "$finding_count" "$detail" "$log_file"
apply_step_status "$status" "$kind"
}
run_json_step() {
local name="$1"
local kind="$2"
local detail="$3"
local artifact_file="$4"
shift 4
local log_file="$REPORT_DIR/${name}.log"
local code=0
echo ">>> [live-readiness] $name"
if "$@" >"$artifact_file" 2> >(tee "$log_file" >&2); then
code=0
else
code="$?"
fi
local parsed
parsed="$(node -e '
const fs = require("node:fs");
try {
const value = JSON.parse(fs.readFileSync(process.argv[1], "utf8"));
const status = String(value.status || "FAIL").toUpperCase();
const count = Number(value.findingCount || 0);
process.stdout.write(`${status}\t${Number.isFinite(count) ? count : 1}`);
} catch {
process.stdout.write("FAIL\t1");
process.exitCode = 1;
}
' "$artifact_file")" || true
local status="FAIL"
local finding_count=1
IFS=$'\t' read -r status finding_count <<<"$parsed"
if [[ "$code" -ne 0 && ! "$status" =~ FAIL|ERROR|BLOCKED ]]; then
status="FAIL"
finding_count=1
fi
echo "[live-readiness][$status] $name findings=$finding_count"
write_step "$name" "$status" "$kind" "$code" "$finding_count" "$detail" "$artifact_file"
apply_step_status "$status" "$kind"
}
write_skip_step() {
local name="$1"
local detail="$2"
local log_file="$REPORT_DIR/${name}.log"
echo "[live-readiness][SKIP] $name:$detail" | tee "$log_file"
write_step "$name" "SKIP" "finding_allowed" 0 1 "$detail" "$log_file"
}
has_live_smoke_credentials() {
[[ -n "${LIVE_SMOKE_ADMIN_IDENTIFIER:-}" ]] &&
[[ -n "${LIVE_SMOKE_ADMIN_PASSWORD:-}" ]] &&
[[ -n "${LIVE_SMOKE_EMPLOYEE_IDENTIFIER:-}" ]] &&
[[ -n "${LIVE_SMOKE_EMPLOYEE_PASSWORD:-}" ]]
}
has_live_ocr_credentials() {
if [[ -n "${PLAYWRIGHT_OCR_LIVE_IDENTIFIER:-}" && -n "${PLAYWRIGHT_OCR_LIVE_PASSWORD:-}" ]]; then
return 0
fi
[[ -n "${LIVE_SMOKE_EMPLOYEE_IDENTIFIER:-}" ]] && [[ -n "${LIVE_SMOKE_EMPLOYEE_PASSWORD:-}" ]]
}
has_live_ocr_sample() {
if [[ -n "${PLAYWRIGHT_OCR_LIVE_FILE:-}" && -f "$PLAYWRIGHT_OCR_LIVE_FILE" ]]; then
return 0
fi
if [[ -n "${LIVE_OCR_INVOICE_FILE:-}" && -f "$LIVE_OCR_INVOICE_FILE" ]]; then
export PLAYWRIGHT_OCR_LIVE_FILE="$LIVE_OCR_INVOICE_FILE"
return 0
fi
if [[ -n "${PLAYWRIGHT_OCR_LIVE_DIR:-}" && -d "$PLAYWRIGHT_OCR_LIVE_DIR" ]]; then
return 0
fi
return 1
}
run_json_step \
"environment" \
"required" \
"public endpoints and safe readiness labels" \
"$REPORT_DIR/environment.json" \
env LIVE_SMOKE_BASE_URL="$PUBLIC_BASE_URL" LIVE_SMOKE_EXPECTED_BUILD_SHA="$EXPECTED_BUILD_SHA" node "$ROOT_DIR/scripts/qa/check-live-smoke-env.mjs" --json
run_command_step \
"publicReady" \
"required" \
"public readiness endpoint" \
curl -fsS "$PUBLIC_BASE_URL/ready"
run_command_step \
"publicBundle" \
"required" \
"public bundle copy and build marker scan" \
env PUBLIC_EXPECTED_BUILD_SHA="$EXPECTED_BUILD_SHA" PUBLIC_FORBIDDEN_BUILD_SHA="$FORBIDDEN_FULL_BUILD_SHA" node "$ROOT_DIR/scripts/qa/check-public-bundle-copy.mjs" "$PUBLIC_BASE_URL"
run_json_step \
"pendingOcr" \
"required" \
"pending OCR count summary" \
"$REPORT_DIR/pending-ocr.json" \
node "$ROOT_DIR/scripts/qa/check-pending-ocr.mjs" --thresholds=2,5,10 --json
if has_live_smoke_credentials; then
run_command_step \
"liveSmoke" \
"required" \
"authenticated public smoke" \
env LIVE_SMOKE_BASE_URL="$PUBLIC_BASE_URL" bash "$ROOT_DIR/scripts/qa/run-web-gates.sh" smoke-live
else
write_skip_step "liveSmoke" "authenticated smoke prerequisites are incomplete"
fi
if has_live_ocr_credentials && has_live_ocr_sample; then
run_command_step \
"liveOcr" \
"required" \
"live OCR sample verification" \
bash -c 'cd "$1" && PLAYWRIGHT_MANUAL=1 PLAYWRIGHT_OCR_LIVE=1 PLAYWRIGHT_OCR_ALLOW_DUPLICATE="${PLAYWRIGHT_OCR_ALLOW_DUPLICATE:-1}" E2E_BASE_URL="$2" npx playwright test tests/e2e/manual/live-invoice-ocr.spec.ts --workers=1 --reporter=list' _ "$CLIENT_DIR" "$PUBLIC_BASE_URL"
else
write_skip_step "liveOcr" "OCR credentials or PDF sample are incomplete"
fi
if node "$REPORT_TOOL" privacy "$ROOT_DIR" "$REPORT_DIR" >"$REPORT_DIR/privacy.log" 2>&1; then
write_step "privacy" "PASS" "required" 0 0 "readiness report privacy scan" "$REPORT_DIR/privacy-findings.json"
else
write_step "privacy" "FAIL" "required" 1 1 "redacted privacy findings detected" "$REPORT_DIR/privacy-findings.json"
STATUS=1
fi
if ! node "$REPORT_TOOL" summarize "$ROOT_DIR" "$REPORT_DIR" "$PUBLIC_BASE_URL"; then
STATUS=1
fi
summary_status="$(node -e 'const s=require(process.argv[1]); process.stdout.write(String(s.status || "UNKNOWN"))' "$REPORT_DIR/summary.json" 2>/dev/null || printf 'UNKNOWN')"
summary_ref="$(node -e 'const s=require(process.argv[1]); process.stdout.write(String(s.reportRef || "summary unavailable"))' "$REPORT_DIR/summary.json" 2>/dev/null || printf 'summary unavailable')"
echo "[live-readiness][$summary_status] readiness 检查完成"
echo "[live-readiness] report=$summary_ref"
exit "$STATUS"