Skip to content

feat: 修复 update 跨平台资产探测并新增 version 版本查询命令#431

Merged
phantom5099 merged 8 commits into1024XEngineer:mainfrom
pionxe:fix/version-update-probe
Apr 24, 2026
Merged

feat: 修复 update 跨平台资产探测并新增 version 版本查询命令#431
phantom5099 merged 8 commits into1024XEngineer:mainfrom
pionxe:fix/version-update-probe

Conversation

@pionxe
Copy link
Copy Markdown
Collaborator

@pionxe pionxe commented Apr 23, 2026

变更背景

当前存在两个核心问题:

  1. neocode update 在部分场景会误报 no release asset found for current platform,即使 release 里存在对应平台资产。
  2. CLI 缺少 version 子命令,用户无法先确认“当前版本 / 远端版本 / 是否需要升级”。

本 PR 目标是补齐版本可观测闭环:先查版本,再执行升级,失败可诊断

Closes #426

主要改动

  1. updater 资产匹配策略升级
  • 将“精确资产名匹配”改为“平台语义匹配(os/arch/ext)”
  • 兼容命名变体(大小写、_/-、扩展名组合)
  • 多候选资产时不再随机选择,改为明确报错
  1. 更新失败诊断增强
  • 无候选或多候选时,错误信息包含:
  • os
  • arch
  • expected-pattern
  • available-assets-count
  • candidate-assets
  • 对诊断输出做上限控制:候选最多前 10 个,单项最长 120 字符
  1. 新增 neocode version 子命令
  • 输出当前版本
  • 探测远端最新版本并输出比较结果
  • 默认仅比较稳定版,--prerelease 才纳入预发布
  • 探测失败时仍返回成功退出码(便于脚本与自动化)
  1. 统一探测入口并消除重复探测
  • 抽取 CLI 侧轻量探测 helper
  • version 命令跳过静默检查,避免同次命令二次网络探测
  1. 文档与测试
  • 更新 docs/guides/update.mdREADME.md
  • 增加 updater 命名变体、无候选、多候选、诊断截断等测试
  • 增加 version 命令场景测试(有更新/无更新/失败/预发布/非 semver)

行为变化

  • 新增命令:
  • neocode version
  • neocode version --prerelease
  • update 在资产探测失败时会输出更可执行的诊断信息
  • 同平台命中多个候选资产时,升级会失败并提示歧义,不再自动选取

测试结果

  • go test ./internal/updater ./internal/cli
  • ⚠️ go test ./... 在当前环境失败于既有用例:
    internal/configTestFsyncDirectoryNonWindowsSucceedsForExistingDirectoryAccess is denied
    该失败与本 PR 修改范围无直接关联。

风险与回滚

  • 风险:资产语义匹配规则变更可能影响极端命名资产的选择结果
  • 控制:已加入“多候选报错”与诊断输出,避免错误升级
  • 回滚:可回退到本 PR 前版本并恢复旧探测逻辑

Checklist

  • 修复 update 跨平台资产探测误报
  • 新增 version 子命令并支持 --prerelease
  • 统一探测入口并避免重复探测
  • 增强错误诊断信息
  • 补齐核心回归测试
  • 更新用户文档

- 将 updater 从“精确资产名过滤”调整为基于 os/arch/ext 的语义匹配
- 兼容资产命名大小写、分隔符与扩展名变体,避免“有资产却命不中”
- 在无候选/多候选场景输出可诊断错误信息(os、arch、expected-pattern、available-assets-count、candidate-assets)
- 新增 neocode version 命令,输出当前版本、远端版本与比较结果
- 默认仅比较稳定版,--prerelease 才纳入预发布版本比较
- 抽取统一版本探测入口,version 命令跳过静默检查,避免二次探测
- 补充 updater/cli 回归测试,并更新更新指南与 README 说明
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 23, 2026

Codecov Report

❌ Patch coverage is 93.65559% with 21 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/updater/updater.go 93.52% 9 Missing and 7 partials ⚠️
internal/cli/root.go 62.50% 1 Missing and 2 partials ⚠️
internal/cli/version_command.go 96.87% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown

@fennoai fennoai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Completed 4 review passes (code quality, performance, security, docs).

1 issue found after deduplication.

// newAssetDiagnosticError 生成包含平台与候选信息的可执行诊断错误。
func newAssetDiagnosticError(message string, target assetTarget, probe probeResult) error {
return fmt.Errorf(
`%s (os=%s arch=%s expected-pattern="%s" available-assets-count=%d candidate-assets=%v)`,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: Medium (security hardening)

newAssetDiagnosticError embeds remote-controlled asset names (candidate-assets) directly into error text. These strings can contain ANSI control sequences and are later surfaced by CLI errors, which can lead to terminal escape injection/log pollution.

Please sanitize diagnostic fields before formatting (reuse sanitizeVersionForTerminal-style filtering or equivalent), or encode/unquote non-printable bytes in diagnostics.

@pionxe
Copy link
Copy Markdown
Collaborator Author

pionxe commented Apr 23, 2026

@xgopilot 请你帮我将codecov/patch覆盖率提升至百分之九十五以上!

@fennoai
Copy link
Copy Markdown

fennoai Bot commented Apr 23, 2026

完成情况

已针对 codecov/patch 覆盖率目标补充了分支测试,并将提交推送到 PR 分支 fix/version-update-probe

本次改动

  • 新增/补强 version 命令相关分支测试:
    • internal/cli/version_command_test.go
    • internal/cli/version_probe_test.go
  • 新增/补强 updater 资产探测与诊断分支测试:
    • internal/updater/updater_test.go

本地验证

  • go test ./internal/updater ./internal/cli -coverprofile=/tmp/cover_new.out
    • internal/cli/version_command.go: 100%
    • internal/cli/version_probe.go: 100%
    • internal/updater/updater.go: 显著提升(关键新增分支已覆盖)
  • go test ./...:全部通过

提交信息

建议等待 Codecov 重新计算 patch 覆盖率;按本次覆盖补齐,目标 >95% 预期可达。

View job run

Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: pionxe <148670367+pionxe@users.noreply.github.com>
@phantom5099
Copy link
Copy Markdown
Collaborator

@xgopilot 批判性review整个PR,分析所有潜在风险点,找出所有漏洞,确保每个地方的修改不是退步的,方案上的设计也不能碎片化,更不能妥协式兼容或兜底旧代码,不许输出正向表扬

@fennoai
Copy link
Copy Markdown

fennoai Bot commented Apr 23, 2026

审查结论(仅问题)

  1. 严重:version 命令在“远端有新版本但当前平台不可更新”时会给出错误结论

    • 位置:internal/updater/updater.go:161, internal/updater/updater.go:273, internal/cli/version_command.go:103
    • 机制:CheckLatest 只在 probeStatusMatched 才计算 HasUpdate,但仍返回 LatestVersionversion 命令随后在 HasUpdate=false 时直接输出 You are on the latest version.
    • 结果:当最新版本存在但因 no candidate/ambiguous 无法升级时,用户会被误导为“已是最新”,这是功能性退步。
  2. 高风险:更新失败诊断把远端资产名原样拼接到终端,存在终端控制字符注入面

    • 位置:internal/updater/updater.go:526, internal/updater/updater.go:559, internal/updater/updater.go:565
    • 机制:candidate-assets 仅做长度截断,不做 ANSI/控制字符清洗,最终直接 %v 输出。
    • 结果:若资产名含转义序列/换行,可能污染终端输出或伪造日志行。当前 PR 新增了这一路径,扩大了输出攻击面。
  3. 中风险:版本解析策略过宽,可能误选 tag 并导致错误的“最新版本”判定

    • 位置:internal/updater/updater.go:57, internal/updater/updater.go:466
    • 机制:semverTagPattern 非锚定,parseReleaseVersion 取 tag 内首个匹配子串。
    • 结果:非规范 tag(含多个数字片段或语义噪声)可能被当作合法版本参与排序,产生错误探测结果。
  4. 中风险:探测链路出现双实现残留,增加后续语义漂移概率

    • 位置:internal/updater/updater.go:304
    • 机制:主路径已切到 ProbeLatest,但 DetectLatest 旧实现仍保留并被测试覆盖(internal/updater/updater_test.go:890 起)。
    • 结果:同一模块内存在两套“最新版本探测”语义,后续维护很容易出现修一处漏一处的碎片化回归。

复核范围

  • 已审查 origin/main...HEAD 全部变更文件。
  • 已本地执行:go test ./internal/updater ./internal/cli
  • 未扩展执行 go test ./...(本次按 PR 变更域聚焦)。

View job run

@pionxe
Copy link
Copy Markdown
Collaborator Author

pionxe commented Apr 24, 2026

@xgopilot 请你帮我解决review提到的问题!

@fennoai
Copy link
Copy Markdown

fennoai Bot commented Apr 24, 2026

处理结果

已根据上次 review 的 4 个问题完成修复,并已推送到当前 PR 分支 fix/version-update-probe(commit: a856275)。

已完成修复

  1. 修复 version 误报 latest
  • updater.CheckResult 新增 ComparableLatest,仅当“最新版本且当前平台可安装”时才参与升级比较。
  • version 命令在“远端有版本但当前平台无可安装资产”时输出:Update status: unknown (latest release has no installable asset for current platform).
  1. 修复诊断输出终端注入风险
  • updater 诊断路径新增清洗:去除 ANSI 序列与不可打印字符。
  • candidate-assetsosarchexpected-pattern 输出前均做清洗。
  1. 收紧版本 tag 解析规则
  • parseReleaseVersion 改为严格匹配完整 semver tag(vX.Y.Z + 可选 prerelease/build),不再从任意字符串中抽取子串。
  1. 清理重复探测实现
  • 删除 selfupdateClient.DetectLatest 旧入口与对应测试残留,保留单一探测语义路径(ProbeLatest)。

测试

  • go test ./internal/updater ./internal/cli
  • go test ./...

未完成项

  • 无。

View job run

Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: pionxe <148670367+pionxe@users.noreply.github.com>
@pionxe
Copy link
Copy Markdown
Collaborator Author

pionxe commented Apr 24, 2026

@xgopilot 请你帮我解决冲突问题!

@fennoai
Copy link
Copy Markdown

fennoai Bot commented Apr 24, 2026

已完成冲突修复

已处理当前 PR 与 origin/main 的冲突并推送到分支 fix/version-update-probe

本次处理:

  • 合并 README.md 冲突:同时保留“版本与升级命令”与“RFC#420 双产物与启动兼容”内容。
  • 合并 docs/guides/update.md 冲突:在保留 version/update 新说明的同时,补回主干中的“双产物安装建议 / 升级后验证 / 回滚步骤”。
  • 验证通过:go test ./internal/updater ./internal/cli
  • 已推送提交:43b2bf3

未完成项:无。

View job run

Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: pionxe <148670367+pionxe@users.noreply.github.com>
@pionxe
Copy link
Copy Markdown
Collaborator Author

pionxe commented Apr 24, 2026

@xgopilot 请你帮我解决文件冲突问题!

@fennoai
Copy link
Copy Markdown

fennoai Bot commented Apr 24, 2026

冲突处理结果

已完成本次“文件冲突”处理,并将修复提交推送到当前 PR 分支 fix/version-update-probe

  • 已确认并解决与 origin/main 的冲突点(README.mddocs/guides/update.md)。
  • 保留主干最新文档基线内容,并在 README.md 中保留 version/update 命令说明。
  • 本地验证通过:go test ./internal/updater ./internal/cli
  • 已推送提交:ad0e941
  • PR feat: 修复 update 跨平台资产探测并新增 version 版本查询命令 #431 当前状态:mergeStateStatus = CLEAN(可合并)。

未完成项:无。

View job run

Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: pionxe <148670367+pionxe@users.noreply.github.com>
@phantom5099
Copy link
Copy Markdown
Collaborator

@xgopilot 审查一轮目标是否完成、是否引入新问题,并评估是否可以合并

@fennoai
Copy link
Copy Markdown

fennoai Bot commented Apr 24, 2026

审查结论(仅问题)

  1. 中风险:version 仍可能误报“已是最新”

    • 位置:internal/updater/updater.go:264-277internal/cli/version_command.go:105-113
    • 问题:ProbeLatest 先拿到 latestEligible(语义上的最新 release),但只要存在更旧的 latestMatched(当前平台可安装),就会把 LatestVersion 覆盖为 latestMatched。随后 version 按该值输出 You are on the latest version.
    • 影响:当“最新 release 对当前平台无资产,但旧 release 有资产”时,用户会看到“已是最新”,与“latest stable version”字面含义冲突,也会掩盖“当前平台无法安装真正最新 release”的事实。
    • 建议:补一个用例覆盖该场景,并将“远端最新版本”和“当前平台最新可安装版本”分离输出,或在该场景统一降级为 Update status: unknown
  2. 低风险:文档与实现不一致,目标闭环信息不完整

    • 位置:docs/guides/update.md:7internal/cli/root.go:163-165
    • 问题:实现中 version 已加入“跳过静默检测”名单,但文档仍只写 url-dispatchupdate。同时该文档当前未体现 neocode version 的使用与输出语义。
    • 影响:用户和维护者会基于过期文档理解行为,降低可诊断性。
    • 建议:同步文档到当前行为,补上 version 命令与 --prerelease 场景说明。

目标完成度与可合并性

  • 目标完成度:主功能(跨平台资产探测、version 命令、测试补充)已落地,但上述语义问题与文档失真仍存在。
  • 可合并判断:暂不建议合并,建议先修复第 1 条(功能语义)并同步第 2 条(文档一致性)。

复核与验证

  • 变更对比:git diff origin/main...HEAD
  • 本地测试:go test ./internal/updater ./internal/cligo test ./...(均通过)

View job run

@pionxe
Copy link
Copy Markdown
Collaborator Author

pionxe commented Apr 24, 2026

@xgopilot 请你解决review中的问题!
关于第一个问题, 如果我理解的没错的话,该问题是:neocode version 命令可能会因为找到了一个“可用的最高版 (v1.9)”,就对比你的 v1.8 并提示:“You are on the latest version”(或类似逻辑),从而掩盖了 v2.0 已经存在的事实。
我希望遇到这种情况,是先更新到可用的最高版,后提示更新到的版本以及远端可能存在问题!
关于第二个问题,我希望你能够将文档对齐实现!

@fennoai
Copy link
Copy Markdown

fennoai Bot commented Apr 24, 2026

已完成你提出的两项修复,并推送到当前分支。

结果摘要

  1. 修复 version 掩盖更高不可安装版本的问题
  • updater 中分离了两个概念:
    • 远端语义最新版本:LatestVersion
    • 当前平台可安装的最高版本:InstallableVersion
  • 新增 LatestInstallable 语义并在 CheckLatest 中收敛为 ComparableLatest
  • HasUpdate 现在可在“远端更高版本不可安装,但存在更低可安装版本”场景下正确为 true
  1. 调整 neocode version 输出策略(按你的期望)
  • 当远端最新不可安装但存在可安装升级时:
    • 先提示可升级到当前平台可安装最高版本(含 target 版本)
    • 再提示远端存在更高但当前平台不可安装的状态
  • 当已在“当前平台可安装最高版本”时,不再误报 You are on the latest version.,改为明确说明并附远端提示。
  1. 文档与实现对齐
  • docs/guides/update.md
    • 补充 neocode version / --prerelease 说明
    • 明确 version 也跳过静默检测
    • 增补“远端最新不可安装但有可安装回退版本”的输出语义
  • README.md:补充上述关键行为说明。
  1. 额外一致性修复
  • 静默更新提示改为优先展示 InstallableVersion,避免提示版本与实际可升级版本不一致。

测试

  • go test ./internal/updater ./internal/cli
  • go test ./...

提交与推送

未完成项:无。

View job run

xgopilot and others added 3 commits April 24, 2026 14:28
…lign docs

Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: pionxe <148670367+pionxe@users.noreply.github.com>
fix: resolve version fallback messaging and align update docs
@phantom5099 phantom5099 merged commit 3b2310a into 1024XEngineer:main Apr 24, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: update 跨平台误报无可用资产,且缺失 version 子命令导致版本可观测性不足

3 participants