ci: M147 给两个平台的 test 步加取证能力(--no-fail-fast + 注解 + 退出码回显)
三条红里 `test (windows)` 至今只有一个「Process completed with exit code 1」——而 cargo
自己的失败码是 101,那个 1 的来源不明(pwsh 包装层洗码 / 进程被杀,两说都未排除)。job log
要登录才能读(匿名 403),但**注解匿名可读**(GET /check-runs/<id>/annotations → 200)。
所以把一条 `cargo test --workspace --all-targets` 拆成两个平台的取证版本,各做三件事:
1. `--no-fail-fast`:cargo 默认第一个失败的 target 就停(M144 实测 Linux 只跑了 7 个 test
binary 就退),后面还有没有第二条失败完全看不到;
2. 失败时把 `error` / `failures:` / `test result: FAILED` / panicked 行升成 `::error::`
注解(`%` 转 `%25`,那是 workflow command 的保留字符)——拿不到 job log 时注解是匿名
侧唯一能取到的失败正文;
3. 显式 `echo "cargo exit=<code>"`,把「包装层把码洗成 1」「cargo 真失败(101)」「进程被杀
只给码、零诊断」三种情形分开。
两平台的码从哪来(不能混用):
- Linux 走 bash(默认 shell 带 `-e` + `pipefail`):先 `set +e` 再自己取 `${PIPESTATUS[0]}`
——那是 cargo 的码,不是 `tee` 的码;不关 `-e` 的话管道一失败就在 tee 之后退出,后面三行
永远跑不到。
- Windows 走 pwsh:`PIPESTATUS` 是 bash 语法,改用 `$LASTEXITCODE`(`Tee-Object` 是 cmdlet,
不会改它)。注解的正则不锚 `error:` 那一支,因为 pwsh 把原生 stderr 折成 ErrorRecord 后
行首可能多一截前缀,锚死会漏行。
两条都以 `exit <code>` 结尾,退出码不再经过管道传递。
This commit is contained in:
1 parent
8bfabafe8a
commit
ae1410f342
1 file changed
+49
-1
@@ -132,7 +132,55 @@ jobs:
|
||||
# 同 clippy:`--workspace` 不含 `unlucky-app`(M118),Slint 退役树不再被 `--all-targets` 拉起。
|
||||
# 也因此**不要**再写 `--exclude unlucky-app`:它已不是成员,那面旗子只会打一条
|
||||
# `excluded package(s) … not found in workspace` 的警告然后空转(实测 exit 0,不报错)。
|
||||
- run: cargo test --workspace --all-targets
|
||||
#
|
||||
# ---- 取证(M147):下面是同一件事的两个平台版本,不是两条不同的测试 ----
|
||||
# M144 的三条红里两条已在 docker 里定位到行,第三条 `test (windows)` 在 run 里只留下
|
||||
# `Process completed with exit code 1`——而 cargo 自己的失败码是 **101**,所以那个 1 的
|
||||
# 来源不明(包装层洗码 / 进程被杀,两说都未排除)。job log 要登录才能读(匿名 403),
|
||||
# 但**注解匿名可读**(`GET /check-runs/<id>/annotations` → 200,M144 实证)。所以这三件
|
||||
# 事各自对准一种「看不见」:
|
||||
# 1) `--no-fail-fast`:cargo 默认在第一个失败的 target 就停(M144 实测 Linux 只跑了
|
||||
# 7 个 test binary 就退出),后面还有没有第二条失败完全看不到;
|
||||
# 2) 把 `error` / `failures:` / panicked 行升成 `::error::` 注解:拿不到 job log 时,
|
||||
# 注解是匿名侧唯一能取到的失败正文;
|
||||
# 3) 显式打印 cargo 的退出码:把「包装层把码洗成 1」「cargo 真失败(101)」「进程被杀
|
||||
# 只给码、零诊断」三种情形分开——这正是 M144 没定的那一半。
|
||||
- name: cargo test --workspace --all-targets(ubuntu,失败升注解)
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
log="$RUNNER_TEMP/cargo-test.log"
|
||||
# 默认 shell 带 `-e` + `pipefail`:管道里 cargo 一失败就会在 tee 之后立刻退出,
|
||||
# 下面三行永远跑不到。所以这段先关 `-e`,自己取 `PIPESTATUS[0]`(cargo 的码,
|
||||
# 不是 tee 的码)。
|
||||
set +e
|
||||
cargo test --workspace --all-targets --no-fail-fast 2>&1 | tee "$log"
|
||||
code=${PIPESTATUS[0]}
|
||||
set -e
|
||||
echo "cargo exit=$code"
|
||||
if [ "$code" -ne 0 ]; then
|
||||
# `%` 是 workflow command 的保留字符,要转成 `%25`,否则注解正文会被截断。
|
||||
grep -E '^(error(\[E[0-9]+\])?:|failures:|test result: FAILED|thread .* panicked at| *--> )' "$log" \
|
||||
| head -40 | sed 's/%/%25/g; s/^/::error::/' || true
|
||||
fi
|
||||
exit "$code"
|
||||
- name: cargo test --workspace --all-targets(windows,失败升注解)
|
||||
if: runner.os == 'Windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
# pwsh 没有 PIPESTATUS(那是 bash 语法):拿 `$LASTEXITCODE` —— Tee-Object 是 cmdlet,
|
||||
# 不会把它改掉,所以它是 cargo 自己的码。
|
||||
$log = Join-Path $env:RUNNER_TEMP 'cargo-test.log'
|
||||
cargo test --workspace --all-targets --no-fail-fast 2>&1 | Tee-Object -FilePath $log
|
||||
$code = $LASTEXITCODE
|
||||
Write-Host "cargo exit=$code"
|
||||
if ($code -ne 0) {
|
||||
# 正则不锚 `error:` 那一支:pwsh 把原生 stderr 折成 ErrorRecord 后行首可能多一截前缀,
|
||||
# 锚死会漏行;`%` 是 workflow command 的保留字符,转成 `%25`。
|
||||
Select-String -Path $log -Pattern '(error(\[E\d+\])?:|^failures:|test result: FAILED|thread .* panicked at|^\s+--> )' |
|
||||
Select-Object -First 40 |
|
||||
ForEach-Object { Write-Host "::error::$($_.Line.Replace('%', '%25'))" }
|
||||
}
|
||||
exit $code
|
||||
|
||||
build:
|
||||
name: build release (${{ matrix.os }})
|
||||
|
||||
Reference in new issue
Block a user