Skip to content

ci: 缩短 CI 关键路径执行时长(实测 12.5min → ~9min) #110

@membphis

Description

@membphis

背景

实测最近一次 ci.yml(run 26703086677,main)各 job 起止偏移(秒,从 run 创建算起):

0    77   194  257            303                              751
■ Lua lint 11s
■■ Sanitizers 77s
■■■■■■ Supply-chain audit 194s
■■■■■■■ Rust tests (ubuntu) 228s
■■■■■■■■ Rust tests (macos-14) 257s   ◀─ needs:rust 的“门”
■■■■■■■■■■ Fuzz regression guard 301s
              └ 门开(259s) ┬ OpenResty ×3 / package ×2 / Lua(OpenResty) ≤70s 并行收工
                          └ Lua (upstream LuaJIT) 492s ━━━━━▶ 751s

总 wall-clock = 751s ≈ 12.5min。关键路径 = rust-macos 门(257s)→ lua-upstream(492s)。其余 job 都在 303s 前并行收工,不在关键路径上。

492s 的 Lua integration tests (upstream LuaJIT)同一个 job 内串行做了:cargo buildbustedvalgrind 全套 memcheck(关 JIT,最慢,约 420s)luarocks make → 再跑一遍 busted。valgrind 占大头。

设计约束(已与维护者确认):valgrind 必须保留在每次 PR(不移 cron)——担心单个 PR 引入的内存错误漏到 main;并且要改为阻塞门禁(去掉当前的 continue-on-error),让带内存错误的 PR 直接 CI 失败。不采用分片

在这两条约束下,把 valgrind 拆成独立并行 job 后,它就是关键路径上约 540s 的唯一高杆;rust 门、fuzz、audit、其它 Lua/OpenResty job 全部落在其下、不再影响 wall-clock。因此本 Issue 的关键路径优化只剩 valgrind 解耦这一件事;共享 artifact / fuzz corpus / audit 预编译 / rockspec 去重在此约束下均为 minutes-only,归入姊妹 Issue #111

目标

把每次 PR 的 CI wall-clock 从实测 ~12.5min 降到 ~9min:valgrind 保留每次 PR 全套运行、并改为阻塞门禁,但从串行链 + rust-macos 门中解耦为独立并行 job,使它不再串在 492s 链尾、也不再等 macos 门。覆盖不减反增(变阻塞)。

范围外(Non-goals)

  • 把 valgrind 移到 cron——明确否决,必须每次 PR 跑。
  • valgrind 分片到 matrix——本 Issue 不做(若日后要从 ~9min 进一步压到 ~5min 再单开 Issue)。
  • 共享 build 产物、fuzz corpus 重放、audit 预编译、rockspec 去重——在 valgrind 高杆下均为 minutes-only,不影响 wall-clock,归入 ci: 削减 CI 冗余与噪音(不影响 wall-clock) #111

验收标准

  • 改动后典型 PR 的 ci.yml wall-clock ≤ ~10min(以实测 run 时长为准)。
  • valgrind 全套 memcheck 仍在每次 PR 运行,覆盖与现在等同或更强。
  • valgrind 作为独立并行 job 运行,不再串在 lua-upstream 的 492s 链尾、不再等 rust-macos 门。
  • valgrind 去掉 continue-on-error:PR 引入的内存错误会让 CI 失败、阻塞合并。
  • 关键路径不再包含 rust-macos 门 → lua-upstream 的串行链。
  • 全部现有 Rust + Lua 测试继续通过。

任务清单

每项标注关键路径 Δ(对 751s wall-clock 的预估影响;正为缩短)。

1. valgrind 解耦为独立并行 job(Δ ≈ −210s,751s→~540s)

  • 1.1 把 valgrind memcheck 从 lua upstream job 内的串行步骤抽出,独立成 job
  • 1.2 该 job 只依赖编译产物(自建 libqjson.so,或复用 ci: 削减 CI 冗余与噪音(不影响 wall-clock) #111 的共享 artifact),不 needs: rust,与常规 busted 并行启动
  • 1.3 保留现有 valgrind 参数与 valgrind.supp,仍跑全套 tests/lua(覆盖不减)

2. valgrind 改为阻塞门禁

3. 验证

  • 3.1 触发一次完整 CI,记录新 wall-clock 与各 job 时长,确认关键路径不再是串行链、总时长 ≤ ~10min
  • 3.2 构造一个故意的内存错误 PR(或本地复现),确认 valgrind job 现在会 fail

备注 / 决策

  • 数据来源:gh run view 26703086677。GitHub Actions wall-clock = 关键路径,而非各 job 之和。
  • 约束「valgrind 留 PR + 阻塞 + 不分片」下,valgrind(~540s)成为唯一高杆,其它候选优化均落其下 → 移入 ci: 削减 CI 冗余与噪音(不影响 wall-clock) #111 作 minutes-only 处理。
  • 若日后要从 ~9min 进一步压到 ~5min:valgrind 分片到 matrix 并行跑全套(覆盖不变)是下一步杠杆,届时 fuzz/audit/artifact 才重新进入关键路径——单开 Issue 跟踪。
  • 姊妹 Issue:ci: 削减 CI 冗余与噪音(不影响 wall-clock) #111(削减 CI 冗余与噪音,不影响时长;含共享 artifact、fuzz corpus、audit 预编译、rockspec 去重等 minutes-only 项)。

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions