Repository navigation
feat(desktop): 应用内更新支持增量更新,补丁失败时自动改下完整包 - #1916
Merged
Merged
Conversation
- 升级 Viva 到带增量更新的版本(Lithe-IDEA/viva 609dd47),发布源为当前版本列出补丁时只下载补丁,在临时目录里从已安装的应用生成新版本后安装 - 补丁下载、应用、安装任一步失败时记录 update.delta.fallback_selected,改下完整包,此后同一版本只提供完整包;只读位置和包管理器管理的安装被拒时不重试完整包 - 生成的副本只用一次:安装器取走后、安装失败、检查到其他版本和窗口关闭时删除,删除失败记录 update.delta.cleanup_failed - 更新页显示增量与完整包大小、下载增量、生成新版本和改下完整包的状态,生成新版本时不提供取消 - 新增中英文案,更新跨平台功能矩阵;Core 固定到 #40 合入后的 c1df34b(含 update.delta.cleanup_failed)
- removeUpdatePayload 改为后台任务,退出时等待删除完成 - fetchDelta 在后台 goroutine 中取消时直接同步删除 - 新增测试:删除被挂起时检查结果照常显示,放行后临时应用被删除 - 功能矩阵说明同步
xiaoyumuxi
marked this pull request as ready for review
November 14, 2026 10:27
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
关联 Issue / Linked issue
PR 类型 / Type
改动说明 / What changes
背景 / Why
Viva 桌面端的应用内更新每次都下载完整安装包。旧 macOS 客户端用 Sparkle 增量包,只下载改动的部分。上游 Viva 的
update包已经支持签名增量补丁(上游 27429b5,"feat(update): apply signed delta updates to the installed payload"),所有平台走同一套流程。本 PR 升级 Viva,在客户端接入增量更新:发布源为当前版本列出补丁时只下载补丁,从已安装的应用生成新版本后安装;补丁任一步失败,自动改下完整包。改动 / Changes
增量更新流程(
desktop/internal/workbench/updates.go)Asset.PatchFrom(当前版本)查发布源是否列出了从当前版本出发的补丁。如果有,状态里记下Delta、补丁大小和完整包大小。DownloadPatch下载补丁,同样校验大小和 SHA-256,下载到用户缓存目录Lithe/Updates/<版本>。update.ApplyPatch在系统临时目录里,从已安装的应用生成新版本。这一步只读取已安装的应用,不写入。InstallOptions.Payload交给安装器,校验与完整包相同。update.delta.fallback_selected(字段为stage和error),同一版本以后不再尝试补丁,并自动改下完整包、安装。ErrManagedExternally),以及只读位置(ErrNotWritable)。这两种情况不改下完整包,只显示原因。cancelUpdate在这期间不起作用。removeUpdatePayload),不阻塞窗口线程,退出时会等它完成。deleteUpdatePayload)。update.delta.cleanup_failed。current增加!u.stopped)。updateProgress,补丁下载和完整包下载共用。applyUpdatePatch、updateQuit、removeUpdateDir改成包级变量,方便测试替换。更新页(
desktop/internal/settingswindow/updates_view.go)UpdateStatus新增Delta、DeltaSize、FullSize、Applying、FellBack。local_history_view.go的historySize改名为byteSize,本地历史和更新页显示大小时共用。文案(
shared/i18n/)desktop.settings.updates.applyingdesktop.settings.updates.availableDeltadesktop.settings.updates.downloadingDeltadesktop.settings.updates.downloadingFulldesktop.settings.updates.help,加上“发布源提供增量更新时只下载改动的部分”。desktop/internal/i18n/shared.generated.go。依赖与固定版本
609dd47(merge: bring upstream main (b63e4a0, delta updates) onto main Lithe-IDEA/Lithe-viva#16)。[Feature] 希望尽快推出 Windows 版,另外支持一下 keymap 自定义 #16 合入了上游b63e4a0的增量更新,并带上 macOS payload 安装修复。这个修复同时以 fix(update): install a patched macOS payload under the running bundle's name vivaui/viva#269 提交到上游,目前还未合入。require改为上游b63e4a0对应的伪版本。golang.org/x/sys随 Viva 从 0.49.0 升到 0.50.0。Lithe-IDEA/Lithe-viva,go.mod仍写旧路径github.com/Lithe-IDEA/viva,靠 GitHub 重定向取得。scripts/desktop/build-desktop-core.sh的PINNED_CORE_REVISION升到c1df34b(Lithe-core-rust#40,声明update.delta.cleanup_failed)。update.delta.fallback_selected已在 Lithe-core-rust#38 中声明。功能矩阵
shared/platform-feature-matrix/features/updates-check-download.json的verification和notes补充了增量更新的行为、平台范围和测试命令。两端的实现状态和验证状态保持不变:partial/pending。测试
desktop/internal/workbench/updates_test.go新增:TestDeltaUpdateInstallsTheRebuiltApplicationTestDeltaUpdateFallsBackToTheFullArchive:download、apply、install 三步分别失败TestDeltaUpdateRefusalIsNotRetriedInFullTestCancelledPatchDownloadIsNotAFallbackTestRebuiltApplicationIsDeletedWhenNothingWillInstallItTestRebuiltApplicationIsDeletedOffTheWindowThread:先挂起删除,确认检查结果照常显示;放行后副本被删除a.wait(),等后台删除完成。desktop/internal/settingswindow/about_view_test.go:TestUpdateLineSaysTheStepUnderWay增加增量相关的各个状态。TestApplyingADeltaUpdateOffersNoCancel。不在本 PR 范围内 / Out of scope
desktop/go.mod的replace升到它在 main 上的 commit。原因如下:609dd47在 Windows 上编译失败,报错为internal/platform/windows/window_windows.go:457:7: duplicate case wmSetTitle (constant 32850 of type uintptr)。wmSetSize和 fork 优化建议 #1 的wmSetTitle都用了0x8052。fork [Feature] 希望尽快推出 Windows 版,另外支持一下 keymap 自定义 #16 合并时没有文本冲突,但 fork CI 的 Windows 检查已经失败。wmSetTitle改为0x8053;修复后 Windows amd64/arm64 的 vet 和 build 都通过。latest.json和补丁,所以合入后发行构建的更新页仍显示“未配置”。跟进:[Feature] 发布流程生成签名更新源与增量补丁,并在发行构建中注入更新源 #1913。update包和viva feed目前不支持 Windows 补丁,Windows 的发布源不会列出补丁,客户端直接下载完整安装包。跟进:[Feature] Windows 支持增量更新(Viva update 包与 viva feed 补齐 Windows 补丁) #1914。size、web、windows-materials),在上游b63e4a0和 main5b177b7上同样失败,不在本 PR 处理。类型专属:feat
多平台对齐
Lithe 的目标是 macOS 与 Windows 能力对齐。必须选下面一项:
platform-specific),理由:补充:客户端代码与平台无关,Linux 同样会走增量流程。Windows 缺的只是 Viva 一侧的补丁支持:发布源没有补丁时,客户端照常下载完整安装包,不会报错。
范围检查 / Scope checks
功能矩阵 / Feature matrix
shared/platform-feature-matrix/features/updates-check-download.json:补充了增量更新的verification和notes。两端的实现状态partial、验证状态pending保持不变,因为还没有实机和签名发布源的验收。./scripts/platform-feature-matrix/verify-platform-feature-matrix.sh(validated 224 platform capabilities),以及./scripts/platform-feature-matrix/verify-platform-feature-matrix-change.sh origin/preview HEAD(passed)。.artifacts/下生成的矩阵视图统一日志系统 / Structured logging
rust/logging/events/update.json中声明:update.delta.fallback_selected(Lithe-core-rust#38)和update.delta.cleanup_failed(Lithe-core-rust#40),均已在固定的c1df34b中。本仓库没有shared/logging/,桌面端也没有生成的事件类型;事件 ID 和现有的operationFailedEvent一样,写成字符串常量后经a.emit记录。没有使用print,也没有直接写 stderr。log-exempt)。高频路径(下载进度)不打日志。stage(固定的三个值)和error(logwindow.ErrorFields),不记录路径内容或命令输出node scripts/logging/generate-log-events.mjs --check和node scripts/logging/verify-log-usage.mjs:本仓库没有scripts/logging/。事件目录的生成和检查在 Core 仓库,已随 Lithe-core-rust#38、Add Windows CI workflow configuration #40 运行。界面文案 / i18n
shared/i18n/补齐中英词条,运行node scripts/i18n/generate-i18n.mjs并提交了生成结果,没有手改生成文件node scripts/i18n/verify-app-language-localization.mjs(passed)和node scripts/i18n/generate-i18n.mjs --check(en-US、zh-CN 均为 11130/11130),没有放宽脚本或扩大豁免名单逻辑归属 / Logic placement
update包里,各平台用的是同一份 Go 代码。Lithe 只负责状态编排和界面,Core 不参与更新。性能与内存 / Performance and memory
TestRebuiltApplicationIsDeletedOffTheWindowThread守住这一点go.sum多出的github.com/dsnet/compress和github.com/gabstv/go-bsdiff只供 Viva 的tools/patchgen使用,没有链接进lithe:scripts/desktop/desktop-go.sh list -deps ./cmd/...只列出 Viva 自带的internal/bsdiff和update。不涉及启动、输入、滚动等路径。设置 / Settings
N/A:只改了更新卡片的状态文案和按钮,没有新增或修改设置项,也没有新增或移动设置页。
插件契约 / Plugin contract
N/A:没有改动插件契约、能力版本或插件函数协议。Core 固定版本只是为了日志事件目录而升级。
发行包与资源 / Bundle and resources
Lithe/Updates/<版本>。ApplyPatch放在系统临时目录(os.MkdirTemp),只读取已安装的应用。updates.go的注释里。./scripts/desktop/verify/verify-runtime-bundle-immutability.sh(macOS 和 Windows 源码的静态检查都通过)。无用代码与重构 / Dead code and refactoring
updateProgress取代验证 / Verification
make -C desktop fmt-checkscripts/desktop/desktop-go.sh test ./...scripts/desktop/desktop-go.sh test -race -count=3 ./internal/workbench -run 'TestAutomaticUpdateCheck|TestUpdateCheckFailure|TestCancelledUpdateDownload|TestTurningOffTheAutomaticCheck|TestDeltaUpdate|TestCancelledPatchDownload|TestRebuiltApplicationIsDeleted'scripts/desktop/desktop-go.sh test -race -count=3 ./internal/settingswindow -run 'TestUpdateLineSaysTheStepUnderWay|TestApplyingADeltaUpdateOffersNoCancel'removeUpdatePayload改回在窗口线程同步删除,再跑TestRebuiltApplicationIsDeletedOffTheWindowThreadnode scripts/i18n/verify-app-language-localization.mjsnode scripts/i18n/generate-i18n.mjs --check./scripts/platform-feature-matrix/verify-platform-feature-matrix.sh./scripts/platform-feature-matrix/verify-platform-feature-matrix-change.sh origin/preview HEAD./.agents/skills/write-stable-tests/scripts/verify-test-stability.sh --base origin/preview./scripts/desktop/verify/verify-runtime-bundle-immutability.sh609dd47:GOOS=windows go buildduplicate case wmSetTitle,见“不在本 PR 范围内”GOOS=windows GOARCH=amd64|arm64 CGO_ENABLED=0 go vet ./internal/platform/windows/ ./app/... ./headless/... ./update/...和go build ./...未能执行的检查和原因:
core包依赖 cgo,本机没有 Windows C 工具链。updates.go没有平台构建标签,只用到 Vivaupdate包的跨平台 API,这个包修复后在 Windows 上 vet 通过。latest.json和补丁,被 [Feature] 发布流程生成签名更新源与增量补丁,并在发行构建中注入更新源 #1913 阻塞。所以没有做 macOS 整机验收,也没有界面截图;更新页的各个状态由about_view_test.go覆盖。提交前确认 / Final checks
preview(b582e206a);目标分支:preview.build/、target/、dist/、.artifacts/等产物,没有凭据、个人路径和未脱敏的日志或截图