fix(ci): preserve npm install diagnostics and classify forced timeout
This commit is contained in:
+22
-2
@@ -2509,9 +2509,9 @@
|
||||
|
||||
## BUG-149 | staging quality gate npm ci 缺少安装级 deadline 导致 45 分钟黑洞
|
||||
|
||||
- 状态:resolved(local candidate,远端 gate/deploy 待本提交)
|
||||
- 状态:investigating(2026-09-26 安装卡住复发;既有 deadline 生效,底层卡点待 runner 证据)
|
||||
- 首次发现:2026-08-09
|
||||
- 最近更新:2026-08-09
|
||||
- 最近更新:2026-09-26
|
||||
- 影响面:Gitea staging quality gate 的依赖安装阶段、`manman-linux` runner 与 Gitea/runner 控制面可用性;测试、lint、build、exact-SHA checkout/publish/deploy 合同未改变。
|
||||
- 用户现象:Run 1618(SHA `ffbe505c`)在 Python pip 完成后进入 digest-pinned Node 容器执行 `npm ci`;步骤无后续 npm 输出,直到 45 分钟 job timeout,publish/deploy skipped。
|
||||
- 触发条件:self-hosted runner 在受限 Node 容器中执行 frontend `npm ci`,但安装命令本身没有 fail-closed deadline,npm registry/fetch 也没有比 job-level 更短的诊断边界。
|
||||
@@ -2523,6 +2523,26 @@
|
||||
- 复发自:无
|
||||
- 修复版本:待本次提交 / gate / deploy
|
||||
|
||||
### 2026-09-26 诊断补充(未修改 workflow / 未重跑部署)
|
||||
|
||||
- 版本:远端 staging 与隔离诊断 worktree 均为 `40d7930ab4c8c44e504f3a6caaee351ed262f172`。Gitea run `2937`(显示序号 `1522`)、job `6464` 在 `xiaoxin` runner 的 `Install dependencies` 失败;Python pip 成功,测试步骤与 publish 跳过。
|
||||
- 原始错误:`frontend npm ci failed with status 137 inside bounded Node container`。npm 最后一条警告时间为 `2026-09-26T08:28:41.857Z`,失败时间为 `08:44:11.716Z`,约 930 秒,吻合现有 `timeout --signal=TERM --kill-after=30s 900s`。本地 GNU timeout 缩时验证:子进程忽略 TERM 后被 KILL,退出码确为 137。直接退出路径高度符合超时强杀,但仅凭该退出码不能证明或排除 runner OOM。
|
||||
- 对照:此前成功 run `2934` / job `6456` 在 `07:05:36Z` 输出 `added 859 packages in 40s`。两次的 workflow、`frontend/package.json` 与 lockfile 完全相同;两次都出现 `posthog-node@5.41.0` 要求 Node `^20.20.0 || >=22.22.0`、实际 `22.16.0` 的 EBADENGINE 警告,因此不能把该警告认定为本轮直接失败原因。
|
||||
- 历史防线:900 秒安装 deadline、资源上限与 fetch timeout 均仍存在,阻止了旧 45 分钟黑洞;workflow 仅对 124 输出超时专用文案,137 落入通用失败分支。既有 `staging-backend-workflows.test.ts` 只锁定命令文本与边界,未验证 TERM 不退出后 137 的诊断语义,也不能防止外部安装链路卡住。
|
||||
- 未证实部分:npm 下载/解压/postinstall 的具体卡点及内存/PID 状态。容器使用 `--rm`,npm 日志位于容器 HOME `/tmp` 且未持久化;现有 Actions 日志不足以区分镜像网络、安装脚本或资源问题,不虚构具体故障包。
|
||||
- 后续最小排查:由产品负责人授权后,为安装容器持久化 npm debug 日志并保留退出/OOM 证据,在相同 SHA 重跑;不要仅调大超时或禁用安装脚本。Node engine 版本告警需另行对齐,不冒充本轮根因修复。
|
||||
- 运行态:只读健康检查返回 `status=ok`,web/API SHA 均为此前成功版本 `f74825a27cca881af3373eb0c77f8f52135da378`,本轮最新代码未部署。未执行 push、migration 或 workflow dispatch。
|
||||
|
||||
|
||||
### 2026-09-26 本地诊断修补(未推送 / 未部署,原始卡死仍 investigating)
|
||||
|
||||
- 授权与范围:产品负责人要求修复上述 workflow;仅修改 backend quality gate 的 npm 安装诊断及其回归,不升级 Node、不更换 registry、不增加重试、不放宽 900 秒 deadline 或 CPU/memory/PID 边界。
|
||||
- 已确认缺陷:GNU timeout 的 TERM 后强杀可能返回 137,旧分支只识别 124;`--rm` 和容器内临时 HOME 丢失 OOM 状态及 npm debug 日志。它们是诊断缺陷,不是已证实的 npm 卡死根因。
|
||||
- 本地修补:使用独占 cidfile 和 EXIT trap 清理本次容器;先读取 `State.OOMKilled`,只有 124 或「137 + timeout 实际发送信号的日志」才报告超时,OOM/未知失败仍 fail closed。用 `PIPESTATUS[0]` 保留 Docker 的失败码,不让 tee 掩盖失败。mode-0700 临时目录挂载 npm debug 日志并保存安装输出,成功删除、失败保留在 runner 本地;日志未经脱敏不发布。开启 foreground scripts 与 HTTP 进度用于定位下载或 postinstall 卡点。
|
||||
- 回归:直接提取 workflow 中的安装 shell,以 Docker stub 执行成功、124、强杀 137、OOM 137、未知 137、容器启动失败 125 六种场景,验证分类、退出码、日志保留与定向清理。修补前强杀场景复现通用 137 失败,修补后通过;使用主 checkout 的 Python venv 提供 PyYAML,`node --test frontend/tests/staging-backend-workflows.test.ts` 为 44/44 passed;`bash -n` 与 `git diff --check` 通过。系统 Python 缺 PyYAML 的首次检查失败属于本机工具环境,不是 workflow YAML 错误。
|
||||
- 真实容器验证:本机 Docker Linux/amd64 使用 CI 同一 pinned Node 镜像、同一 lockfile 和资源限制,修改后安装 shell 成功安装 859 包(约 2 分钟)。将验证副本的期限缩至 1 秒 + 1 秒、命令替换为忽略 TERM 的进程,真实 Docker 返回 137、`OOMKilled=false`,workflow 报告超时并返回 124;容器由 trap 删除。此人为强杀实验只验证退出诊断,不复现 npm 卡死。
|
||||
- 剩余边界:本机无法复现 xiaoxin 的原始卡死;未在真实 runner 验证修补版本,未执行 push、workflow dispatch、migration 或 deploy。BUG-149 保持 investigating,下一步是获准推送后以新 SHA 的 runner 日志判断下载、安装脚本或资源卡点,不能将本次诊断修补称为安装问题彻底解决。
|
||||
|
||||
## BUG-150 | staging publish 的 Webpack 镜像构建耗尽共享 Gitea 资源
|
||||
|
||||
- 状态:resolved(local candidate,远端 gate/deploy 待本提交)
|
||||
|
||||
Reference in New Issue
Block a user