diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9e97b15..c04f1b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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//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 }})