From 01b06abc2c2c1c30a057c088c6061081c281a19d Mon Sep 17 00:00:00 2001 From: SkyJourney Date: Tue, 4 Aug 2026 12:25:02 +0800 Subject: [PATCH] =?UTF-8?q?release:=20=E5=8F=91=E5=B8=83=E5=AD=97=E4=BD=93?= =?UTF-8?q?=E7=9B=B4=E6=8E=A5=E5=86=85=E7=BD=AE=E7=89=88=20v0.6.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增能力:14 套主题按纵横方向与五组页边距组成的 140 场景视觉矩阵全部通过,封面执行整页严格门禁,正文执行分页无关的语义块门禁。 问题修复:统一 CSS 到 WordprocessingML 的通用翻译,修复字体嵌入、中文标点字距、精确行距、打印媒体与行内代码连续性,不包含按主题 ID 的特调。 发行变化:Desktop 安装器与免安装 ZIP 直接内置 Serif、Sans、Mono 三套字体包;NSIS 移除字体选择和伴随安装逻辑,不再发布独立字体安装器或字体 ZIP。正式附件收敛为 Desktop 安装器、Desktop ZIP、Docker 离线镜像、Web 部署包和发行说明。 部署兼容:Docker 镜像 md-to-pdf:v0.6.1 使用完整无缓存路径构建,固定 Chromium、Pandoc 3.9.0.2 和三套内置字体包;支持覆盖安装 v0.6.0,Windows 安装器保持未签名的内部发布状态。 验证结果:116 个测试文件、616 项测试、全项目类型检查、生产构建和 git diff --check 全部通过;140/140 视觉矩阵阻断失败和诊断失败均为 0;源码服务、Docker Web API 与实际安装 Desktop 的 DOCX 字体嵌入链路均通过。 --- apps/desktop/README.md | 4 + apps/desktop/build/installer.nsh | 82 ------------------- apps/desktop/tests/release-build.test.ts | 15 +++- docs/PROGRESS.md | 18 ++-- docs/RELEASE.md | 7 +- docs/releases/v0.6.1.md | 10 ++- font-packs/README.md | 5 +- package.json | 2 +- ...ont-pack.mjs => build-desktop-release.mjs} | 2 +- scripts/stage-release.mjs | 29 ------- scripts/stage-release.test.mjs | 13 +-- 11 files changed, 47 insertions(+), 140 deletions(-) rename scripts/{build-desktop-with-font-pack.mjs => build-desktop-release.mjs} (90%) diff --git a/apps/desktop/README.md b/apps/desktop/README.md index 0d26372..31b27d6 100644 --- a/apps/desktop/README.md +++ b/apps/desktop/README.md @@ -62,6 +62,10 @@ npm run verify:pandoc-runtime -w @md-to-pdf/desktop 辅助包;当前未配置代码签名,Windows 首次运行可能显示“未知发布者” 提示。 +Serif、Sans、Mono 三套正式字体随 NSIS 安装包和便携 ZIP 直接进入 +`resources/font-packs`,由应用私有加载,不写入 Windows 系统字体目录。 +安装向导不再提供字体选择页,正式发行也不附带独立字体安装器或字体 ZIP。 + NSIS 使用标准辅助安装模式,支持选择当前用户/所有用户安装和自定义安装 目录,并创建桌面及开始菜单快捷方式。正式安装包作为 Gitea Release 附件 发布,不提交进 Git 历史。 diff --git a/apps/desktop/build/installer.nsh b/apps/desktop/build/installer.nsh index d93f28e..bd24d53 100644 --- a/apps/desktop/build/installer.nsh +++ b/apps/desktop/build/installer.nsh @@ -9,70 +9,6 @@ ; 独立键可让 v0.6.0 默认进入 MorphDoc 目录,同时仍由相同卸载身份识别旧版。 !define INSTALL_REGISTRY_KEY "Software\${APP_GUID}.MorphDoc" -!ifdef FONT_PACK_COMPANION_FILE -!ifndef BUILD_UNINSTALLER - !include "FileFunc.nsh" - !include "nsDialogs.nsh" - - Var fontPackCompanionAvailable - Var fontPackCompanionCheckbox - Var fontPackCompanionExitCode - Var fontPackCompanionHash - Var fontPackCompanionPath - Var fontPackCompanionSelected - - !macro customInit - StrCpy $fontPackCompanionAvailable "0" - StrCpy $fontPackCompanionSelected "0" - StrCpy $fontPackCompanionPath "$EXEDIR\${FONT_PACK_COMPANION_FILE}" - IfFileExists "$fontPackCompanionPath" 0 font_pack_init_done - ${StdUtils.HashFile} $fontPackCompanionHash "SHA2-256" "$fontPackCompanionPath" - StrCmp $fontPackCompanionHash "${FONT_PACK_COMPANION_SHA256}" 0 font_pack_init_done - StrCpy $fontPackCompanionAvailable "1" - IfSilent font_pack_silent font_pack_interactive - font_pack_interactive: - StrCpy $fontPackCompanionSelected "1" - Goto font_pack_init_done - font_pack_silent: - ${GetParameters} $R0 - ${GetOptions} $R0 "/WITHFONTPACK=" $R1 - StrCmp $R1 "1" 0 font_pack_init_done - StrCpy $fontPackCompanionSelected "1" - font_pack_init_done: - !macroend - - Function FontPackCompanionPage - StrCmp $fontPackCompanionAvailable "1" 0 font_pack_page_skip - nsDialogs::Create 1018 - Pop $R0 - StrCmp $R0 "error" 0 +2 - Abort - ${NSD_CreateLabel} 0 0 100% 28u "检测到经过完整性校验的墨呈可选字体包。安装后,政企公文主题可使用与 PDF 相同的原生中文字体资产。" - Pop $R0 - ${NSD_CreateCheckbox} 0 38u 100% 14u "安装 ${FONT_PACK_COMPANION_NAME}" - Pop $fontPackCompanionCheckbox - ${NSD_Check} $fontPackCompanionCheckbox - nsDialogs::Show - Return - font_pack_page_skip: - Abort - FunctionEnd - - Function FontPackCompanionPageLeave - ${NSD_GetState} $fontPackCompanionCheckbox $R0 - StrCmp $R0 ${BST_CHECKED} 0 font_pack_page_unchecked - StrCpy $fontPackCompanionSelected "1" - Return - font_pack_page_unchecked: - StrCpy $fontPackCompanionSelected "0" - FunctionEnd - - !macro customPageAfterChangeDir - Page custom FontPackCompanionPage FontPackCompanionPageLeave - !macroend -!endif -!endif - !macro customInstall DeleteRegKey SHCTX "${MORPHDOC_LEGACY_INSTALL_REGISTRY_KEY}" WriteRegStr SHCTX \ @@ -124,24 +60,6 @@ "" \ "$INSTDIR\${MORPHDOC_EXECUTABLE}" StrCpy $launchLink "$INSTDIR\${MORPHDOC_EXECUTABLE}" - !ifdef FONT_PACK_COMPANION_FILE - StrCmp $fontPackCompanionAvailable "1" 0 font_pack_install_done - StrCmp $fontPackCompanionSelected "1" 0 font_pack_install_done - ${StdUtils.HashFile} $fontPackCompanionHash "SHA2-256" "$fontPackCompanionPath" - StrCmp $fontPackCompanionHash "${FONT_PACK_COMPANION_SHA256}" 0 font_pack_integrity_failed - DetailPrint "正在安装可选字体包:${FONT_PACK_COMPANION_NAME}" - ExecWait '"$fontPackCompanionPath" /S' $fontPackCompanionExitCode - StrCmp $fontPackCompanionExitCode "0" font_pack_install_done - DetailPrint "可选字体包安装失败,退出码:$fontPackCompanionExitCode" - IfSilent font_pack_install_done 0 - MessageBox MB_ICONEXCLAMATION|MB_OK "主程序已安装,但可选字体包安装失败(退出码 $fontPackCompanionExitCode)。您可以稍后单独运行字体包安装器。" - Goto font_pack_install_done - font_pack_integrity_failed: - DetailPrint "可选字体包完整性复核失败,已跳过安装。" - IfSilent font_pack_install_done 0 - MessageBox MB_ICONEXCLAMATION|MB_OK "可选字体包完整性复核失败,主程序已安装,但字体包已跳过。" - font_pack_install_done: - !endif System::Call 'shell32::SHChangeNotify(i 0x08000000, i 0, i 0, i 0)' !macroend diff --git a/apps/desktop/tests/release-build.test.ts b/apps/desktop/tests/release-build.test.ts index d4019bf..e1f2456 100644 --- a/apps/desktop/tests/release-build.test.ts +++ b/apps/desktop/tests/release-build.test.ts @@ -74,6 +74,10 @@ describe("桌面发行构建链", () => { expect(rootManifest.scripts?.["desktop:package"]).toBe( "npm run build:font-pack && npm run package -w @md-to-pdf/desktop" ); + expect(rootManifest.scripts?.["desktop:make"]).toBe( + "npm run build:font-pack && node scripts/build-desktop-release.mjs" + ); + expect(rootManifest.scripts?.["desktop:make:with-font-pack"]).toBeUndefined(); }); it("将固定 Pandoc 最小运行时作为 Desktop 独立资源打包", () => { @@ -190,7 +194,11 @@ describe("桌面发行构建链", () => { "utf8" ); const bundledBuild = readFileSync( - `${projectRoot}/scripts/build-desktop-with-font-pack.mjs`, + `${projectRoot}/scripts/build-desktop-release.mjs`, + "utf8" + ); + const installerInclude = readFileSync( + `${desktopRoot}/build/installer.nsh`, "utf8" ); @@ -201,7 +209,10 @@ describe("桌面发行构建链", () => { ); expect(desktopMain).toContain("getDesktopUserFontPackDirectory()"); expect(bundledBuild).not.toContain("createDesktopCompanionInclude"); - expect(bundledBuild).toContain("已生成内置字体包"); + expect(bundledBuild).toContain("已生成字体直接内置"); + expect(installerInclude).not.toContain("FONT_PACK_COMPANION"); + expect(installerInclude).not.toContain("FontPackCompanionPage"); + expect(installerInclude).not.toContain("/WITHFONTPACK="); }); it("将 DOCX Lua Filter 复制到桌面主进程资源目录", () => { diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index e1137a0..ff3705a 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -1522,13 +1522,17 @@ ECharts 第二阶段浏览器与 PDF 验证结果: 使用同一 `red-briefing` 复验,三份 DOCX 均约 24.17 MB、包含 5 个字体 部件和 40,731,432 字节嵌入字体;安装版产物经 Word/WPS 渲染均为 2 页 A4,逐页视觉通过; -- 阶段 F:已完成。发布提交为 `2c5c1bd`,annotated tag 为 `v0.6.1`; - `release/v0.6.1` 已归集 Desktop 安装器与 ZIP、字体安装器与 ZIP、 - Docker 离线镜像、Web 部署包、发行说明、机器清单和 SHA-256 校验文件。 - 8 项校验和全部通过;799,432,994 字节的离线镜像归档经 `docker load` - 重新导入后内容 ID 保持 - `sha256:1f901fd481ca078d62d22f975691373a160c716e3bfed05721d0704ae5098696`, - 临时容器首页、健康接口、14 主题及 Pandoc 3.9.0.2 capability 均通过。 +- 阶段 F:已完成最终发行重构。Desktop 的 Serif、Sans、Mono 三套字体包 + 直接内置于安装器和免安装 ZIP,NSIS 不再显示字体选择页,正式发行不再 + 拆分字体安装器或字体 ZIP。正式安装包为 185,578,422 字节,免安装 ZIP + 为 242,513,118 字节;安装版默认媒体示例真实导出 10,931,974 字节的 + DOCX,包含 7 个字体部件和 12 个媒体部件。Docker 使用 `--pull`、 + `--no-cache` 且禁用运行层复用的完整路径正式构建,镜像内容 ID 为 + `sha256:f81dbce5857a0a5496851e149936d1fd7da52b76c035187be1079fa1fd5a4717`。 + `release/v0.6.1` 只归集 Desktop 安装器与 ZIP、Docker 离线镜像、Web + 部署包和发行说明五个主附件,并生成机器清单与包含六项的 SHA-256 校验 + 文件;发布引用由本轮 `release:` 提交和重新创建的 annotated `v0.6.1` + 标签统一指向最终发行状态。 每个阶段验收通过后创建一个独立提交,再进入下一阶段。当前阶段不得混入 后续阶段的功能实现。 diff --git a/docs/RELEASE.md b/docs/RELEASE.md index 61fafe3..82494a6 100644 --- a/docs/RELEASE.md +++ b/docs/RELEASE.md @@ -24,8 +24,6 @@ release/v/ release/v/ ├── MorphDoc--x86_64-Setup.exe ├── MorphDoc--x86_64.zip -├── MorphDoc-FontPack---x86_64-Setup.exe -├── MorphDoc-FontPack--.zip ├── MorphDoc-Web--image.tar.gz ├── MorphDoc-Web--deploy.zip ├── manifest.json @@ -54,7 +52,7 @@ TTF、OTF、WOFF 和 WOFF2 必须由 Git LFS 跟踪。新增或升级字体前 ## 发版步骤 1. 完成全量测试、类型检查、生产构建和视觉门禁。 -2. 构建 Desktop 安装包、便携 ZIP 和字体附件。 +2. 构建字体直接内置的 Desktop 安装包和便携 ZIP。 3. 构建并验证版本化 Docker 镜像。 4. 准备 `docs/releases/v.md`。 5. 执行: @@ -65,7 +63,8 @@ TTF、OTF、WOFF 和 WOFF2 必须由 Git LFS 跟踪。新增或升级字体前 6. 逐项核验 `SHA256SUMS.txt`,并从离线归档重新加载 Docker 镜像。 7. 创建内容完整的 `release:` 提交。 -8. 创建 annotated `v` 标签,标签说明与发布提交正文一致。 +8. 重新生成 release 清单,确保 `gitCommit` 指向该发布提交。 +9. 创建 annotated `v` 标签,标签说明与发布提交正文一致。 安装器公开分发前应完成 Authenticode 签名;未签名产物只能按内部发布风险 规则分发。 diff --git a/docs/releases/v0.6.1.md b/docs/releases/v0.6.1.md index 52007c5..03f6070 100644 --- a/docs/releases/v0.6.1.md +++ b/docs/releases/v0.6.1.md @@ -34,16 +34,22 @@ 部件,嵌入字体字节数为 40,731,432。 - 已安装 Desktop 产物经真实 Word 和 WPS 渲染均为 2 页 A4,独立封面及 正文逐页复核通过。 +- 正式安装包覆盖安装后,默认 10 页媒体示例从实际 Desktop 窗口导出 + 10,931,974 字节的 DOCX,包含 7 个字体部件和 12 个媒体部件;字体部件 + 解压后共 11,190,728 字节,确认安装版直接使用随程序内置的字体资源。 - Docker 镜像内置三套字体包与 Pandoc 3.9.0.2;修复复用运行层时 Pandoc 软链接已存在导致构建失败的问题,并通过根级 `.dockerignore` 固定精简 - 构建上下文。 + 构建上下文。正式镜像已使用 `--pull --no-cache` 和禁用运行层复用的完整 + 路径重新构建并通过生产门禁。 - 全项目测试、类型检查、生产构建及 `git diff --check` 通过。 ## 发行与兼容性 - Desktop 安装器和免安装 ZIP 版本均为 0.6.1;支持覆盖 v0.6.0 安装。 +- Serif、Sans、Mono 三套字体直接内置于 Desktop 安装器和免安装 ZIP, + 不写入系统字体目录;安装过程不再显示字体选择,也不再发布独立字体附件。 - Docker 发布镜像为 `md-to-pdf:v0.6.1`,内容 ID 为 - `sha256:1f901fd481ca078d62d22f975691373a160c716e3bfed05721d0704ae5098696`。 + `sha256:f81dbce5857a0a5496851e149936d1fd7da52b76c035187be1079fa1fd5a4717`。 - DOCX 保持原生可编辑段落、Run、列表和表格结构,没有以整页图片替代正文。 - 当前 Windows 安装器未进行 Authenticode 签名,适用于公司内部发布; 公开网络分发前建议增加代码签名。 diff --git a/font-packs/README.md b/font-packs/README.md index 2f750a4..9e6463b 100644 --- a/font-packs/README.md +++ b/font-packs/README.md @@ -78,13 +78,14 @@ Cascadia、Consolas、SFMono、Menlo、Monaco 与 Courier 等候选名称。 组合构建命令为: ```powershell -npm run desktop:make:with-font-pack +npm run desktop:make ``` 该命令先重建完整字体包集合,再构建主安装器和便携 ZIP。electron-builder 把 `output/font-packs/root` 复制到 `resources/font-packs`;Desktop 生产 运行时优先读取该只读内置根目录,再读取用户目录中的额外字体包。内置包 -因此不会被缺失、旧版或同 ID 用户包替换。 +因此不会被缺失、旧版或同 ID 用户包替换。NSIS 不安装系统字体、不显示 +字体选择页,正式发行也不再拆分独立字体安装器或字体 ZIP。 ## Docker 内置发行 diff --git a/package.json b/package.json index eea4590..6a3c3bb 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "build:font-pack": "npm run build -w @md-to-pdf/core && npm run build -w @md-to-pdf/docx-theme-engine && npm run build -w @md-to-pdf/font-pack-registry && npm run build -w @md-to-pdf/docx-engine && npm run build -w @md-to-pdf/font-pack-builder && node scripts/build-font-packs.mjs", "verify:font-pack": "npm run build:font-pack", "verify:docker-font-pack": "npm run verify:font-pack && npm run build:web-runtime && npm run build -w @md-to-pdf/server && node deploy/verify-font-pack-compose.mjs", - "desktop:make:with-font-pack": "npm run build:font-pack && node scripts/build-desktop-with-font-pack.mjs", + "desktop:make": "npm run build:font-pack && node scripts/build-desktop-release.mjs", "release:stage": "node scripts/stage-release.mjs", "test:release-stage": "node --test scripts/stage-release.test.mjs", "test:docx-layout-visual-matrix-cases": "node --test scripts/docx-layout-visual-matrix-cases.test.mjs", diff --git a/scripts/build-desktop-with-font-pack.mjs b/scripts/build-desktop-release.mjs similarity index 90% rename from scripts/build-desktop-with-font-pack.mjs rename to scripts/build-desktop-release.mjs index e08b1cf..62f3843 100644 --- a/scripts/build-desktop-with-font-pack.mjs +++ b/scripts/build-desktop-release.mjs @@ -37,5 +37,5 @@ await new Promise((resolvePromise, reject) => { }); process.stdout.write( - `已生成内置字体包的主安装器与便携 ZIP:${join(desktopRoot, "out", `v${desktopManifest.version}`)}\n` + `已生成字体直接内置的主安装器与便携 ZIP:${join(desktopRoot, "out", `v${desktopManifest.version}`)}\n` ); diff --git a/scripts/stage-release.mjs b/scripts/stage-release.mjs index 884d3a7..738722a 100644 --- a/scripts/stage-release.mjs +++ b/scripts/stage-release.mjs @@ -186,28 +186,6 @@ export async function stageRelease(options = {}) { `MorphDoc-${version}-x86_64-Setup.exe`, `MorphDoc-${version}-x86_64.zip` ]; - const fontPackArtifacts = [ - { - name: "MorphDoc-FontPack-mdtp-serif-sc-1.0.0-x86_64-Setup.exe", - source: join( - repositoryRoot, - "output", - "font-packs", - "windows", - "MorphDoc-FontPack-mdtp-serif-sc-1.0.0-x86_64-Setup.exe" - ) - }, - { - name: "MorphDoc-FontPack-mdtp-serif-sc-1.0.0.zip", - source: join( - repositoryRoot, - "output", - "font-packs", - "release", - "MorphDoc-FontPack-mdtp-serif-sc-1.0.0.zip" - ) - } - ]; const releaseNotesSource = join( repositoryRoot, "docs", @@ -217,9 +195,6 @@ export async function stageRelease(options = {}) { for (const name of desktopNames) { await assertReadableFile(join(desktopDirectory, name)); } - for (const artifact of fontPackArtifacts) { - await assertReadableFile(artifact.source); - } await assertReadableFile(releaseNotesSource); await mkdir(stageDirectory, { recursive: true }); @@ -227,9 +202,6 @@ export async function stageRelease(options = {}) { for (const name of desktopNames) { await copyFile(join(desktopDirectory, name), join(stageDirectory, name)); } - for (const artifact of fontPackArtifacts) { - await copyFile(artifact.source, join(stageDirectory, artifact.name)); - } await copyFile(releaseNotesSource, join(stageDirectory, "RELEASE-NOTES.md")); const deployName = `MorphDoc-Web-${version}-deploy.zip`; @@ -249,7 +221,6 @@ export async function stageRelease(options = {}) { const primaryNames = [ ...desktopNames, - ...fontPackArtifacts.map((artifact) => artifact.name), imageName, deployName, "RELEASE-NOTES.md" diff --git a/scripts/stage-release.test.mjs b/scripts/stage-release.test.mjs index 52573eb..2239e97 100644 --- a/scripts/stage-release.test.mjs +++ b/scripts/stage-release.test.mjs @@ -61,14 +61,7 @@ test("Web 离线部署 ZIP 包含 Compose 和导入说明", async () => { } }); -test("正式发布强制归集独立字体安装器和 ZIP", () => { - assert.match( - stageReleaseSource, - /MorphDoc-FontPack-mdtp-serif-sc-1\.0\.0-x86_64-Setup\.exe/u - ); - assert.match( - stageReleaseSource, - /MorphDoc-FontPack-mdtp-serif-sc-1\.0\.0\.zip/u - ); - assert.match(stageReleaseSource, /fontPackArtifacts\.map/u); +test("正式发布不再拆分独立字体安装器和 ZIP", () => { + assert.doesNotMatch(stageReleaseSource, /MorphDoc-FontPack-/u); + assert.doesNotMatch(stageReleaseSource, /fontPackArtifacts/u); });