十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Screenpipe 桌面应用本地更新(Updater)测试指南:基于 mock-updates 模拟 Tauri 自动更新全流程

Screenpipe 桌面应用本地更新(Updater)测试指南:基于 mock-updates 模拟 Tauri 自动更新全流程 Screenpipe 桌面应用本地更新Updater测试指南基于 mock-updates 模拟 Tauri 自动更新全流程【免费下载链接】screenpipeYC (S26) | Open Computer History | Record your screen continuously locally and provide context to your agents (Claude, Codex, Openclaw, Hermes, Runner...)项目地址: https://gitcode.com/GitHub_Trending/sc/screenpipe这篇指南讲解 Screenpipe 桌面应用Tauri 2 Rust内置的本地更新测试套件 mock-updates如何在不依赖官方更新服务器的情况下用本机127.0.0.1:8765模拟新版本发布 → 旧版本应用检查更新 → 下载并暂存升级包的完整链路。读完你将掌握updater-local:build/updater-local:stage-last/updater-local:serve三组命令的用法、签名与 manifest 清单的生成原理以及如何驱动打包后的真实应用做端到端更新回归。核心文档位于 e2e/mock-updates/README.md配套实现见 e2e/mock-updates/updater-harness.ts。一、套件概览为什么需要本地 mock 更新服务器Screenpipe 桌面应用通过tauri-plugin-updater实现自动更新生产环境从https://screenpipe.com/api/app-update/{channel}/{{target}}-{{arch}}/{{current_version}}拉取更新清单见 src-tauri/src/updates.rs。在开发与 CI 中直接依赖公网端点既不安全也不可控因此仓库在apps/screenpipe-app-tauri/e2e/mock-updates/下内置了一套离线测试方案用minisign 密钥对对本地构建的更新包签名与生产一致把签名后的安装包暂存到本地目录用Bun 内置 HTTP 服务在127.0.0.1:8765提供 manifest 与安装包下载让旧版本应用指向该端点验证完整的更新检查、下载、验签、暂存流程。套件目录结构e2e/mock-updates/文件作用README.md快速上手命令文档本指南的主体updater-harness.ts统一 CLI构建、签名、暂存、服务端packaged-update-restart.e2e.tsmacOS 打包级端到端测试真实安装重启windows-persistence-server.tsWindows 企业持久化更新的策略服务 fixturetsconfig.json该子项目的 TypeScript 配置所有 npm 脚本都通过 apps/screenpipe-app-tauri/package.json 暴露核心三组为updater-local:build: bun ./e2e/mock-updates/updater-harness.ts build, updater-local:serve: bun ./e2e/mock-updates/updater-harness.ts serve, updater-local:stage-last: bun ./e2e/mock-updates/updater-harness.ts stage-last另有updater-local:setup-keys生成开发签名密钥和prepare-updater-manifest手工写 manifest两个辅助脚本。二、前提条件Bun所有脚本用 Bun 运行仓库锁定packageManager: bun1.3.10自带Bun.serve与Bun.spawnSyncRust 工具链updater-local:build会调用tauri-apps/cli触发 cargo 编译首次构建较慢平台支持harness 的discoverBundle()支持 macOS.app.tar.gz、Linux.AppImage.tar.gz、Windows.nsis.zip/-setup.exe打包级重启测试packaged-update-restart.e2e.ts目前仅 macOS首次需生成签名密钥build在无环境变量签名时自动调用setup-keys生成开发用 minisign 密钥对幂等。三、快速上手三步骤本地更新验证步骤一构建并暂存新版本发布物将 apps/screenpipe-app-tauri/src-tauri/Cargo.toml 的[package] version改成一个更新的 semver文档示例为2.4.229当前仓库为2.7.28实际以你的目标版本为准然后依次执行bun run updater-local:build bun run updater-local:stage-last bun run updater-local:serveupdater-local:build以release-localcargo profile 编译并打包带签名的更新工件产物输出到src-tauri/target/release-local/bundle/下的平台目录updater-local:stage-last自动挑选最新构建的 bundle复制到e2e/mock-updates/artifacts/并从Cargo.toml读取当前版本号生成e2e/mock-updates/manifest.jsonupdater-local:serve启动本地更新服务器保持该终端持续运行╔═══════════════════════════════════════════════╗ ║ Mock update server → http://127.0.0.1:8765/ ║ ║ Stage: bun run updater-local:stage-last ║ ╚═══════════════════════════════════════════════╝步骤二构建旧版本应用另开一个终端把Cargo.toml的 version 改成一个低于步骤一的 semver然后执行bun run updater-local:build这一步产出的是用户当前安装的旧版本安装包用于启动后触发更新检查。步骤三验证更新流程启动步骤二构建的旧版应用在应用内触发更新检查设置页/托盘菜单的更新入口。预期结果应用从http://127.0.0.1:8765/拉到暂存的新版本 manifest下载签名安装包、验签后完成暂存提示重启应用。注意事项README 明确强调必须先构建新版再构建旧版后执行的旧版构建会覆盖src-tauri/target/release-local/bundle下的 bundle 输出目录若顺序颠倒stage-last暂存的将是旧版工件导致更新逻辑失效更新服务器的终端必须一直运行直到验证完成stage-last在暂存完成后即把工件与 manifest 固化到e2e/mock-updates/下因此后续重跑旧版构建不会破坏已暂存的更新源。四、底层原理updater-harness.ts 源码拆解updater-harness.ts是套件的核心提供 5 个子命令build、setup-keys、stage-last、prepare-manifest、serve。关键常量const SIGNING_PASSWORD screenpipe-local-updater-e2e; const CARGO_PROFILE release-local; // 快速本地 release 构建 const PORT 8765; // 本地更新服务端口 const TAURI_CLI [bun, x, --bun, tauri-apps/cli2.11.2];4.1 签名体系setup-keys / ensureSigning更新包签名复用 Tauri 官方signer generate命令生成开发用 minisign 密钥对const gen Bun.spawnSync( [...TAURI_CLI, signer, generate, -w, PRIVATE_KEY, --ci, --password, SIGNING_PASSWORD], { cwd: APP_ROOT, stdin: ignore, stderr: inherit, stdout: inherit }, );生成的公钥会被写进signing/pubkey-merge.json合并配置随--config传给 tauri build使构建出的应用内嵌该公钥用于验签。实现还带一个密码方案版本戳.password-scheme-version当签名方案升级时自动轮换密钥避免旧密钥污染。4.2 build 命令与 tauri.e2e.jsonbuild命令实际执行的是[...TAURI_CLI, build, --features, features, --config, cfgE2e, --, --profile, CARGO_PROFILE]其中features固定包含official-build源码构建默认不带此 feature不带它应用会显示auto-updates unavailable并通过tauri.e2e.json叠加更新端点配置{ bundle: { createUpdaterArtifacts: true }, plugins: { updater: { active: true, dialog: false, dangerous-insecure-transport-protocol: true, endpoints: [http://127.0.0.1:8765/] } } }dangerous-insecure-transport-protocol允许通过明文 HTTP 拉取更新仅限本地测试createUpdaterArtifacts: true指示打包器产出可被更新器消费的工件。此外还支持两个覆盖参数--app-version 9.9.9通过 config merge 把不同版本烧录进二进制打包级 e2e 依赖它区分旧应用与服务端提供的新版--features a,b在official-build之上追加 cargo features例如打包测试追加e2e以启用本地驱动路由。签名私钥通过环境变量TAURI_SIGNING_PRIVATE_KEY/TAURI_SIGNING_PRIVATE_KEY_PATH/TAURI_SIGNING_PRIVATE_KEY_PASSWORD传入若外部已注入这些变量CI 场景则跳过本地signing/目录的生成。4.3 平台工件发现discoverBundle暂存前需要定位最新构建的 bundle按平台区分后缀平台目录匹配后缀macOSbundle/macos.app.tar.gzLinuxbundle/appimage.AppImage.tar.gzWindowsbundle/nsis.nsis.zip/.exe.zip/-setup.exe按 mtime 取最新文件并映射到 manifest 的platforms键darwin-aarch64、darwin-x86_64、linux-x86_64、windows-x86_64。4.4 manifest 清单生成prepare-manifest / stage-laststage-last从Cargo.toml正则解析当前版本/^version\s*\s*([^])/m然后调用prepare-manifest写出清单const manifest { version, notes: Local signed bundle **${base}** (staged). Delete when done testing., pub_date: new Date().toISOString().replace(/\.\d{3}Z$/, Z), platforms: { [hostPlatformKey()]: { signature, url } }, };其中url指向本地服务器http://127.0.0.1:8765/artifacts/文件名signature读取自bundle.sig文件。该格式与tauri-plugin-updater期望的 manifest 结构一致version / notes / pub_date / platforms 四要素。手工定制时可直接用bun run prepare-updater-manifest --version SEMVER --bundle PATH [--sig PATH]4.5 本地更新服务器serveserve用Bun.serve监听127.0.0.1:8765提供三类路由GET /与GET /manifest.json返回 manifest JSON带Access-Control-Allow-Origin: *CORSGET /artifacts/name从artifacts/目录返回安装包二进制application/octet-stream并做路径穿越防护path.relative检查拒绝..越界其余返回 404非 GET 返回 405。五、进阶打包级端到端测试 packaged-update-restart.e2e.ts三步快速验证之外仓库还提供一个真实安装 重启的 macOS 端到端测试覆盖 wdio 无法触及的场景应用更新会 relaunch 并杀死共享 WebDriver 会话cd apps/screenpipe-app-tauri bun e2e/mock-updates/packaged-update-restart.e2e.ts # 重跑可跳过两次 release-local 构建 SP_PACKAGED_UPDATER_SKIP_BUILD1 bun e2e/mock-updates/packaged-update-restart.e2e.ts它依次构建 v9.9.9更新源与当前版本安装体通过隔离的 control 端口11461驱动托盘Restart to update的真实生产处理器断言 6 个场景IDLE-INSTALL未登录engine 未启动、boot phase 为 idle状态下完成暂存并成功重启到新版本——对应历史上重启静默无动作缺陷的回归FEEDBACK点击后菜单可见 Installing update… 反馈再退出TCC-SAFE退出路径安装不会把已授权 bundle 滞留在staged-update/replaced/previous.appPOST-UPDATE CAPTURE替换进程启动真实引擎并产出 ScreenCaptureKit 帧而非继承旧进程的权限拒绝状态POST-UPDATE更新标记被消费为已应用无暂存更新时点击不会杀掉应用FAILED-ATTEMPT DETECTION伪造from 当前版本的失败标记启动时菜单显示 Update didnt apply — click to retry。测试严格隔离专用数据目录 端口所有 kill 都按 workdir 路径匹配 PID保证不会误伤同机运行的正式 screenpipe 进程日志会保留到e2e/results/packaged-update-restart.log作为证据。六、与生产更新链路的对应关系本地 mock 流程并非测试专用玩具而是对生产链路的镜像。在 src-tauri/src/updates.rs 中可以看到真实端点构造fn consumer_update_channel(settings: OptionSettingsStore) - static str { match settings.map(|settings| settings.update_channel.as_str()) { Some(pre-release) pre-release, _ stable, } } fn consumer_update_endpoint(channel: str) - String { format!( https://screenpipe.com/api/app-update/{channel}/{{{{target}}}}-{{{{arch}}}}/{{{{current_version}}}} ) }对应地本地 manifest 的platforms键darwin-aarch64等正是生产 URL 中{target}-{arch}段的值signature/url结构与tauri-plugin-updater的解析逻辑一致。Cargo.toml 中的两个依赖也直接服务于更新链路的健壮性semver 1用于 updater 的版本序比较双更新防重入minisign-verify 0.2暂存更新包的二次签名复核与 updater 插件同 crate 同版本。此外Cargo.toml中定义了一个专门用于本套件的编译 profile[profile.release-local] inherits release lto false codegen-units 16 incremental true opt-level 1 debug false注释明确其用途Maximum-speed local builds for updater e2e harness — no optimization, fastest compile即以牺牲运行时性能换取最小编译时间。七、常见问题与排查建议stage-last报 no matching bundle先跑updater-local:build确认产物出现在src-tauri/target/release-local/bundle/对应平台目录应用检查更新无响应确认serve终端仍在运行、端口 8765 未被占用并用curl http://127.0.0.1:8765/manifest.json验证清单可达签名验签失败删除e2e/mock-updates/signing/目录重新生成密钥对并确保build与stage-last使用同一份密钥密钥轮换戳不匹配时会自动重建顺序颠倒导致更新源被旧版覆盖重新按先新版后旧版的顺序执行stage-last会在暂存时重新挑选最新工件需要调试应用侧更新日志更新状态与错误会写入应用数据目录下screenpipe-app.YYYY-MM-DD.log打包级测试也会把完整日志沉淀到e2e/results/。八、总结mock-updates 套件把 Tauri 自动更新这条容易黑盒化的链路变成了可在本机三分钟内复现的确定性流程build签名构建→stage-last暂存清单→serve本地服务→ 旧版本触发检查。它既服务于日常手工回归也支撑packaged-update-restart.e2e.ts这类打包级自动化验证并与生产端点/api/app-update/{channel}/{{target}}-{{arch}}/{{current_version}}保持格式与签名机制的一致。对任何需要为 Screenpipe 桌面端开发、测试或维护更新功能的开发者而言这份文档与配套 harness 都是直接可用的实战入口。【免费下载链接】screenpipeYC (S26) | Open Computer History | Record your screen continuously locally and provide context to your agents (Claude, Codex, Openclaw, Hermes, Runner...)项目地址: https://gitcode.com/GitHub_Trending/sc/screenpipe创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表