测试文件修复 (17/19 spec/tests): - 完全重写 10 个内容错误文件 (phase-37/39/40/41/42/45/46/51/52/53) · phase-37: 租户CRUD → Grafana仪表盘验证 · phase-39: 租户套餐 → @DataMask注解脱敏 · phase-40: 租户账单 → 岗位管理(/api/v1/posts) · phase-41: 修正状态机(FROZEN/CANCELLED)和路由(/freeze/unfreeze) · phase-42: 虚构endpoint → 超管机制测试(isSuperAdmin/TenantLineHandler) · phase-45: /tasks/audit → /task-logs + system:taskLog:* · phase-46: 工作流引擎 → 导入导出中心 · phase-51: 修正消息记录(msg_record + msg_user_inbox) · phase-52: 消息日志 → 订阅管理(JSONB preference) · phase-53: ACL可见性 → 工作流引擎4表CRUD+approve/reject - 修复7个权限action名 (create→add, update→edit, detail→query) CI Gate 流水线: - 新增 scripts/wait-github-workflow.sh (gh API轮询, 支持timeout) - 更新 scripts/run-all.sh: 扩展至Phase 53 + --checkpoint/--repo/--workflow/--auto-commit参数 Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
119 lines
3.9 KiB
Bash
Executable File
119 lines
3.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# ═══════════════════════════════════════════════════════════
|
||
# wait-github-workflow.sh — 轮询 GitHub Actions 直到指定 workflow 完成
|
||
#
|
||
# 用法:
|
||
# bash scripts/wait-github-workflow.sh \
|
||
# --repo owner/repo \
|
||
# --sha <full-commit-sha> \
|
||
# --workflow build-and-notify.yml
|
||
#
|
||
# 可选参数:
|
||
# --timeout-sec 3600 总超时(默认 3600s)
|
||
# --interval-sec 15 轮询间隔(默认 15s)
|
||
#
|
||
# 依赖:
|
||
# gh CLI(已 `gh auth login`)或 GITHUB_TOKEN 环境变量(repo/actions:read 权限)
|
||
#
|
||
# 退出码:
|
||
# 0 — success
|
||
# 2 — 参数错误
|
||
# 3 — 超时
|
||
# 10 — workflow 以非 success 结论结束
|
||
# ═══════════════════════════════════════════════════════════
|
||
set -euo pipefail
|
||
|
||
# ── Argument parsing ───────────────────────────────────────
|
||
REPO=""
|
||
SHA=""
|
||
WORKFLOW=""
|
||
TIMEOUT_SEC=3600
|
||
INTERVAL_SEC=15
|
||
|
||
while [[ $# -gt 0 ]]; do
|
||
case "$1" in
|
||
--repo) REPO="$2"; shift 2 ;;
|
||
--sha) SHA="$2"; shift 2 ;;
|
||
--workflow) WORKFLOW="$2"; shift 2 ;;
|
||
--timeout-sec) TIMEOUT_SEC="$2"; shift 2 ;;
|
||
--interval-sec) INTERVAL_SEC="$2"; shift 2 ;;
|
||
*) echo "[wait-workflow] Unknown arg: $1"; exit 2 ;;
|
||
esac
|
||
done
|
||
|
||
if [[ -z "$REPO" || -z "$SHA" || -z "$WORKFLOW" ]]; then
|
||
echo "Usage: $0 --repo owner/repo --sha <sha> --workflow <workflow_file>"
|
||
echo " (e.g. --workflow build-and-notify.yml)"
|
||
exit 2
|
||
fi
|
||
|
||
# ── Helpers ────────────────────────────────────────────────
|
||
get_run_id() {
|
||
# 返回该 workflow 在该 commit 上最新一条 run 的 id;未找到返回空字符串
|
||
gh api \
|
||
-H "Accept: application/vnd.github+json" \
|
||
"/repos/${REPO}/actions/workflows/${WORKFLOW}/runs?per_page=50" \
|
||
--jq ".workflow_runs[] | select(.head_sha==\"${SHA}\") | .id" \
|
||
2>/dev/null | head -n 1 || true
|
||
}
|
||
|
||
get_run_info() {
|
||
local run_id="$1"
|
||
gh api \
|
||
-H "Accept: application/vnd.github+json" \
|
||
"/repos/${REPO}/actions/runs/${run_id}" \
|
||
--jq '{status:.status,conclusion:.conclusion,url:.html_url}' \
|
||
2>/dev/null || true
|
||
}
|
||
|
||
# ── Main loop ──────────────────────────────────────────────
|
||
echo "[CI] Waiting for workflow '${WORKFLOW}' on ${REPO} @ ${SHA:0:12}..."
|
||
start_ts=$(date +%s)
|
||
run_id=""
|
||
|
||
while true; do
|
||
elapsed=$(( $(date +%s) - start_ts ))
|
||
if (( elapsed >= TIMEOUT_SEC )); then
|
||
echo "[CI] TIMEOUT after ${TIMEOUT_SEC}s — sha=${SHA:0:12}"
|
||
exit 3
|
||
fi
|
||
|
||
# ── Find run id ──
|
||
if [[ -z "$run_id" ]]; then
|
||
run_id="$(get_run_id)"
|
||
if [[ -z "$run_id" ]]; then
|
||
echo "[CI] Run not found yet (elapsed ${elapsed}s) — retrying in ${INTERVAL_SEC}s..."
|
||
sleep "$INTERVAL_SEC"
|
||
continue
|
||
fi
|
||
echo "[CI] Found run_id=${run_id}"
|
||
fi
|
||
|
||
# ── Poll status ──
|
||
info="$(get_run_info "$run_id")"
|
||
if [[ -z "$info" ]]; then
|
||
echo "[CI] Failed to fetch run info — retrying in ${INTERVAL_SEC}s..."
|
||
sleep "$INTERVAL_SEC"
|
||
continue
|
||
fi
|
||
|
||
status="$(echo "$info" | jq -r '.status')"
|
||
conclusion="$(echo "$info" | jq -r '.conclusion')"
|
||
url="$(echo "$info" | jq -r '.url')"
|
||
|
||
echo "[CI] status=${status} conclusion=${conclusion} elapsed=${elapsed}s"
|
||
|
||
if [[ "$status" == "completed" ]]; then
|
||
if [[ "$conclusion" == "success" ]]; then
|
||
echo "[CI] PASSED — ${url}"
|
||
exit 0
|
||
else
|
||
echo "[CI] FAILED — conclusion=${conclusion}"
|
||
echo "[CI] URL: ${url}"
|
||
exit 10
|
||
fi
|
||
fi
|
||
|
||
sleep "$INTERVAL_SEC"
|
||
done
|