CI 里更新 DeepSeek Harness 与 DSH plugin:非交互、锁版本与缓存
CI 里更新 DeepSeek Harness 与手工更新是两件事:没有交互终端(提示一出现就挂死)、要求可复现(版本不能自己漂)、要求快(每次重装的时间会被乘以构建次数)。 所以正确的做法不是把手工命令原样塞进 YAML,而是先选一种「版本从哪来」的方案(钉版本 / 跟随最新 + 快照 / 镜像承载),再补上非交互与失败即退出的写法,最后把缓存接上。DSH plugin 在 CI 里还多一层:它们的版本也要一起钉,否则本体锁住了、插件却飘,问题照样复现不了。
CI 里更新 DeepSeek Harness 和手工更新差在哪:三种方案
一句话结论:差别只有三条——没有终端、不能容忍版本随机、时间成本被放大;三条都指向同一件事:把版本变成显式输入。
| 维度 | 手工更新 | CI 里更新 |
|---|---|---|
| 交互 | 可以按提示选 | 任何提示都会导致挂起 |
| 版本 | 允许跟随最新 | 必须钉住或记录快照 |
| 时间 | 只花一次 | 每次构建都要花 |
| 失败可见性 | 你盯着终端 | 只有日志与退出码 |
方案 A:钉版本安装 / 升级(可复现,推荐)
一句话结论:把本体与 DSH plugin 的版本都写死在配置里,升级 = 改版本号并提交——这是唯一能回答「这次跑的是哪一版」的方案。
- 本体钉版本安装:
npm i -g @deepseek-ai/dsh@0.2.0-rc.2
dsh --version # 预期:与钉住的版本一致
- 插件清单也钉版本,写成一个可执行的清单文件(示例):
# plugins.txt 每行一个「包名@版本」
dsh plugin add <插件包名>@<版本>
- 升级是一个显式动作:改版本号 → 提交 → 流水线重跑;不要在 CI 里写「永远装最新」。
- 保留验证过的组合记录:本体版本 + 插件版本写成一行,回退时照抄上一行即可(这一点在 多台机器统一更新 DeepSeek Harness 里同样适用)。
方案 B:跟随最新 + 记录快照(跟随型)
一句话结论:确实需要「总跑最新」时,也要把这次实际拿到的版本打印并归档——把不可复现换成可追溯。
- 安装最新版,但立即记录实际版本:
npm i -g @deepseek-ai/dsh
dsh --version | tee version.txt # 归档进构建产物
- 把快照当构建结果的一部分:版本文件、已装 DSH plugin 清单都留档,出问题能比对「上次绿的时候是什么版本」。
- 配一个告警:版本变化时通知(而不是静默跟随),让「上游发新版」这件事可见。
- 取舍说明:这条方案放弃了可复现,换取了「第一时间发现兼容问题」——适合你本来就在跟踪上游节奏的仓库。
方案 C:用镜像承载版本(CI 最省时)
一句话结论:把本体与常用 DSH plugin 预置进自建镜像,流水线只拉镜像——版本天然钉住,安装时间基本归零。
- 镜像里钉版本 + 预置插件(写法见 DeepSeek Harness 容器化安装 的方案 C)。
- CI 直接用镜像跑测试,不再安装:少了下载与编译,构建时间稳定。
- 升级 = 构建新镜像并推私有仓库,旧镜像留作回退点——这比改脚本里的版本号更容易回滚。
- 注意缓存与卷:流水线里把数据目录设成临时目录(跑完即弃),避免把上一次的会话状态带进这次测试。
DSH plugin 在 CI 里的非交互与「失败即退出」:三种写法
一句话结论:非交互靠三件事——显式的环境变量、不触发输入的参数、以及超时兜底;失败即退出靠 set -e 与显式判断退出码。
- 写法一:显式声明非交互环境(示例):
export CI=true
set -euo pipefail # 任一命令失败即终止,避免带病继续
- 写法二:命令层面避免交互:不要使用会提问的参数(例如交互式确认、编辑器型参数);需要「全自动」时优先用具确定性输入的等价形式。
- 写法三:超时兜底,防止挂死整条流水线:
timeout 900 npm i -g @deepseek-ai/dsh@0.2.0-rc.2
# 预期:超时后以非零码退出,流水线立刻失败而不是卡住
- 别忽略退出码:把「安装」与「校验」分成两步,校验失败也要让流水线红——只装不验等于没测。
DeepSeek Harness CI 缓存与提速:三种做法
一句话结论:缓存按收益排序是「镜像 > 包缓存 > 按哈希跳过安装」;能上镜像就上镜像。
- 镜像预置(收益最大):本体与高频 DSH plugin 都在镜像里,运行阶段零安装。
- 缓存 npm 缓存目录,用锁文件或清单哈希做缓存键:
# 伪代码示意:缓存键由清单文件哈希构成
key: dsh-${{ hashFiles('plugins.txt', 'package-lock.json') }}
- 按哈希跳过安装:清单没变就不重装,只做校验(快但要小心「缓存里是坏产物」的情况,定期清理一次)。
- 代理与镜像源:内网流水线记得把 registry 指到私有源,否则每次都在公网拉(见 离线与内网里用 npx @deepseek-ai/dsh web)。
跑完必须做的版本与 DSH plugin 校验
一句话结论:安装退出码为 0 不等于升级成功——必须验证「版本对不对、插件齐不齐、服务能不能起」。
- 版本校验:打印
dsh --version与实际可执行路径,和预期比对。 - 插件清单校验:列出已装列表并核对数量与版本;数量少了说明有插件没装上。
- 冒烟校验:起一次服务并确认端口可访问(
dsh web起得来即最小可用)。 - 留档:把上面三项的输出写进构建产物,出问题时有据可查。
- 顺手看数据目录:CI 里
DSH_HOME指向临时目录更干净,避免状态污染下次构建。

DSH plugin CI 排查注意事项
一句话结论:CI 里的失败先分「挂死」与「报错」两类——挂死几乎都是交互提示,报错才去看版本与源。
- 挂死→ 查是否有交互提示、是否缺
CI=true、是否缺超时兜底。 - 装不上→ 查源与包名版本是否存在(内网还查私有源是否同步)。
- 版本没变→ 检查是不是装到了另一个入口(全局 vs npx),这与 npx 与全局混装的版本漂移 同源。
- 插件缺→ 逐项核对清单,而不是重试。
- 偶发失败→ 先怀疑缓存命中了坏产物,清缓存重跑一次定位。
- 修复状态如实:本文方案基于 npm 可复现安装机制与官方 CLI 的升级/插件子命令说明;
dsh具体参数名以流水线里dsh --help的输出为准,DeepSeek Harness 迭代较快,建议把版本号与参数一起写进仓库文档。
CI 里要装的插件清单,先在 DSH Plugin Hub 里敲定再写进流水线配置,比在流水线里边翻边装可靠得多。
来源:apps/cli/README.md、npm Docs · npm ci、npm @deepseek-ai/dsh。
常见问题
在 DeepSeek Harness 里,交互式提示在无终端的流水线里不会有人回答,进程就挂住了。避免要点有三条:安装/升级时显式带上非交互与环境变量(例如把持续集成环境变量设为真)、不使用需要输入的参数、并在命令前加超时兜底。DeepSeek Harness 的具体参数以你运行的 dsh --help 输出为准。
在 DeepSeek Harness 里,因为流水线要的是可复现:不钉版本时,今天绿的构建明天可能因为上游发了新版本而红,排查成本很高。钉版本让你能明确回答「这次跑的是哪一版」,回滚时也有确定的落点;升级应当是显式动作,而不是自动跟着最新走。
三条:把包缓存目录(npm 缓存)在流水线里缓存起来复用;把 DeepSeek Harness 本体与常用 DSH plugin 预置在自建镜像里,运行阶段直接启动;以及只在依赖清单变化时才重新安装(用锁文件或哈希做缓存键)。三者可以叠加,镜像方案收益最大。
三条校验:打印 dsh --version 与实际解析到的可执行路径、确认版本与预期一致;列出已装 DSH plugin 清单并核对数量与版本;跑一个最小功能冒烟(例如启动 dsh web 并确认端口可访问)。只看安装命令的退出码不够——退出码为 0 但版本没变也是常见情况。
在 DeepSeek Harness 里,因为版本是钉住的,回退就是把版本号改回上一个可用版本并重跑,不需要额外的卸载步骤。要点是保留一份「哪些版本组合验证过」的记录(本体版本 + 插件版本),这样回退时能一次改到位,而不是逐个试。
相关术语
- 非交互模式(non-interactive mode)
- 非交互模式指命令在不接受人工输入的环境(如 CI 流水线)中运行的方式。DeepSeek Harness 的安装与升级在 CI 中必须走非交互路径,否则会因等待输入而挂起。— https://docs.npmjs.com/cli/v10/commands/npm-ci
- 可复现构建(reproducible build)
- 可复现构建指同样的输入(代码 + 锁定的依赖版本)每次得到同样的结果。DeepSeek Harness 与其 DSH plugin 在 CI 里应钉住版本,才能把「构建失败」与「上游变更」这两类原因分开。— https://docs.npmjs.com/cli/v10/commands/npm-ci
- 缓存键(cache key)
- 缓存键是流水线缓存命中与否的判定依据,通常由依赖清单文件的哈希构成。用锁文件或清单哈希作缓存键,可以在依赖未变时直接复用缓存、变了才重新安装。— https://docs.npmjs.com/cli/v10/commands/npm-ci
- 冒烟校验(smoke check)
- 冒烟校验指升级后跑一次最小可用性验证,确认关键路径没坏。对 DeepSeek Harness 而言,最小集合是版本号、已装 DSH plugin 清单、以及 dsh web 能否启动。— https://github.com/deepseek-ai/deepseek-harness/blob/master/apps/cli/README.md
来源
- deepseek-ai/deepseek-harness — apps/cli/README.md(升级与 plugin 子命令)· deepseek-ai(GitHub)
- npm Docs — npm ci 与依赖可复现安装· npm
- npm — @deepseek-ai/dsh(版本列表)· npm