Appearance
功能规格说明:CI/CD 集成
规格文件:docs/specs/ecosystem/ci-integration.md创建日期:2026-10-30
用户场景与测试 (必填)
用户故事:在 GitHub Actions 里一条 uses 就触发 AI 审查(优先级:P0)
作为维护仓库的开发者,我希望在 PR 上加一段 uses: netease-lcap/wave-agent/.github/workflows/review.yml@v1、把模型凭证放进 repository secret,就自动跑一次 AI 审查并收到 PR 评论,以便不必自己拼「装 CLI + 认证 + 权限 + 回评论」这四步。
优先级原因:这是「CI/CD 流水线插件」的产品化封装本身;没有它,用户要手写安装、认证、权限模式与结果回传,等于没交付。
独立测试:在一个模板化的示例仓库里,只加一个 job 级 uses 与一个 WAVE_API_KEY secret,对含有变更的分支提一个 PR,断言:workflow 成功、PR 上出现审查评论、job 产物里有结果 JSON。
验收场景:
- 假设 workflow 里使用
uses: netease-lcap/wave-agent/.github/workflows/review.yml@v1并给了prompt,当 job 运行时,则 可复用 workflow 自行完成 Node 环境准备与 CLI 安装,调用方不需要写npm i -g wave-code。 - 假设 只配了
WAVE_API_KEY(以及可选的WAVE_BASE_URL)secret,当 workflow 运行时,则 凭证通过环境变量注入到 CLI 的配置链,无需在 CI 里写~/.wave/settings.json,也不出现在日志里。 - 假设 本次运行正常结束,当 workflow 收尾时,则 结果 JSON(
--output-format json的信封)写入工作区文件并作为 job 产物上传,文件名与路径固定可引用。 - 假设 本次运行失败(模型不可用、凭证无效等),当 workflow 收尾时,则 job 失败(退出码非 0),且结果 JSON 里
is_error为true、失败原因在errors里。 - 假设 跑的是审查类提示词,当 workflow 运行时,则 默认只放行只读工具集(读文件、搜内容、
git查询、gh/glab查询与评论),不授予写文件、改配置、执行任意命令的能力。 - 假设 当前分支存在 PR,当 审查产出发现时,则 评论由内置技能自己发出(
gh pr comment),workflow 不重复发一条。
用户故事:在 GitLab CI 里跑同一套(优先级:P1)
作为用 GitLab 的团队,我希望拿到一段可直接粘进 .gitlab-ci.yml 的 job,用 masked 变量提供凭证,以便不依赖 GitHub 专用能力。
优先级原因:GitLab 是私有化部署的主战场,模板体量小,但缺了就等于只支持一半客户。
独立测试:把模板段粘进示例仓库的 .gitlab-ci.yml,配置 WAVE_API_KEY(masked)与 GITLAB_TOKEN,对 MR 提一次提交,断言 pipeline 成功、MR 上出现评论、job artifacts 里有结果 JSON。
验收场景:
- 假设 用户粘贴模板段并配置了 masked 变量
WAVE_API_KEY,当 pipeline 运行时,则 job 完成 CLI 安装与调用,不需要额外的 before_script。 - 假设 环境里有
glab与可用的GITLAB_TOKEN,当 审查产出发现时,则 评论以 MR note 形式发出。 - 假设 用户没配
GITLAB_TOKEN,当 运行时,则 审查照常进行、结果落在 artifacts 里,只是不发评论(不因此失败)。
用户故事:把结果 JSON 当上游数据用(优先级:P1)
作为在流水线里聚合质量报告的工程师,我希望 workflow/job 的产物里有稳定的结果 JSON,以便后续步骤(门禁判定、报告归档)读它而不是解析日志。
优先级原因:这是「质量报告生成」那一项的输入;把产物约定死在文档里,后续步骤才可能加而不破坏用户。
独立测试:在 workflow 里断言该文件的路径存在、能 jq 出 subtype / result / tool_calls 字段。
验收场景:
- 假设 有下游步骤需要读取结果,当 workflow 结束时,则 结果 JSON 位于约定的固定路径(见 FR-3),且 job outputs 提供
result/subtype/is-error/result-file四项。 - 假设 用户把
output-format设为stream-json,当 运行时,则 产物是逐行事件流文件,末行仍是result事件,下游仍可用「取末行」的方式读到结果。
用户故事:在无交互环境里不卡在权限确认(优先级:P0)
作为在 CI 里跑 wave 的执行者,我希望在没有任何人值守的情况下不会因为权限确认而挂住或空转,以便流水线能稳定结束。
优先级原因:CI 里没有 stdin 交互;一旦某个工具调用进入「等待确认」,job 会一直卡到超时,这比失败更糟。
独立测试:在受限工具集下跑一个必然需要工具调用的提示词,断言运行在无 stdin 的环境里正常结束、没有权限等待。
验收场景:
- 假设 在 CI(无 TTY、无 stdin 输入)中运行,当 模型调用只读工具时,则 工具直接执行,不发出权限请求、不等待输入。
- 假设 模型尝试调用未被允许的工具,当 该调用发生时,则 权限被拒并作为工具结果返回给模型,运行继续结束(不挂起、不重试等待)。
边界情况
- 封装形态:用主仓库的可复用 workflow(
uses: owner/repo/.github/workflows/<file>.yml@ref)——它只取那一个 yml,不下载仓库快照,也就谈不上仓库越大越慢。不为此新建独立仓库:本仓库是 public,一条uses已经完成封装,独立仓库只会多出版本同步与内网镜像成本。本轮也不提供 step 级的 composite action:真要用「插进已有 job」时再按同一套输入与产物约定补,不另起一套设计。 - CI 里的权限预设:
--permission-mode dontAsk+ 收窄的--tools。无 callback 时受限工具一律被拒、拒绝原因作为工具结果回到模型,运行照常收尾(不会等待输入);技能自己在 frontmatter 里声明的allowed-tools在执行时注册为临时规则,所以审查需要的git/gh查询无需在模板里再抄一遍。 - PR 来自 fork:默认
GITHUB_TOKEN对 fork PR 是只读的,发评论会失败。文档必须给出两条路径:改用pull_request_target(注明风险:不要 checkout 不可信代码后执行)或使用带pull-requests: write的 token。 - 凭证缺失:没有
WAVE_API_KEY且没有登录态时报错退出(退出码 1),结果 JSON 的errors里有原因,而不是静默产出空结果。 - CLI 版本固定:默认装最新版会让流水线在别人发版后行为漂移,文档要求 pin 版本(
wave-version),可复用 workflow 的默认值也必须是明确的版本号而不是隐式 latest。 - 结果文件已存在:上次运行的产物不得被误读,每次运行先覆盖再写。
- 超时:审查可能跑很久,模板给出
timeout-minutes建议值,不写死到可复用 workflow 内部。 - 私有 npm / 内网模型网关:
WAVE_BASE_URL与 registry 都可配置,模板不假设公网可达。 - 门禁(阻断合并)不在本规格内:依赖 A2 的状态上报,见 issue #2663 第 3 步;本规格只保证「结果可读 + 退出码正确」,并给出「把它设成 required check」的说明。
需求 (必填)
功能需求
- FR-1 可复用 workflow:主仓库
.github/workflows/提供带workflow_call的可复用 workflow,输入至少包含prompt(必填)、wave-version、output-format、permission-mode、tools、allowed-tools、api-key(缺省读WAVE_API_KEY)、base-url;输出至少包含result、subtype、is-error、result-file。 - FR-2 最小权限预设:默认工具集覆盖「读文件 / 搜内容 /
git查询 / 平台 CLI 查询与评论」;需要写能力的场景必须由调用方显式放开。 - FR-3 产物:结果写入固定文件名(默认
wave-result.json)并上传为 artifact;同时通过 job outputs(可选形态为 step outputs)暴露result、subtype、is-error、result-file。 - FR-4 GitLab 模板:文档提供可直接粘贴的 job 段(镜像、变量、artifacts),与 GitHub 侧共用同一套环境变量与产物约定。
- FR-5 文档交付:在
docs/cli.md增加「CI 集成」一章(认证、权限预设、两个平台的完整示例、产物约定、fork PR 注意事项),并在docs/tutorials.md增加一篇实操教程;示例必须可复制即跑。 - FR-6 退出码透传:沿用打印模式的失败判据(抛错或「有错且无正文」),封装层不另外发明判据。