构建、发布与版本
构建、发布与版本
应用更新检查、安装包下载和 SHA-256 校验见 updater-and-downloads.md。
.NET 要求
主应用目标框架:
<TargetFramework>net10.0-windows10.0.20348</TargetFramework>构建前需要 .NET 10 SDK。安装包脚本中会检查并安装 .NET 10 Desktop Runtime,当前依赖脚本阈值是 10.0.9。SmartBP 模块打包工具同样运行在 .NET 10 下。
手动 publish
README 中的基础构建命令:
dotnet publish ".\neo-bpsys-wpf\neo-bpsys-wpf.csproj" -c Release -o ".\build\neo-bpsys-wpf"主项目 csproj 会在 Build/Publish 后构建并复制内置插件到输出目录的 Plugins\...。
WebRenderer 前端构建
WebRenderer 插件的前端由 Host sidecar 的 MSBuild target 调用 pnpm 构建(pnpm install --frozen-lockfile + pnpm run build),构建机需要 pnpm + Node.js。
普通 Debug Build 在 pnpm 不可用或前端失败时警告并省略整个 WebRenderer 插件。Release、Beta、Preview Build 以及默认 Publish 必须具备完整前端与 sidecar 产物,否则失败。
显式传入 -p:WebRendererSkipWebBuild=true 可省略整个 WebRenderer,包括直接 Publish 的精简产物;不会复用旧前端或旧插件输出。该选项适用于本地业务调试。RequireWebRenderer=true 表示必须包含 WebRenderer,与显式跳过同时设置时报错。
官方 build.ps1(含 Beta/Preview wrapper)强制 RequireWebRenderer=true、WebRendererSkipWebBuild=false,并在调用安装器前检查最终插件 DLL、manifest、Host 程序、前端 index 和 JS。Actions 使用同一脚本,不能将缺件发布降级为成功。仅检查 wwwroot 目录存在不足以证明构建完整。
构建脚本
根目录脚本:
| 脚本 | 配置 |
|---|---|
build.ps1 / build.bat | Release,默认配置 |
build.ps1 -Configuration Beta / build_beta.bat | Beta |
build.ps1 -Configuration Preview / build_preview.bat | Preview |
build_beta.ps1 / build_preview.ps1 | 兼容 wrapper,只转调 build.ps1 -Configuration ... |
build.ps1 是唯一真实构建实现,-Configuration 可选 Release、Beta、Preview,默认 Release。三种配置都会执行完整产物流程:
- 切到仓库根目录。
- 创建
build\neo-bpsys-wpf。 - 用
git rev-parse --short=7 HEAD获取BuildMeta。 - 按
win-x64、SelfContained=false执行主应用dotnet restore。 - 按同一 RID 和 self-contained 配置执行内置插件
TeamJsonMaker的dotnet restore。 - 按同一 RID 和 self-contained 配置执行主应用
dotnet publish。 - 检查
neo-bpsys-wpf.exe是否存在。 - 从
neo-bpsys-wpf.exe的ProductVersion读取本次 tag。 - 调用
Installer\Inno Setup 6\ISCC.exe构建 lite 安装包。 - 计算
neo-bpsys-wpf_Installer.exe.sha256。 - 按
win-x64、SelfContained=false执行 SmartBP 模块项目dotnet restore。 - 按同一 RID 和 self-contained 配置执行 SmartBP 模块项目
dotnet publish到build\SmartBpModule。 - 读取模块 staging 的
component.json版本,在剔除宿主已提供的文件后生成Integrity.Version = 1文件清单并写回 staging 清单。 - 用仓库内官方 x64 7-Zip(
third_party/7zip/win-x64/7z.exe)从同一 staging 目录生成SmartBpModule.7z和SmartBpModuleManifest.json。 - 调用
Installer/build_Installer_full.iss构建 full 安装包。 - 计算
neo-bpsys-wpf_Installer_full.exe.sha256。
所有配置预期产物:
neo-bpsys-wpf_Installer.exe
neo-bpsys-wpf_Installer.exe.sha256
neo-bpsys-wpf_Installer_full.exe
neo-bpsys-wpf_Installer_full.exe.sha256
SmartBpModule.7z
SmartBpModuleManifest.jsonneo-bpsys-wpf_Installer.exe 是 lite 默认安装包,也是旧 updater 固定目标。它不包含 SmartBP 的 OpenCvSharp、PaddleOCR、PaddleInference 和具体实现 DLL。neo-bpsys-wpf_Installer_full.exe 是首次安装便利包,包含 lite 应用和 SmartBP 模块 staging 文件,并在安装时写入 %APPDATA%\neo-bpsys-wpf\SmartBpModuleState.json。
SmartBpModule.7z 和 full 安装包必须来自同一个 build\SmartBpModule staging 目录,避免 release 模块包与 full installer 内置模块不一致。官方 SmartBP 模块 release artifact 是 SmartBpModule.7z;运行时仍兼容旧 SmartBpModule.zip 包。
build.ps1 的 Write-SmartBpModuleIntegrity 根据最终 staging 文件自动生成 Integrity.Files:每项包含 / 分隔的相对 Path、字节 Size 和 Sha256。同一份清单同时嵌入包内 component.json、full 安装器文件和远程 SmartBpModuleManifest.json。清单不包含 component.json 自身,也不包含可变资产 OCRModels/、tessdata/、AI/、Runtime/Paddle/cuda/、Runtime/Paddle/Dependencies/、Runtime/Paddle/Downloads/、PaddleRuntimeDownload/。不要手工把生成的清单写进模块项目源码中的 component.json;普通开发构建仍使用旧包关键文件探针。
清单大小随发布文件数量增长,与 DLL、模型的容量无关。本地及远端清单上限为 8 MiB(SmartBpModuleConstants.MaxManifestBytes),构建时对包内和远端清单执行相同字节数限制。运行时直接从 UTF-8 流反序列化,不先构造整份 UTF-16 字符串;本地清单在读取前检查长度,网络响应的缓冲上限同样覆盖无 Content-Length 的响应。网络 I/O 异步执行,JSON 解析和本地校验在后台执行;UI 版本标签复用成功加载时的版本,不重新读取或校验整份清单。
加载、解压导入及目标卷副本切换前在后台验证清单中的文件大小和 SHA-256,缺失、截断或等长内容损坏都不能进入模块运行时。页面路径检查只验证大小,不重复读取大型 DLL。旧包没有 Integrity 时保留旧格式,执行关键托管依赖、CPU native 库和内置区域配置探针;不生成伪摘要,也不改写旧清单。旧包探针不等价于完整逐文件校验,修复安装的新包才提供发布文件全量摘要。
SmartBP 模块通过在线下载、设置页导入或 SmartBP 页面手动导入 .7z / .zip 升级时,只替换模块程序文件;模块目录下的托管 OCR 资产根目录 OCRModels/ 和 tessdata/ 会原地保留。这里包含 PaddleOCR、RapidOCR 模型和 Tesseract traineddata。Runtime/Paddle/cuda/、Runtime/Paddle/Dependencies/、Runtime/Paddle/Downloads/ 和 PaddleRuntimeDownload/ 也作为已安装资产保留,覆盖 Paddle CUDA、CUDA/cuDNN 依赖和下载缓存;升级包带有同名文件时仍保留原有内容。lite/full 安装器使用相同的目录排除规则,full 更新默认复用已记录的模块位置。即使归档包误带同名资产目录,也不得覆盖用户已经下载好的 OCR 资产。
SmartBP 模块版本独立维护在模块源码的 component.json,build.ps1 从发布后的该文件读取 ModuleVersion 并写入 SmartBpModuleManifest.json。更新检查使用已加载模块的 component.json 版本,通过 .NET Version 做数值比较,支持 26.10.19 和 26.10.19.1 这样的三段、四段版本号,后者会被识别为前者的更新版本。full 安装器写入的初始 SmartBpModuleState.ModuleVersion 仍使用主程序 ProductVersion;模块成功加载后以 component.json 中的实际模块版本更新该状态。
模块下载 URL 使用本次构建确定的 release tag,也就是主程序 ProductVersion。正式 GitHub Actions 发布时同样读取安装包 ProductVersion 并作为 tag_name,因此 manifest 内不再保留 {tag} 占位。模块版本递增不会改变主程序版本或 release tag;在线更新仍查询当前主程序 tag 对应的模块 manifest。
SmartBP 模块打包使用仓库内官方 x64 7-Zip(third_party/7zip/win-x64/7z.exe),构建机器不需要安装 7-Zip。运行时解压由随应用发布的官方 7-Zip 完成(位于 <AppBase>/Tools/7Zip/),用户不需要单独安装 7-Zip。应用仅发布 win-x64。
插件包可以是 .zip 或 .7z,安装时同样由运行时归档服务探测并解压。.bpui / Designer v3 布局包导入导出行为不随 SmartBP/插件归档支持变化,仍按 BPUI 文档描述处理。
Inno Setup
安装脚本:
Installer/build_Installer.isslite 安装脚本从发布产物 exe 提取版本号,输出:
build/neo-bpsys-wpf_Installer.exefull 安装脚本:
Installer/build_Installer_full.iss输出:
build/neo-bpsys-wpf_Installer_full.exe安装包允许 x64 compatible 架构,lite 安装包复制 publish 目录全部内容和 LICENSE。full 安装包额外复制 SmartBP 模块 staging 目录,并提供模块安装路径页面。模块路径会阻止 Program Files、Program Files (x86)、Windows、System32、驱动器根目录等不适合写入或维护的位置。InitializeSetup 调用 Dependency_AddDotNet100Desktop,依赖脚本检查 Microsoft.WindowsDesktop.App 10.0.9 或更高修订。卸载时询问是否删除 %APPDATA%\neo-bpsys-wpf。
构建配置
主项目定义:
<Configurations>Debug;Release;Beta;Preview</Configurations>| 配置 | 行为 |
|---|---|
| Release | 默认正式构建 |
| Beta | 定义 BETA,版本后缀 -beta,IsFindPreRelease 默认 true |
| Preview | 定义 PREVIEW,版本后缀 -preview,优化关闭、调试符号开启 |
| Debug | 开发调试 |
App.xaml.cs 的启动更新检查条件为 #if !DEBUG && !PREVIEW,与项目定义的 PREVIEW 一致。Debug 和 Preview 不编译该检查分支。
版本概念
| 概念 | 位置 | 说明 |
|---|---|---|
| 应用版本 | neo-bpsys-wpf.csproj 的 VersionPrefix/VersionSuffix | 应用发布版本 |
| BuildMeta | 构建脚本传入 /p:BuildMeta=$GitHash | 写入 InformationalVersion |
| 插件 API 版本 | 插件 manifest.yml 的 apiVersion | 宿主加载兼容性判断 |
| PluginSdk 源码引用版本 | 插件项目引用的 neo-bpsys-wpf.PluginSdk 仓库提交 | 编译和打包 SDK 来源 |
| 插件自身版本 | 插件 manifest.yml 的 version | 市场更新比较 |
应用版本迭代:首位用于大型重构/重大更改(例如赛事规则或 UI 重构);第二位用于重大模块更新或第三位满十跟进;第三位随新 Feature 递增;BuildMeta 使用 git 短 hash,本地构建为 local。此规则与主项目注释一致。
v3 起不再发布 PluginSdk NuGet 包,也不再通过 GitHub Actions 推送 PluginSdk nupkg。插件开发应 clone 本仓库并用 ProjectReference 引用 neo-bpsys-wpf.PluginSdk,必要时固定到具体 git 提交。
