news 2026/10/16 9:13:29

MooTool Next Flutter 发布与更新通道指南:多产品仓库中的版本、打包、CI 与客户端更新机制

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MooTool Next Flutter 发布与更新通道指南:多产品仓库中的版本、打包、CI 与客户端更新机制
  • 桌面应用
  • 开发工具

【免费下载链接】MooTool

Handy tool set for developers

项目地址:https://gitcode.com/gh_mirrors/mo/MooTool
点击查看免费下载

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):

项目约定
产品 IDnext-flutter
版本来源next-flutter/pubspec.yaml中的version字段(当前为0.1.0+1)
Git tagnext-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/x64MooTool-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 x64MooTool-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.0

scripts/check-release.py 承担“发布身份三重校验”:

  1. 从 pubspec.yaml 的正则^version:\s*([0-9][^\s+]+)解析版本号;
  2. 校验release-notes/{version}.md存在,且首行标题同时包含产品名MooTool Next Flutter与版本号(对应 next-flutter/release-notes/0.1.0.md 的 H1 写法);
  3. 若传入--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,完整链路为:

  1. 启动触发:app_controller.dart 在应用启动且设置项autoCheckUpdates为 true 时静默调用checkForUpdates(quiet: true)。
  2. HTTP 拉取清单:update_models.dart 中defaultUpdateFeedUrl指向仓库根 update-manifest.json(当前托管在 master 分支),并要求必须 HTTPS。
  3. 解析与隔离:update_service.dart 首先校验identity.productId == Product.id(防止更新服务被编译进错误的产品线),再检查响应体非空且不超过 2 MB;随后以schemaVersion == 1、products为映射的前提解析清单,只取products['next-flutter']节点,且要求其status == 'active',否则视为未发布(unpublished)。
  4. 版本比较:使用 semver.dart 的语义化版本解析与比较;稳定版客户端会自动忽略prerelease版本,只有当前版本自身带预发布标识(如-beta.1)时才允许接收后续预发布。
  5. 资产选择: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 的发布纪律可归纳为四条:

  1. tag 隔离:一律使用next-flutter-v*,不碰 Java 的v*命名空间,不与其他产品共用 tag;
  2. Latest 隔离:make_latest: false,全局Latest只留给当前主力产品(Electron),测试版本必须标记 pre-release;
  3. CI 隔离:以 tag 前缀next-flutter-v*触发专属工作流,只构建、校验、收集next-flutter/目录的产物,从 tag 解析产品 ID 与版本号并校验与pubspec.yaml一致;
  4. 更新通道隔离:客户端只读取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

项目地址:https://gitcode.com/gh_mirrors/mo/MooTool
点击查看免费下载

相关推荐

上一篇:eslint-config-next 16 实战指南:为 Next.js 项目配置 ESLint 9 Flat Config
下一篇:WezTerm Lua API 深度指南:MuxTab 标签页对象完全解析

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/16 9:12:30

ChatGPT 图片生成入门:用文字描述做出可用的配图

ChatGPT 图片生成入门:用文字描述做出可用的配图适合人群:写博客、做 PPT、发公众号时需要配图,但不会设计软件,也不想到处找图担心版权的同学。按 OpenAI 帮助中心的说明,ChatGPT 的图片生成(ChatGPT Imag…

作者头像 李华
网站建设 2026/10/16 9:11:37

具身智能开源项目Open-RAIL:VLA/WAM技术栈与上手实践指南

1. 从"向全球开源"这四个字里,我读出了什么第一次看到"向全球开源"这个标题,配合 Open-RAIL、VLA/WAM、具身智能这几个关键词,我的直觉是:这大概率是一个面向机器人领域的开源项目发布,而且野心不…

作者头像 李华
网站建设 2026/10/16 9:11:29

工艺窗口优化:DoE实战找到最佳工艺参数

一、痛点背景:从一次真实的生产事故说起 工艺窗口优化:DoE实战找到最佳工艺参数这个问题,在FAB里不是一天两天了。我见过太多工程师踩坑:要么是方法用错导致数据误判,要么是工具选型失误导致项目延期,要么是流程设计有缺陷导致资源浪费。更要命的是,这些坑往往不是技术…

作者头像 李华