修复(CI追绿·fix-ci-obs续): run_all套件执行器平台分派——Windows cmd.exe形态逐位保留(/V:ON延迟展开+ERRORLEVEL落盘+taskkill树杀),POSIX新支(/bin/sh -c同步串行:引擎退出再落$?,create_process拿sh pid供存活轮询;截止杀pkill -P子进程先于kill父防孤儿); 根因=run15远端77套件全数秒死(24/18/18/17四分片)=cmd.exe在mac不存在create_process失败pid<0逐套件判红; Windows回归单套验证绿+S9/gdstyle绿

This commit is contained in:
DKChan committed 2026-11-03 08:22:55 +08:00
1 parent 574f202405
commit 03d53b1fc4
1 file changed
+17 -3
+17 -3
View File
@@ -279,9 +279,18 @@ func _run_suite(suite: Dictionary, idx: int, filtered: bool = false) -> Dictiona
DirAccess.make_dir_recursive_absolute(proj + "/tests/.gates")
# /V:ON=延迟展开:!ERRORLEVEL! 到 echo 执行时(套件已退出)才取值;
# 延迟展开会吞字面 !,命令串各段(引擎路径/工程路径/套件路径/日志路径)不得含 !。
var cmd := '"%s" --headless --path "%s" --script "%s" > "%s" 2>&1 & echo !ERRORLEVEL! > "%s"' % [bin, proj, path, log, codefile]
var pid: int = -1
var out := PackedStringArray()
var pid: int = OS.create_process("cmd.exe", PackedStringArray(["/V:ON", "/C", cmd]))
if OS.get_name() == "Windows":
# Windows 形态(原实现逐位保留):/V:ON 延迟展开,!ERRORLEVEL! 到 echo 时(套件已退出)才取值;
# 延迟展开会吞字面 !,命令串各段(引擎路径/工程路径/套件路径/日志路径)不得含 !。
var cmd := '"%s" --headless --path "%s" --script "%s" > "%s" 2>&1 & echo !ERRORLEVEL! > "%s"' % [bin, proj, path, log, codefile]
pid = OS.create_process("cmd.exe", PackedStringArray(["/V:ON", "/C", cmd]))
else:
# POSIX 形态(mac/Linux runner):/bin/sh -c 同步串行——sh 前台等引擎退出再落 $?,
# 无延迟展开问题;create_process 拿 sh 的 pid(存活轮询=sh 前台等待期),截止杀走 kill 树。
var sh_cmd := '"%s" --headless --path "%s" --script "%s" > "%s" 2>&1; echo $? > "%s"' % [bin, proj, path, log, codefile]
pid = OS.create_process("/bin/sh", PackedStringArray(["-c", sh_cmd]))
if pid < 0:
push_error("[run_all] FAIL %s — cmd 子进程启动失败(pid=%d)" % [path, pid])
return {"fail": 1, "timed_out": false}
@@ -299,7 +308,12 @@ func _run_suite(suite: Dictionary, idx: int, filtered: bool = false) -> Dictiona
var negative := bool(suite.get("negative", false))
if timed_out:
var kill_out := PackedStringArray()
OS.execute("taskkill", PackedStringArray(["/F", "/T", "/PID", str(pid)]), kill_out, true)
if OS.get_name() == "Windows":
OS.execute("taskkill", PackedStringArray(["/F", "/T", "/PID", str(pid)]), kill_out, true)
else:
# POSIX:先杀 sh 的直接子进程(引擎),再杀 sh 自身(顺序要紧——先杀父会让子成孤儿续跑)
OS.execute("pkill", PackedStringArray(["-9", "-P", str(pid)]), kill_out, true)
OS.execute("kill", PackedStringArray(["-9", str(pid)]), kill_out, true)
# taskkill 落刀到进程对象消失有间隔:等死确认再放行下一套件(10s 宽限),
# 确认不了也如实报红留 PID 供手工清杀,不静默放行。
var reap_deadline := Time.get_ticks_msec() + 10000