release: 发布字体直接内置版 v0.6.1
新增能力: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 字体嵌入链路均通过。
This commit is contained in:
@@ -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 历史。
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 复制到桌面主进程资源目录", () => {
|
||||
|
||||
+11
-7
@@ -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`
|
||||
标签统一指向最终发行状态。
|
||||
|
||||
每个阶段验收通过后创建一个独立提交,再进入下一阶段。当前阶段不得混入
|
||||
后续阶段的功能实现。
|
||||
|
||||
+3
-4
@@ -24,8 +24,6 @@ release/v<semver>/
|
||||
release/v<version>/
|
||||
├── MorphDoc-<version>-x86_64-Setup.exe
|
||||
├── MorphDoc-<version>-x86_64.zip
|
||||
├── MorphDoc-FontPack-<id>-<font-version>-x86_64-Setup.exe
|
||||
├── MorphDoc-FontPack-<id>-<font-version>.zip
|
||||
├── MorphDoc-Web-<version>-image.tar.gz
|
||||
├── MorphDoc-Web-<version>-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<version>.md`。
|
||||
5. 执行:
|
||||
@@ -65,7 +63,8 @@ TTF、OTF、WOFF 和 WOFF2 必须由 Git LFS 跟踪。新增或升级字体前
|
||||
|
||||
6. 逐项核验 `SHA256SUMS.txt`,并从离线归档重新加载 Docker 镜像。
|
||||
7. 创建内容完整的 `release:` 提交。
|
||||
8. 创建 annotated `v<version>` 标签,标签说明与发布提交正文一致。
|
||||
8. 重新生成 release 清单,确保 `gitCommit` 指向该发布提交。
|
||||
9. 创建 annotated `v<version>` 标签,标签说明与发布提交正文一致。
|
||||
|
||||
安装器公开分发前应完成 Authenticode 签名;未签名产物只能按内部发布风险
|
||||
规则分发。
|
||||
|
||||
@@ -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 签名,适用于公司内部发布;
|
||||
公开网络分发前建议增加代码签名。
|
||||
|
||||
@@ -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 内置发行
|
||||
|
||||
|
||||
+1
-1
@@ -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",
|
||||
|
||||
@@ -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`
|
||||
);
|
||||
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user