Files
HomeAgent/.github/workflows
JianFeeeee 1aec7688a6 ci: 加固 C 门禁 —— 卡死不再拖满超时,且缺工具不再假装通过
## 两个独立问题

### ① 卡死:20 分钟全花在 apt-get,不是门禁

实测证据:本机 `make check-csrc` 五个子门禁**各自 0~1 秒**:

    csrc-lint 1s / csrc-abi 0s / csrc-headers 0s / csrc-sanitize 0s / csrc-cross 0s

而 CI 里同一个 job 两次跑到 20 分钟 job 级超时(其中一次直接 cancelled)。
卡死点只可能在 `apt-get update` —— ubuntu-latest runner 上偶发挂住不返回,
既不失败也没进展,只能等 job timeout,而报错信息毫无指向性。

### ② 假通过:缺工具时门禁 `[SKIP] ... exit 0`

这是更危险的一个。Makefile 里每道门禁在缺依赖时:

    if ! command -v $CC_ARM64 >/dev/null 2>&1; then
        echo "  [SKIP] $CC_ARM64 不存在(未装交叉工具链)"; exit 0
    fi

本机这样合理(开发者未必装交叉工具链),但在 CI 里意味着:apt-get 悄悄失败
⇒ 五道门禁全部跳过 ⇒ **job 绿** ⇒ 让人以为 C 侧有门禁,实际一个都没跑。

**静默降级比红更危险:红会有人修,绿没人看。**

实测确认(`CC_ARM64=nonexistent-gcc-xyz make csrc-cross`):

    == C 侧交叉编译(linux/arm64)==
      [SKIP] nonexistent-gcc-xyz 不存在(未装交叉工具链)
    --- 退出码: 0 ---        ← 这就是问题

## 加固内容

| 措施 | 作用 |
|---|---|
| 逐包检查是否已安装 | runner 镜像通常自带 cmake/clang ⇒ **多数情况完全不碰网络** |
| apt-get 自带 `Acquire::*Timeout=60` + `Retries=3` | 卡住时自身失败,而不是拖到 job 级超时(后者报错无指向性) |
| 装包 step `timeout-minutes: 6` | 双保险 |
| 新增「确认工具链齐备」步骤 | 缺任一工具 ⇒ 红,并 `::error::` 说明"缺工具时门禁会 SKIP 等于假装通过" |
| 跑门禁 step `timeout-minutes: 5` | 门禁实测 0~1 秒,超出即异常(不是慢) |
| `grep '\[SKIP\]'` 二次拦截 | 覆盖将来新增门禁时漏配依赖的情况 |
| job `timeout-minutes` 20 → 15 | 已经是纯 apt-get 余量 |

## 为什么要两道 SKIP 拦截

「确认工具链齐备」+「grep [SKIP]」看似重复,其实针对不同风险:

- 前者:**当前**三道门禁的依赖齐不齐
- 后者:**将来**新增门禁时,新依赖没写进安装步骤 —— 那时前者不知道要检查它,
  只有日志里的 `[SKIP]` 能抓到

## 本地实测(逐条验证,不是只改完就推)

| 验证 | 结果 |
|---|---|
| YAML 可解析 | ✅ |
| 三件套本机齐备 | ✅ cmake / clang / aarch64-linux-gnu-gcc |
| `make check-csrc` 无 SKIP | ✅ 五门禁全实际执行 |
| 已装则跳过 apt-get 分支 | ✅ 「三件套已存在,跳过 apt-get」 |
| 部分缺失时拼装需要安装列表 | ✅ 正确识别出 `clang` |
| **变异:交叉工具链缺失** | ✅ grep 拦截生效(若不加这层,CI 会绿) |
2026-10-22 23:39:21 +08:00
..