diff --git a/.gitea/workflows/pr-automation.yml b/.gitea/workflows/pr-automation.yml index ad33e1627..e509ebf42 100644 --- a/.gitea/workflows/pr-automation.yml +++ b/.gitea/workflows/pr-automation.yml @@ -18,7 +18,7 @@ jobs: name: Auto Approve on CI Green runs-on: ci-check if: github.event_name == 'pull_request' && !github.event.pull_request.draft - timeout-minutes: 3 # 长等待模式:等CI全绿后自动合并,不遗漏任何PR + timeout-minutes: 10 # 等待CI全绿+审批,需要充足时间 steps: - name: Checkout code shell: sh @@ -61,7 +61,8 @@ jobs: name: Auto Merge on CI Green + Approved runs-on: ci-check if: github.event_name == 'pull_request' && !github.event.pull_request.draft && github.event.pull_request.base.ref == 'develop' - timeout-minutes: 3 # 短作业模式:检查一次,不满足就退出,由pr-auto-scan每5分钟定时兜底 + needs: [auto-approve] # 修复竞态:必须等审批完成后再尝试合并 + timeout-minutes: 15 # 等待审批+CI就绪+合并,需要充足时间 steps: - name: Checkout code shell: sh diff --git a/scripts/ci/auto_merge.sh b/scripts/ci/auto_merge.sh index bcf7747ab..9a4b74f66 100755 --- a/scripts/ci/auto_merge.sh +++ b/scripts/ci/auto_merge.sh @@ -32,9 +32,9 @@ CONTEXTS=( echo "检查CI Gate统一门禁" echo -# 等待60秒,给CI启动写status的时间 -echo "等待60秒让CI启动..." -sleep 60 +# 等待30秒后开始轮询,最多10分钟 +echo "等待30秒让CI启动..." +sleep 30 # 405计数器(单次运行内重试) MERGE_405_COUNT=0 @@ -72,9 +72,9 @@ check_and_merge() { # CI未全绿(pending中)→ 退出,等下次触发 if [ "$ALL_SUCCESS" != "true" ]; then echo - echo "⏳ CI尚未全绿(仍有pending),退出等待下次触发" - echo " (pr-auto-scan每5分钟扫描一次,CI通过后会自动合并)" - exit 0 + echo "⏳ CI尚未全绿(仍有pending),等待重试..." + echo " (当前第${attempt}次轮询,最多${MAX_ATTEMPTS}次)" + return 1 fi # CI全绿 → 合并 @@ -136,13 +136,28 @@ check_and_merge() { fi } -# 最多重试3次(用于405重试,非CI轮询) -for i in 1 2 3; do +# 轮询等待CI就绪+审批完成,最多10分钟(60次x10秒) +MAX_ATTEMPTS=60 +for attempt in $(seq 1 $MAX_ATTEMPTS); do if check_and_merge; then exit 0 fi + + # 检查PR是否还open(可能已被手动合并或关闭) + PR_STATE=$(curl -s -H "Authorization: token ${MERGE_TOKEN}" \ + "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}" \ + | python3 -c "import sys,json; print(json.load(sys.stdin).get('state',''))" 2>/dev/null || echo "?") + + if [ "$PR_STATE" != "open" ]; then + echo "PR状态为 ${PR_STATE},无需继续等待" + exit 0 + fi + + if [ $attempt -lt $MAX_ATTEMPTS ]; then + sleep 10 + fi done echo -echo "本次检查未满足合并条件,退出。pr-auto-scan每5分钟会继续扫描。" +echo "⏰ 等待10分钟后仍未满足合并条件,退出。pr-auto-scan定时扫描会继续重试。" exit 0 diff --git a/tests/unit/test_generation_cover.py b/tests/unit/test_generation_cover.py index 1398c5cba..e7065b34d 100644 --- a/tests/unit/test_generation_cover.py +++ b/tests/unit/test_generation_cover.py @@ -707,9 +707,9 @@ class TestStrayLoggerRemoved: source = inspect.getsource(generation_cover) # The stray call was logger.info(\n plan_id,\n generation_task_id,\n) # with no format string — should not exist - assert "logger.info(\n plan_id," not in source, ( - "Stray logger.info(plan_id, generation_task_id) should be removed" - ) + assert ( + "logger.info(\n plan_id," not in source + ), "Stray logger.info(plan_id, generation_task_id) should be removed" class TestUploadCoverType: