d2ce73184a
CI/CD Pipeline / Unit Tests (push) Successful in 2m18s
CI/CD Pipeline / Frontend Lint (push) Successful in 2m40s
CI/CD Pipeline / Validate Code Quality And Tests (push) Successful in 3m0s
CI/CD Pipeline / Integration Tests (push) Successful in 1m23s
CI Build & Deploy Pipeline / Staging API Integration Tests (push) Failing after 2m28s
CI Build & Deploy Pipeline / Build Staging API Image (push) Successful in 6m16s
CI Build & Deploy Pipeline / Build Staging Web Image (push) Successful in 4m43s
CI Build & Deploy Pipeline / Build Staging Worker Image (push) Successful in 7m29s
CI Build & Deploy Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 2m4s
CI Build & Deploy Pipeline / Build Production API Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Production Web Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Production Worker Image (push) Has been skipped
CI Build & Deploy Pipeline / Deploy Production (push) Has been skipped
CI Build & Deploy Pipeline / Production Browser E2E (push) Has been skipped
CI Build & Deploy Pipeline / Staging E2E Tests (push) Failing after 2m35s
109 lines
3.4 KiB
Bash
Executable File
109 lines
3.4 KiB
Bash
Executable File
#!/bin/bash
|
|
# 自动合并通过 CI 检查的 PR
|
|
# 用法: ./scripts/auto_merge_prs.sh [target_branch]
|
|
#
|
|
# 合并前必须验证的 CI 检查项:
|
|
# - CI/CD Pipeline / Validate Code Quality And Tests (push)
|
|
# - CI/CD Pipeline / Frontend Lint (push)
|
|
# 只有两个检查项均为 success 状态才允许合并
|
|
|
|
GITEA_API="${GITEA_API_URL:-https://git.xiaoxiajianji.com/api/v1}"
|
|
TOKEN="${GITEA_API_TOKEN:?Please set GITEA_API_TOKEN environment variable}"
|
|
REPO="xiaoxia/xiaoxia-saas"
|
|
TARGET_BRANCH="${1:-develop}"
|
|
|
|
# 必需的 CI 检查项(context 名称前缀匹配,避免 pipeline 名称变化导致匹配失败)
|
|
REQUIRED_CHECKS=(
|
|
"Validate Code Quality And Tests"
|
|
"Frontend Lint"
|
|
)
|
|
|
|
echo "=== Checking open PRs targeting $TARGET_BRANCH ==="
|
|
|
|
# 获取所有 open PR
|
|
PRS=$(curl -s -H "Authorization: token $TOKEN" \
|
|
"$GITEA_API/repos/$REPO/pulls?state=open&sort=updated&direction=desc" | python3 -c "
|
|
import json, sys
|
|
data = json.load(sys.stdin)
|
|
for pr in data:
|
|
if pr.get('base', {}).get('ref') == '$TARGET_BRANCH':
|
|
head_sha = pr.get('head', {}).get('sha', '')
|
|
print(f\"{pr['number']}|{pr['title']}|{head_sha}\")
|
|
")
|
|
|
|
if [ -z "$PRS" ]; then
|
|
echo "No open PRs found for $TARGET_BRANCH"
|
|
exit 0
|
|
fi
|
|
|
|
merge_count=0
|
|
skip_count=0
|
|
|
|
echo "$PRS" | while IFS='|' read -r number title head_sha; do
|
|
echo ""
|
|
echo "--- PR #$number: $title ---"
|
|
echo " Head SHA: $head_sha"
|
|
|
|
# 获取该 commit 的 combined CI 状态
|
|
STATUS_JSON=$(curl -s -H "Authorization: token $TOKEN" \
|
|
"$GITEA_API/repos/$REPO/commits/$head_sha/status")
|
|
|
|
# 检查每个必需的 CI 项是否通过
|
|
all_passed=true
|
|
failed_checks=""
|
|
|
|
for check_pattern in "${REQUIRED_CHECKS[@]}"; do
|
|
state=$(echo "$STATUS_JSON" | python3 -c "
|
|
import json, sys
|
|
d = json.load(sys.stdin)
|
|
pattern = '$check_pattern'
|
|
# 在 statuses 中找到匹配的最新状态
|
|
target = None
|
|
for s in d.get('statuses', []):
|
|
if pattern in s.get('context', ''):
|
|
target = s
|
|
break # status 接口返回的是每个 context 的最新状态,取第一个匹配即可
|
|
if target:
|
|
print(target.get('state', 'unknown'))
|
|
else:
|
|
print('not_found')
|
|
")
|
|
|
|
if [ "$state" = "success" ]; then
|
|
echo " ✅ $check_pattern: $state"
|
|
else
|
|
echo " ❌ $check_pattern: $state"
|
|
all_passed=false
|
|
failed_checks="$failed_checks $check_pattern($state)"
|
|
fi
|
|
done
|
|
|
|
if [ "$all_passed" != "true" ]; then
|
|
echo " ⏭️ Skipping - CI not passed:$failed_checks"
|
|
skip_count=$((skip_count + 1))
|
|
continue
|
|
fi
|
|
|
|
# CI 全部通过,执行合并
|
|
echo " 🚀 All CI checks passed, merging..."
|
|
RESULT=$(curl -s -X POST \
|
|
-H "Authorization: token $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
"$GITEA_API/repos/$REPO/pulls/$number/merge" \
|
|
-d '{"Do": "merge"}')
|
|
|
|
if echo "$RESULT" | python3 -c "import json,sys; d=json.load(sys.stdin); sys.exit(0 if d.get('merged', False) or 'id' in d else 1)" 2>/dev/null; then
|
|
echo " ✅ PR #$number merged successfully"
|
|
merge_count=$((merge_count + 1))
|
|
else
|
|
echo " ❌ PR #$number merge failed"
|
|
# 提取错误信息
|
|
err_msg=$(echo "$RESULT" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('message', str(d)[:200]))" 2>/dev/null)
|
|
echo " Error: $err_msg"
|
|
fi
|
|
done
|
|
|
|
echo ""
|
|
echo "=== Done ==="
|
|
echo "Merged: $merge_count | Skipped: $skip_count"
|