goose CLI 命令变更跟踪自动化测试指南:从本地端到端验证到 GitHub Actions 回归检查

goose CLI 命令变更跟踪自动化测试指南:从本地端到端验证到 GitHub Actions 回归检查 goose CLI 命令变更跟踪自动化测试指南从本地端到端验证到 GitHub Actions 回归检查【免费下载链接】goosean open source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM项目地址: https://gitcode.com/GitHub_Trending/goose3/goose本文围绕 goose 仓库中的 TESTING.md 展开讲解如何本地与在 GitHub Actions 中测试 CLI 命令跟踪自动化cli-command-tracking包括提取脚本、diff 脚本、AI 合成配方、全链路流水线的逐段测试方法以及如何用已知变更版本做回归验证。读完本文你可以独立在本地跑通提取-比对-合成-文档更新四段流水线定位提取超时、构建失败、macOS Keychain 提示等典型问题并理解每个环节背后的源码实现逻辑。一、这条自动化要解决什么问题goose 的 CLI 命令定义在 Rust 源码中clap 派生的 Command 枚举而面向用户的 CLI 参考文档是 goose-cli-commands.md。两者会随版本演进逐渐脱节。cli-command-tracking 自动化 采用确定性脚本 AI 配方的混合设计解决这个问题提取确定性对指定版本的 goose 二进制递归执行--help把命令树解析为 JSON命令、子命令、别名、选项的短/长标志、默认值、可选值比对确定性对比新旧两份结构 JSON输出结构化的变更清单并按严重级别自动分类破坏性变更合成AI用 goose recipe 把cli-changes.json写成人类可读的cli-changes.md更新文档AI再跑一个 recipe 把变更落到goose-cli-commands.md并生成update-summary.md供人工审查。各阶段之间通过output/目录下的 JSON/Markdown 文件传递数据因此测试时每一段都可以单独执行、单独验证——这正是 TESTING.md 把测试拆成六个步骤的原因。二、前置条件本地测试需要Python 3.7Rust 工具链用于从源码构建 goosejq用于在命令行中检查 JSON 输出已安装的 goose CLI用于运行两个 AI recipe可访问 goose 仓库的 Git 环境三、本地测试六个步骤逐段验证步骤 1准备环境cd /path/to/cli-command-tracking # 即本仓库 documentation/automation/cli-command-tracking/ # 设置 goose 仓库路径 export GOOSE_REPO/path/to/goose # 创建输出目录 mkdir -p outputGOOSE_REPO是 run-pipeline.sh 和提取脚本解析版本、定位文档文件的基准路径output/是所有中间产物的落盘位置已在仓库中忽略。步骤 2测试提取脚本针对某个具体版本提取 CLI 结构# 用一个 release 版本测试 ./scripts/extract-cli-structure.sh v1.19.0 output/test-extraction.json # 验证输出 jq .version, .commands | length output/test-extraction.json # 查看某个具体命令 jq .commands[] | select(.name session) output/test-extraction.json # 确认被跳过命令被排除 jq .commands[].name output/test-extraction.json | grep -v term预期输出合法的 JSON 结构版本号被正确提取捕获全部命令14 个以上排除term这类被跳过的命令子命令正确嵌套选项带有全部字段short、long、value_name、help、default、possible_values。常见问题未安装 Rust通过 rustup 安装构建失败检查 Cargo.toml 依赖超时错误调大脚本内超时Keychain 提示见下文故障排查一节。源码层面它做了什么extract-cli-structure.sh 是一条获取二进制 → 调用 Python 解析的包装脚本获取策略分两条路若参数是v主.次.补丁形式的 release tag脚本内 is_release_tag 用正则^v[0-9]\.[0-9]\.[0-9]$判断则通过官方下载脚本拉取该版本的预构建二进制避免每次完整编译否则HEAD或任意提交引用走 build_from_sourceHEAD 直接cargo build --release其他引用则用git worktree add在临时目录检出该 tag 构建构建成功后拷贝二进制并移除 worktree。拿到二进制后extract-cli-structure.py 递归执行goose [子命令...] --help并解析 clap 风格帮助文本parse_options 从Options:区块逐个切分选项块用正则分别提取短标志-x、长标志--xxx、值名VALUE、行内/多行帮助文本以及[default: ...]、[possible values: ...]两个元信息标注parse_subcommands 从Commands:区块提取子命令名与[aliases: ...]自动生成的help命令会被跳过extract_command_structure 以递归方式遍历整棵命令树父级解析出的别名会向下传递因为别名只显示在父命令的帮助里每次--help调用默认 10 秒超时run_help_command 中timeout10超时只会打警告并返回空文本不会中断整棵树的提取。跳过命令的配置化哪些命令不参与提取由 skip-commands.json 决定目前配置了term原因终端集成通过goose/g别名文档化。Python 端 load_skip_commands 启动时读取该文件递归遍历时命中名单的命令会打印Skipping command: xxx到 stderr 并被剔除——这就是上面第 2 步用grep -v term验证的由来。增删跳过命令只需改这个 JSON无需改代码。步骤 3测试 diff 脚本对比两个版本的 CLI 结构# 分别提取两个版本 ./scripts/extract-cli-structure.sh v1.14.0 output/old-cli-structure.json ./scripts/extract-cli-structure.sh v1.15.0 output/new-cli-structure.json # 运行 diff python3 scripts/diff-cli-structures.py \ output/old-cli-structure.json \ output/new-cli-structure.json \ output/cli-changes.json # 查看结果 jq .has_changes, .summary output/cli-changes.json # 查看具体变更 jq .changes.commands.added output/cli-changes.json jq .changes.commands.modified[0] output/cli-changes.json jq .breaking_changes output/cli-changes.json预期输出版本有差异时has_changes: true带各类变更计数的 summary结构化、可逐条检查的详细变更按类别归好的破坏性变更。源码层面它做了什么diff-cli-structures.py 的核心逻辑分三步flatten_commands 把嵌套命令树摊平成完整命令路径 → 命令数据的字典例如session list递归处理任意深度嵌套子命令在摊平时被剥离以免比较时递归compare_options 以长标志无长标志则用短标志为键对齐新旧选项逐字段比较short、long、value_name、help、default、possible_values六个字段任何字段变化都记入modifiedcategorize_breaking_changes 按严重级别自动归类破坏性变更变更类型严重级别命令被移除command_removedhigh选项被移除option_removedhigh选项标志重命名option_renamedhigh枚举值被移除enum_values_removedhigh默认值改变default_changedmedium别名被移除alias_removedmedium输出的summary.breaking_changes只统计 high 级别条目便于在日志里一眼看出风险面。步骤 4测试 AI 合成配方生成人类可读的变更文档cd output # 运行合成配方 goose run --recipe ../recipes/synthesize-cli-changes.yaml # 检查输出 ls -lh cli-changes.md head -50 cli-changes.md预期输出生成cli-changes.mdMarkdown 格式规范破坏性变更列在最前面复杂变更附带示例。对应配方 synthesize-cli-changes.yaml 要求模型同时读取三份输入cli-changes.json、old-cli-structure.json、new-cli-structure.json按破坏性变更 → 新命令 → 移除命令 → 修改命令 → 非破坏性变更的结构生成文档并要求使用text_editor工具写出cli-changes.md。安全约束测试 AI 工作流时确保通过store_comment工具发送的内容不包含三反引号代码围栏即使cli-changes.md这类 Markdown 文件本身允许普通反引号。步骤 5测试文档更新配方更新实际文档cd output # 设置目标文档路径 export CLI_COMMANDS_PATH/path/to/goose/documentation/docs/guides/goose-cli-commands.md # 运行更新配方 goose run --recipe ../recipes/update-cli-commands.yaml # 检查输出 ls -lh update-summary.md cat update-summary.md # 验证文档确实被更新 git diff $CLI_COMMANDS_PATH对应配方 update-cli-commands.yaml 的关键设计是只记录当前状态不记录变更历史选项被删就从文档删掉不写已移除、新增就补上不标注新增。配方对 AI 施加了硬性禁令——只能整段删除被明确移除的命令章节、不得改动分类标题、不得重命名未记录的选项、不得重复章节、不得重写示例且必须用str_replaceold_str/new_str做最小化精确编辑。CLI_COMMANDS_PATH未设置时回落到$GOOSE_REPO/documentation/docs/guides/goose-cli-commands.md。步骤 6测试完整流水线cd /path/to/cli-command-tracking # 设置文档路径可选仅更新步骤需要 export CLI_COMMANDS_PATH/path/to/goose/documentation/docs/guides/goose-cli-commands.md # 运行流水线 ./scripts/run-pipeline.sh v1.14.0 v1.15.0 # 检查全部输出 ls -lh output/预期输出全部中间文件生成、流水线无错误完成、汇总显示检测到变更、cli-changes.md生成。run-pipeline.sh 的源码细节版本自动检测不显式传参时优先用gh release list --repo aaif-goose/goose取最新与次新 release tag无gh时回落到git tag --sort-v:refname过滤^vX.Y.Z$RELEASE_TAG环境变量供 GitHub Actions 的 release 触发使用要测试未发布代码需显式传HEAD会话日志过滤AI 阶段用sed去 ANSI 颜色、grep -v过滤starting session、session id:、text_editor行头等会话噪音并用cat -s压缩空行PIPESTATUS[0]检查保证 goose 自身失败不会被 grep 的退出码掩盖产物有效性校验合成产物必须含# CLI Command Changes标题才落盘为cli-changes.md否则视为失败退出无变更短路has_changes为false时流水线打印 No Changes Detected 并跳过 AI 阶段不产生文档更新。四、用已知变更版本做验证要验证自动化测得准需要用真实存在 CLI 变更的版本对。寻找测试版本cd /path/to/goose # 查看 CLI 定义的提交历史 git log --oneline --all -- crates/goose-cli/src/cli.rs | head -20 # 查看某次提交时的命令定义 git show commit-hash:crates/goose-cli/src/cli.rs | grep enum Command -A 30crates/goose-cli/src/cli.rs正是命令枚举的所在文件据此可找到新增/删除/修改了命令的提交并定位对应版本区间。测试用例一新增命令./scripts/run-pipeline.sh v1.13.0 v1.14.0 jq .changes.commands.added output/cli-changes.json测试用例二选项被修改./scripts/run-pipeline.sh v1.14.0 v1.15.0 jq .changes.commands.modified output/cli-changes.json测试用例三无变更同一版本对自身应当无变化./scripts/run-pipeline.sh v1.14.0 v1.14.0 jq .has_changes output/cli-changes.json # 应输出: false五、GitHub Actions 测试在 Fork 中测试Fork 仓库如尚未 Fork把自动化文件拷入 forkcp -r /path/to/cli-command-tracking \ /path/to/forked-goose/documentation/automation/ cp /path/to/goose/.github/workflows/docs-update-cli-ref.yml \ /path/to/forked-goose/.github/workflows/该 workflow 即 docs-update-cli-ref.yml在 fork 设置 Secrets添加ANTHROPIC_API_KEY可选设置 VariablesGOOSE_PROVIDER默认 anthropic、GOOSE_MODEL默认 claude-opus-4-5手动触发Actions → Update CLI Documentation → Run workflow测试时设dry_run: true并可选择要比较的版本。Dry Run 模式以dry_run: true触发不创建 PR在工作流日志中查看输出、下载 artifacts 检查生成的文件、确认变更符合预期。Workflow 输入参数输入说明默认值old_version旧版本 tag自动从 releases 检测new_version新版本 tagHEADdry_run生成文件但不创建 PRtrue检查 Artifacts工作流运行后进入 workflow run 页面 → 下载 artifacts ZIP → 解压查看old-cli-structure.json— 旧版本 CLI 结构new-cli-structure.json— 新版本 CLI 结构cli-changes.json— 检测到的变更cli-changes.md— 人类可读文档pipeline.log— 执行日志六、验证清单在宣布自动化测完了之前逐项核对提取脚本处理所有命令形态简单命令、带子命令、带别名解析所有选项形态短标志、长标志、带值、纯 flag捕获默认值与可选值能处理没有描述的命令支持两级及以上嵌套子命令能正确从 git tag 构建 goosediff 脚本检测新增命令检测删除命令检测选项修改检测帮助文本变化检测默认值变化检测可选值变化正确分类破坏性变更AI 配方生成可读文档给出迁移指引Markdown 格式正确遵守不输出三反引号围栏的安全约束包含相关示例使用 text_editor 工具写文件流水线端到端无错误跑通正确处理无变更分支生成全部预期输出文件正确过滤 goose 会话输出GitHub Actionsworkflow 正确触发能构建两个版本的 goose上传 artifacts检测到变更时创建 PR尊重 dry_run 模式在 fork 中可用自动拉取上游 tags七、故障排查macOS Keychain 提示在 macOS 上运行goose --help或goose --version可能触发 keychain 访问提示因为 goose 启动时会尝试读取存储的凭据。本地 workaround提示时允许访问。CI 侧需注意 GitHub Actions runner 没有 keychain可能需要绕过凭据加载——从源码结构看可以调查是否存在keyring: false配置项或禁用凭据加载的环境变量并确认这是否会阻塞 CI 执行原文档将其标记为待调查项以实际验证结果为准。旧版本构建失败某些旧版本依赖不同可手动验证# 确认版本 tag 存在 git tag | grep v1.14.0 # 手动构建 git worktree add /tmp/goose-test v1.14.0 cd /tmp/goose-test cargo build --release提取超时调大 extract-cli-structure.py 中的超时当前为 10 秒result subprocess.run(cmd, capture_outputTrue, textTrue, timeout30) # 从 10 调大diff 出现意外变更多半是帮助文本格式本身变了直接对比两版本的原始 help 输出定位./old-goose session --help old-help.txt ./new-goose session --help new-help.txt diff old-help.txt new-help.txtAI 配方失败先确认输入文件存在且为合法 JSONls -lh output/cli-changes.json output/old-cli-structure.json output/new-cli-structure.json jq empty output/cli-changes.json # 校验 JSONfork 中 workflow 失败逐项确认ANTHROPIC_API_KEY已设置、上游 tags 已拉取workflow 会自动执行、Rust 工具链可用。八、人工复核与回归测试数据自动化跑完后做人工复核关注五个维度准确性检测到的变更是否与实际 CLI 变更一致、完整性是否全部捕获、文档质量更新后的文档是否准确清晰、示例有效性示例是否仍可运行、风格一致性与既有文档格式是否一致。同时保存已知正确的输出作为回归基线mkdir -p test-data cp output/cli-changes.json test-data/v1.14.0-to-v1.15.0-changes.json cp output/cli-changes.md test-data/v1.14.0-to-v1.15.0-changes.md日后修改提取或 diff 逻辑时用同一版本对重跑并对比基线即可确认改动没有破坏既有功能。九、小结与关键路径这条测试路线的本质是把一条确定性数据管道 AI 文档生成的四段流水线拆开独立验证再用已知变更版本对和回归基线兜住精度。核心文件索引测试指南主体TESTING.md、设计说明README.md提取extract-cli-structure.sh、extract-cli-structure.py比对diff-cli-structures.py流水线run-pipeline.shAI 配方synthesize-cli-changes.yaml、update-cli-commands.yaml跳过命令配置skip-commands.jsonCI 工作流docs-update-cli-ref.yml目标文档goose-cli-commands.md适用前提本地完整测试需要 Rust 工具链与 goose CLIrelease tag 走预构建二进制下载HEAD/提交引用走源码构建AI 阶段依赖可正常调用的模型凭据本地为 goose 配置CI 为ANTHROPIC_API_KEY。【免费下载链接】goosean open source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM项目地址: https://gitcode.com/GitHub_Trending/goose3/goose创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考