- 桌面应用
- 开发工具
【免费下载链接】MooTool
Handy tool set for developers
MooTool 采用“同一仓库、多个独立产品线”的发布方式,本文聚焦其中基于 Flutter 的桌面产品线MooTool Next Flutter(产品 IDnext-flutter),系统讲解从版本来源、Git tag、安装包产物、本地打包与校验、CI 发布流水线,到客户端更新检查与下载安装的完整链路。读完本文,你将掌握在 monorepo 中为一条独立产品线发版的全过程,并理解其“未签名发布 + SHA-512 校验 + 手动安装”的更新协议设计。
本文主体依据 next-flutter/docs/release.md 展开,并结合作品线目录 next-flutter/ 中的脚本、Dart 源码、测试与 .github/workflows/next-flutter-build.yml 给出源码级佐证。
一、发布身份:产品 ID、版本来源与 Git tag
MooTool Next Flutter 是一条与 Java、Electron、Tauri、macOS Native 平级的独立产品线,其发布身份信息定义如下(见 next-flutter/docs/release.md):
| 项目 | 约定 |
|---|---|
| 产品 ID | next-flutter |
| 版本来源 | next-flutter/pubspec.yaml中的version字段(当前为0.1.0+1) |
| Git tag | next-flutter-v{semver},例如next-flutter-v0.1.0 |
| Release 标题 | MooTool Next Flutter {version} |
Latest标记 | make_latest: false(不得占用全局 Latest) |
在源码中,这些身份常量集中定义于 next-flutter/lib/app/product.dart:Product.id = 'next-flutter'、displayName = 'MooTool Next Flutter'、applicationId = 'com.rememberber.mootool.next.flutter'、tagPrefix = 'next-flutter-v'。其中applicationId同时用于 macOS 的用户数据目录命名,保证与 Java 等其他产品严格隔离。
tag 前缀为什么必须有
根据仓库根目录的总约定 RELEASE_CONVENTIONS.md,Git tag 在整个仓库内必须唯一。历史 Java 产品线已占用无前缀的v1.0.0~v1.7.9命名空间,因此新产品一律使用“产品 ID +-v”前缀。next-flutter-v0.1.0与 Electron 的next-electron-v1.0.0、macOS Native 的next-macos-native-v*互不冲突;同一仓库可以同时存在多个相同语义版本的 tag,因为它们属于不同产品线。
此外,RELEASE_CONVENTIONS.md 还要求:每个 tag 对应且仅对应一个产品版本的 Release;Release 只上传当前产品的安装包和更新元数据;Release Notes 只能比较同一产品线的前后两个 tag。
二、安装包矩阵与命名规则
next-flutter/docs/release.md规定的发布产物如下:
| 平台 | 文件 |
|---|---|
| macOS arm64/x64 | MooTool-Next-Flutter-{version}-mac-{arch}.dmg |
| Windows x64 安装版 | MooTool-Next-Flutter-{version}-win-x64-setup.exe |
| Windows x64 便携版 | MooTool-Next-Flutter-{version}-win-x64-portable.zip |
| Linux x64 | MooTool-Next-Flutter-{version}-linux-x64.AppImage、同前缀.deb |
这些文件名并非随手命名,而是由更新模块中的PackageNames类统一生成并约束(见 next-flutter/lib/core/update/package_names.dart):
- macOS 只允许
dmg包型,架构aarch64归一为arm64、amd64/x86_64归一为x64; - Windows 只接受
nsis(安装版)与portable/zip(便携版)两种包型; - Linux 只接受
appimage与deb两种包型。
scripts/verify-package.py 用正则^MooTool-Next-Flutter-(版本)-(mac-(arm64|x64)\.dmg|win-x64-(setup\.exe|portable\.zip)|linux-x64\.(AppImage|deb))$对构建产物逐一对号入座,同时计算 Base64 形式的 SHA-512 摘要并输出文件大小——这套“文件名 → 平台/架构/包型”的映射与更新客户端的选择逻辑完全同源,避免发布端与客户端对资产描述出现分叉。
全部未签名,需用户手动确认
所有安装包均未签名。macOS 上 Gatekeeper 会拦截,用户需在 Finder 中右键选择“打开”;Windows 可能触发 SmartScreen 提示。这是产品线的既定策略,CI 中也以 warning 显式标注(见后文),并据此设计了客户端的“下载 → 校验 → 手动安装”更新协议,而不是应用内自动静默安装。
三、本地构建与发布前校验
1. 打包入口
在仓库根目录下的 next-flutter/scripts/package.sh 是对外的统一打包入口,它按参数分派到平台专属脚本:
cd next-flutter ./scripts/package.sh macos # 需要完整 Xcode ./scripts/package.sh windows # 在 Windows 上 ./scripts/package.sh linux # 在 Linux 上package.sh内部逻辑非常克制:只接受macos|windows|linux三个参数,其余参数直接打印 usage 并退出;且明确“Packages are unsigned. Missing platform toolchains fail instead of faking an installer.”——即必须在本机具备对应平台工具链,缺工具链时报错退出,而不是伪造一个空壳安装包。脚本分派到的build-macos.sh、build-windows.sh、build-linux.sh在 scripts 目录内与package.sh同级(后三者通过exec调起),产物统一输出到next-flutter/dist/。
2. 版本与发布说明一致性校验
python3 scripts/check-release.py --root . --tag next-flutter-v0.1.0scripts/check-release.py 承担“发布身份三重校验”:
- 从 pubspec.yaml 的正则
^version:\s*([0-9][^\s+]+)解析版本号; - 校验
release-notes/{version}.md存在,且首行标题同时包含产品名MooTool Next Flutter与版本号(对应 next-flutter/release-notes/0.1.0.md 的 H1 写法); - 若传入
--tag,校验其严格等于next-flutter-v{version}。
这个脚本同样被 CI 的checkjob 使用:普通提交用check-release.py --root .,tag 提交追加--tag "${{ github.ref_name }}",从而在发布流水线入口就杜绝 tag 与版本来源漂移。
3. 质量检查与本地运行
配套的开发/检查脚本还包括:
- scripts/check.sh:
flutter pub get+dart format --set-exit-if-changed+flutter analyze+flutter test test/unit,是提交前与 CIcheckjob 等价的质量门槛; - scripts/run.sh:
flutter run -d macos,支持传入--data-dir指定独立数据目录(通过--dart-define=FLUTTER_APP_DATA注入),方便在隔离环境做升级测试。
四、CI 发布流水线:tag 触发、三平台构建、非 Latest 发布
产品线 CI 定义在 .github/workflows/next-flutter-build.yml,与RELEASE_CONVENTIONS.md的“发布工作流必须通过 tag 前缀触发,而不是根据整个仓库的最高版本判断产品”原则一致:
- 触发条件:push 到
next-flutter/**路径或.github/workflows/next-flutter-build.yml自身,以及 tagnext-flutter-v*;PR 路径过滤相同;另支持workflow_dispatch手动触发打包。 - check job(ubuntu-latest):安装 stable Flutter,依次执行
check-release.py(含 tag 一致性校验)、flutter pub get、dart format检查、flutter analyze、flutter test test/unit。tag 提交还会输出一条醒目的 warning:next-flutter packages are intentionally unsigned...。 - package-macos / package-windows / package-linux:分别在三平台 runner 上构建 DMG、setup.exe + portable.zip、deb + AppImage。macOS 构建显式设置
CSC_IDENTITY_AUTO_DISCOVERY: 'false'与CODE_SIGNING_ALLOWED: 'NO'来确保产出未签名包;Linux 额外安装clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev等 Flutter 桌面构建依赖。产物以next-flutter-{平台}为名上传 artifact。 - release job:下载三个 artifact,从
pubspec.yaml动态读取版本号,以next-flutter/release-notes/{version}.md为 Release Notes,执行gh release create "${{ github.ref_name }}" --latest=false,标题为MooTool Next Flutter ${version}。
关键约束再次出现在 release job 末尾的 warning 中:CI 不会更新根目录 update-manifest.json——“Enable the next-flutter node only after assets are reachable. make_latest is false.”也就是说,即使 Release 已发布,客户端更新清单也要等到安装包确实可下载后才启用(详见下节)。
五、客户端更新通道:只读next-flutter节点,下载校验后手动安装
1. 更新检查的数据流
客户端更新逻辑位于 next-flutter/lib/core/update/ 与 next-flutter/lib/app/app_controller.dart,完整链路为:
- 启动触发:app_controller.dart 在应用启动且设置项
autoCheckUpdates为 true 时静默调用checkForUpdates(quiet: true)。 - HTTP 拉取清单:update_models.dart 中
defaultUpdateFeedUrl指向仓库根 update-manifest.json(当前托管在 master 分支),并要求必须 HTTPS。 - 解析与隔离:update_service.dart 首先校验
identity.productId == Product.id(防止更新服务被编译进错误的产品线),再检查响应体非空且不超过 2 MB;随后以schemaVersion == 1、products为映射的前提解析清单,只取products['next-flutter']节点,且要求其status == 'active',否则视为未发布(unpublished)。 - 版本比较:使用 semver.dart 的语义化版本解析与比较;稳定版客户端会自动忽略
prerelease版本,只有当前版本自身带预发布标识(如-beta.1)时才允许接收后续预发布。 - 资产选择:update_service.dart 的
selectUpdateAsset按客户端平台(darwin/win32/linux)、架构(arm64/x64,支持universal回退)与包型偏好(macOS 仅dmg,Windows 优先nsis后portable,Linux 优先appimage后deb)挑选下载项,同时支持priority字段参与排序。
2. 下载、SHA-512 校验与手动安装
update_downloader.dart 对下载做三重防护:
- HTTPS 强制:URL scheme 非
https直接抛错; - 大小校验:下载字节数与清单
size必须一致; - SHA-512 校验:对下载内容计算 SHA-512,Base64 结果必须等于清单中
sha512字段(格式由正则^[A-Za-z0-9+/]{86}==$校验)。
校验通过后先写入带.download后缀与 pid 的临时文件,再重命名到最终路径(cache/updates/{fileName}),避免半截文件被误用。之后客户端调用openLocalPath打开安装包:macOS 用open、Windows 用cmd /c start、Linux 用xdg-open,只负责唤起系统安装流程,绝不宣称自动安装成功。对应到 app_controller.dart 的状态机:idle → available → downloading → ready,下载完成提示语为“updateReadyUnsigned”,并支持用户取消下载(cancelUpdateDownload)。
3. 没有匹配资产时只打开发布页
当清单中不存在next-flutter节点、节点未激活,或当前平台/架构没有匹配资产时,UpdateCheckResult落入unpublished或“无资产”状态:客户端不做下载,而是直接打开defaultReleaseUrl(产品 Releases 页面),由用户从页面手动选择安装包。这正是 0.1.0 阶段的实际行为——next-flutter/release-notes/0.1.0.md 明确记载“资产可访问前不写更新清单节点”,因此根目录 update-manifest.json 当前仅含java与next-electron两个产品节点,next-flutter节点待首个 Release 资产就绪后再启用。
4. 设置项
更新行为由 next-flutter/lib/app/settings.dart 中的autoCheckUpdates(默认false)与autoDownloadUpdates(默认false)控制,前者决定启动时是否静默检查,后者决定发现可用更新后是否立即自动下载安装包(注意:自动下载不等于自动安装,最终仍由用户手动打开安装包)。
六、用户数据隔离与卸载清理
作为“可与其他产品同时安装”的独立产品线,Next Flutter 的数据目录与其他实现严格错开(见 next-flutter/lib/app/app_paths.dart 的defaultDataRoot()):
| 平台 | 数据根目录 |
|---|---|
| macOS | ~/Library/Application Support/com.rememberber.mootool.next.flutter |
| Windows | %APPDATA%\MooToolNextFlutter |
| Linux | $XDG_DATA_HOME/mootool-next-flutter(未设置时为~/.local/share/mootool-next-flutter) |
app_paths.dart中的verifyIsolation()会在启动时校验数据根路径,禁止其复用MooToolNextElectron、mootool-next-electron、MooToolNextTauri、.MooTool、MooTool等其他产品的目录,也不允许读取到productId不等于next-flutter的product.json——这是更新通道隔离之外的又一层数据隔离防线。
next-flutter/docs/release.md对卸载给出了明确纪律:
- Windows 卸载项名称独立,不会与其他产品混淆;
- 删除用户数据需由用户自行清理上述三个平台的数据目录;
- 发布/清理脚本不得遍历删除
MooTool*通配目录,防止误伤同仓库其他产品的数据。
七、多产品发布约定中的定位总结
把 next-flutter/docs/release.md 放回 RELEASE_CONVENTIONS.md 的总框架中,Next Flutter 的发布纪律可归纳为四条:
- tag 隔离:一律使用
next-flutter-v*,不碰 Java 的v*命名空间,不与其他产品共用 tag; - Latest 隔离:
make_latest: false,全局Latest只留给当前主力产品(Electron),测试版本必须标记 pre-release; - CI 隔离:以 tag 前缀
next-flutter-v*触发专属工作流,只构建、校验、收集next-flutter/目录的产物,从 tag 解析产品 ID 与版本号并校验与pubspec.yaml一致; - 更新通道隔离:客户端只读取
update-manifest.json中products['next-flutter']节点,不读取、不写入其他产品节点,也不以仓库级/releases/latest判断更新。
这套机制保证了 MooTool Next Flutter 与 Java、Electron、Tauri、macOS Native 可以互不干扰地同仓演进、独立发版、同时安装,而 next-flutter/docs/release.md 正是这条产品线发布与更新协议的“一句话权威入口”——版本号、包名、构建命令、CI 触发规则、更新行为与卸载边界,都在这一页以内。
- 桌面应用
- 开发工具
【免费下载链接】MooTool
Handy tool set for developers
相关推荐
MooTool Next Flutter 桌面版开发指南:环境搭建、数据隔离、打包与更新通道
MooTool Next Flutter 桌面版开发指南:环境搭建、数据隔离、打包与更新通道 MooTool Next Flutter 是 MooTool 开源
桌面应用开发工具MooTool Next Flutter P7 产品化验收:只读更新通道、SHA-512 校验与未签名安装包工程化
MooTool Next Flutter P7 产品化验收:只读更新通道、SHA 512 校验与未签名安装包工程化 本文以 MooTool 仓库内 P7 验收报
桌面应用开发工具MooTool Next Flutter 0.1.0 P7 构建环境解析:Xcode 约束、未签名打包与只读更新通道
MooTool Next Flutter 0.1.0 P7 构建环境解析:Xcode 约束、未签名打包与只读更新通道 本文依据 MooTool 仓库中 P7 环
桌面应用开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考