7.8 KiB
description, icon, lang
| description | icon | lang |
|---|---|---|
| 发布节奏、版本策略、OAuth 与安装包规则。发布是如何运作的。 | ship | zh-CN |
发布策略:最新桌面构建与 OAuth
本 runbook 描述了我们如何避免用户在过时的桌面安装包上完成 OAuth(包括 Gmail),而规范流程始终要求最新发布版本。
分发
- tinyhumansai/openhuman 的 GitHub Releases 是桌面构建的主要来源。
- Tauri 更新器端点(见
scripts/prepareTauriConfig.js和发布工作流)应将用户指向当前发布产物。 - 淘汰旧稳定版产物: 当弃用一条发布线时,在 GitHub Releases 上移除或隐藏过时的安装包资源,将 网站 / CDN 下载链接更新为 releases/latest(或当前版本),刷新更新器 manifest(例如 Gist /
latest.json)使其不再指向已弃用的构建,并抽查旧直接 URL 在适当位置是否被重定向、返回 404 或 410。验证方式:尝试从文档或书签中已知的旧资源 URL,确认它们不再提供主要安装路径。
OAuth 最低应用版本
生产 Web 构建在构建时嵌入一个最低支持的应用 semver,使 OAuth 深度链接无法在已弃用的二进制文件上完成。每个安装包携带构建时设定的 floor;对于从不升级的用户,提高 floor 需要他们安装一个新的发布版本(或通过应用内更新)。可选的未来工作:仅通过运行时 API 强制执行移动的最低版本,捆绑值仅作为 fallback。
| 变量 | 用途 |
|---|---|
VITE_MINIMUM_SUPPORTED_APP_VERSION |
例如 0.51.0 —— 桌面应用必须 ≥ 此版本才能完成 openhuman://oauth/success。 |
VITE_LATEST_APP_DOWNLOAD_URL |
可选;默认为 https://github.com/tinyhumansai/openhuman/releases/latest。当门禁阻止 OAuth 时打开。 |
将这些配置为 GitHub Actions 变量。它们必须同时存在于独立的 pnpm build 步骤和 .github/workflows/build-desktop.yml 中的 tauri-apps/tauri-action 步骤环境变量中(由 release-production.yml / release-staging.yml 调用的可重用矩阵),以便嵌入已发布安装包的 Vite bundle 包含该门禁。本地开发时保持 VITE_MINIMUM_SUPPORTED_APP_VERSION 未设置(门禁禁用)。
实现:app/src/utils/oauthAppVersionGate.ts、app/src/utils/desktopDeepLinkListener.ts。
Gmail / Google Cloud OAuth
- Google Cloud Console 中的 Redirect URIs 必须匹配当前后端 + 隧道回调路径。
- 桌面 scheme(
openhuman://)是稳定的;当VITE_MINIMUM_SUPPORTED_APP_VERSION设置时,已安装的二进制文件必须满足最低版本。
发布清单(避免回归)
- 按照现有版本工作流提升
app/package.json和app/src-tauri/tauri.conf.json(以及根目录Cargo.toml/ core)的版本。 - 当弃用对旧安装包的支持时,在该发布之前或同时将
VITE_MINIMUM_SUPPORTED_APP_VERSION设置为新的 floor(仓库 Actions 变量 + 上述两个工作流步骤)。 - 从用户可见表面(GitHub Release 资源、网站、CDN、更新器 feed)移除、重定向或淘汰旧稳定版安装包和陈旧更新器条目。确认已弃用的资源无法从默认安装/更新流程中访问。
- 从 releases/latest 的全新安装上冒烟测试 Gmail 连接。
- 完成手动冒烟清单,然后将完成的签字块(逐字复制,每个已勾选项目保持勾选)粘贴到发布 PR 描述中,然后再打 tag。
工作流:staging vs. production
两个一等 GitHub Actions 工作流,每个环境一个。按意图选择,而非切换 flag。
| 工作流 | 分支 | 提升 | 推送的 Tags | 并发组 | 使用场景 |
|---|---|---|---|---|---|
release-staging.yml |
main |
仅 patch |
v<version>-staging |
release-staging |
为 QA 切割 staging 构建。运行频繁;semver 移动范围窄。 |
release-production.yml |
main |
patch / minor / major(仅在 main_head 上) |
v<version> |
release-production |
提升已验证的 staging tag,或从 main HEAD 热修。 |
两个流程使用的矩阵构建 / 签名 / Sentry-DIF / 产物上传流水线位于 .github/workflows/build-desktop.yml 中,作为 workflow_call 可重用工作流。上述两个顶层工作流拥有 ref 解析、版本提升、tagging 和发布/清理;构建本身是共享的。
切割 staging 构建
- 通过
workflow_dispatch从main运行 Release (Staging)。 - 工作流在
main上提升patch,commitchore(staging): vX.Y.Z,推送分支,并在该 commit 上创建不可变的vX.Y.Z-stagingtag。 - 构建矩阵从 tag(而非 main HEAD)运行,因此即使
main已经前进,rerun 也会重建字节相同的内容。 - 失败时 staging tag 会被自动删除;
main上的提升 commit 保留,因此下一次切割从vX.Y.(Z+1)继续。
没有单独的 staging 分支,staging 切割和 production 提升都存在于 main 上。两者仅通过 tag 后缀(-staging vs 无)和创建工作流来区分。
提升为 production(默认流程)
- 通过
workflow_dispatch以release_source = staging_tag(默认)运行 Release Production。 - 留空
staging_tag以提升最新的v*-staging,或传入显式 tag(例如v1.2.4-staging)以固定版本。 - 工作流去除
-staging后缀,在同一 commit 上创建v<version>,并从该 tag 运行 production 构建矩阵。不再提升版本,产物复用 staging 已验证的内容。
从 main HEAD 热修
- 通过
workflow_dispatch以release_source = main_head和所需的release_type(patch/minor/major)运行 Release Production。 - 工作流运行遗留的提升-and-tag 路径:在
main上提升,commitchore(release): vX.Y.Z,推送,tagvX.Y.Z,构建。 - 仅当需要不经过 staging 的 production-only 修复时才使用此路径。
Tag 策略与回滚
- 命名。 Staging tag 使用 SemVer 预发布后缀
-staging(v1.2.4-staging),因此它们在排序上位于匹配的 production tag 之前。提升到 production 时逐字去除后缀;两个 tag 之间捆绑安装包中嵌入的版本是相同的。 - 冲突。 如果目标 tag 已存在于本地或
origin上,两个工作流都会快速失败。通过删除陈旧 tag(仅限组织维护者)或跳过它来解决。 - 回滚(production)。 失败的构建矩阵会触发
cleanup-failed-release,删除草稿 GitHub Release 和v<version>tag。它从中提升的 staging tag 保持不变,修复后可以重新提升。 - 回滚(staging)。 失败的 staging 构建会删除
v<version>-stagingtag。main上的提升 commit 保留;下一次 staging 切割从新的 patch 号继续,而不是重新使用它(我们接受 patch 号中的一个小"缺口",而不是与并发合并竞争)。 - 谁可以删除 tag。 与
main相同的写入权限。工作流驱动的清理通过工作流的 token 使用actions/github-script运行删除(GitHub App token 仅由prepare-build用于提升 commit + tag 推送);手动删除(git push --delete origin <tag>)需要同等的维护者权限。