perf(desktop): compress macOS DMGs with LZMA

This commit is contained in:
kingwl committed 2026-10-12 18:06:00 +08:00
1 parent 3aa8872e67
commit 01283f1fdd
12 files changed
+69 -8

No files matched your search

+1
View File
@@ -146,6 +146,7 @@ pnpm applies local patches to the following packages at install time, so shipped
- `@fortune-sheet/[email protected]` — [`patches/@[email protected]`](patches/@[email protected])
- `@fortune-sheet/[email protected]` — [`patches/@[email protected]`](patches/@[email protected])
- `@yao-pkg/[email protected]` — [`patches/@[email protected]`](patches/@[email protected])
- `[email protected]` — [`patches/[email protected]`](patches/[email protected])
- `[email protected]` — [`patches/[email protected]`](patches/[email protected])
- `[email protected]` — [`patches/[email protected]`](patches/[email protected])
@@ -30,6 +30,7 @@ export interface DesktopElectronBuilderConfig {
readonly signIgnore: readonly string[]
}
readonly dmg: {
readonly format: 'ULMO'
readonly sign: boolean
readonly writeUpdateInfo: boolean
}
+2 -2
View File
@@ -21,8 +21,8 @@
en: d80a92c02a583b80
zh: b27f75ff29fcea1a
/desktop-packaging/configuration-and-local-builds:
en: e8b8bb1e287bff80
zh: 09b38712c8e974bc
en: e4f526604231ed43
zh: d412179ffdc402ba
/desktop-packaging/windows-actions-packaging:
en: e3f51e7130a0fe05
zh: 70fd6a40d5899871
+2
View File
@@ -93,6 +93,8 @@ pnpm run package:desktop:win:x64
The macOS arm64 command requires Apple Silicon. The macOS x64 command runs on Intel macOS or Apple Silicon with Rosetta. The Windows x64 command requires Windows x64. Linux is not a supported Desktop release target.
Both release and local unsigned macOS DMGs use LZMA compression (`dmg.format: 'ULMO'`) in [the electron-builder configuration](../scripts/electron-builder-config.mjs). A [build-time patch](../../../patches/[email protected]) adds this format to the pinned builder's validation and TypeScript declarations.
Each target owns its packed package inputs, prepared runtime, package set, dsh tree, pnpm preparation state, unpacked application, update metadata, and final artifacts under `apps/desktop/.desktop-build/targets/<target>/`. The Electron archive cache remains shared under `.desktop-build/downloads` because every archive name includes its version, platform, and architecture and is verified before extraction. A target build never consumes another target's mutable preparation state.
<a id="windows-actions"></a>
+2
View File
@@ -93,6 +93,8 @@ pnpm run package:desktop:win:x64
macOS arm64 命令要求 Apple Silicon。macOS x64 命令可以在 Intel macOS 或带 Rosetta 的 Apple Silicon 上运行。Windows x64 命令要求 Windows x64。Linux 不是受支持的 Desktop 发布目标。
macOS 正式发布和本地未签名 DMG 都通过 [electron-builder 配置](../scripts/electron-builder-config.mjs)中的 `dmg.format: 'ULMO'` 使用 LZMA 压缩。[构建时补丁](../../../patches/[email protected])为固定版本 builder 的校验规则和 TypeScript 声明添加此格式。
每个目标都在 `apps/desktop/.desktop-build/targets/<target>/` 下持有自己的打包输入、已准备运行时、包集合、dsh 依赖树、pnpm 准备状态、未打包应用、更新元数据和最终产物。Electron 归档缓存继续由 `.desktop-build/downloads` 共享,因为每个归档文件名都包含版本、平台和架构,并且在解包前经过验证。目标构建绝不读取其他目标的可变准备状态。
<a id="windows-actions"></a>
@@ -166,6 +166,7 @@ export function createElectronBuilderConfig(
target: unsigned ? ['dmg'] : ['dmg', 'zip'],
},
dmg: {
format: 'ULMO',
sign: !unsigned,
writeUpdateInfo: false,
},
@@ -13,6 +13,7 @@ export const DESKTOP_RUNTIME_PATCHES: Readonly<Record<string, DesktopRuntimePatc
'@fortune-sheet/[email protected]': { scope: 'workspace-only', reason: 'Patched spreadsheet code is embedded in the client bundle.' },
'@fortune-sheet/[email protected]': { scope: 'workspace-only', reason: 'Patched spreadsheet code is embedded in the client bundle.' },
'@yao-pkg/[email protected]': { scope: 'workspace-only', reason: 'The executable packer executes on the build host.' },
'[email protected]': { scope: 'workspace-only', reason: 'DMG format validation executes on the build host.' },
'[email protected]': { scope: 'workspace-only', reason: 'The patched parser is embedded in the client bundle and worker.' },
'[email protected]': { scope: 'shared', reason: 'Runtime terminals need helper resolution and Windows worker cleanup.' },
}
@@ -1,5 +1,6 @@
import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest'
import { readFileSync } from 'node:fs'
import { createRequire } from 'node:module'
import type { NotarizeOptions } from '@electron/notarize'
import {
resolveDesktopAppId,
@@ -12,6 +13,11 @@ import {
assertMacOSSignatureDetails,
} from '../scripts/verify-macos-signature.mjs'
const require = createRequire(import.meta.url)
const { validateConfiguration } = require('app-builder-lib/out/util/config/config.js') as {
validateConfiguration: (config: object, logger: { isEnabled: false }) => Promise<void>
}
const RELEASE_ENVIRONMENT = {
DSH_DESKTOP_APP_ID: 'com.example.desktop',
DSH_DESKTOP_MANDATORY_UPDATE_TEST_ORIGIN: 'https://policy.example.com',
@@ -75,6 +81,7 @@ describe('desktop macOS release signature', () => {
signIgnore: ['/Contents/Resources/app\\.asar\\.unpacked/dsh(?:/|$)', '/Contents/Resources/runtime/primary-runtime(?:/|$)', '\\.pak$'],
},
dmg: {
format: 'ULMO',
sign: true,
writeUpdateInfo: false,
},
@@ -87,6 +94,23 @@ describe('desktop macOS release signature', () => {
expect(typeof config.artifactBuildCompleted).toBe('function')
})
it('accepts LZMA DMGs through builder validation while rejecting unknown formats', async () => {
const { createElectronBuilderConfig } = await import('../scripts/electron-builder-config.mjs')
for (const arch of ['arm64', 'x64']) {
for (const unsigned of ['0', '1']) {
const config = createElectronBuilderConfig({
...RELEASE_ENVIRONMENT,
DSH_DESKTOP_TARGET_ARCH: arch,
DSH_DESKTOP_UNSIGNED: unsigned,
}, 'darwin', arch)
expect(config.dmg.format).toBe('ULMO')
await expect(validateConfiguration(config, { isEnabled: false })).resolves.toBeUndefined()
}
}
await expect(validateConfiguration({ dmg: { format: 'invalid' } }, { isEnabled: false }))
.rejects.toThrow('configuration.dmg.format')
})
it('seals PAK resources with their enclosing bundle while signing executable code', async () => {
const { createElectronBuilderConfig } = await import('../electron-builder.config.mjs')
const config = createElectronBuilderConfig(RELEASE_ENVIRONMENT, 'darwin', 'arm64')
@@ -43,7 +43,7 @@ it('classifies the current workspace and shares only runtime patch bytes', () =>
const before = readFileSync(join(repository, 'pnpm-lock.yaml'))
const plan = prepareRuntimePatches(project, repository)
expect(plan.patches.map(entry => entry.spec)).toEqual(['@earendil-works/[email protected]', '[email protected]'])
expect(plan.workspaceOnly).toHaveLength(5)
expect(plan.workspaceOnly).toHaveLength(6)
const settings = yaml.load(readFileSync(join(project, 'pnpm-workspace.yaml'), 'utf8')) as { overrides: Record<string, string> }
expect(settings.overrides['@earendil-works/pi-ai']).toBeUndefined()
expect(settings.overrides['@earendil-works/pi-ai@^1.0.2']).toBe('1.0.2')
+27
View File
@@ -0,0 +1,27 @@
diff --git a/out/options/macOptions.d.ts b/out/options/macOptions.d.ts
index e93987d973399b17f3970c858abb49f5e4b193d6..445a73c81e1d7eb61dc318373d2331487934d3f5 100644
--- a/out/options/macOptions.d.ts
+++ b/out/options/macOptions.d.ts
@@ -258,7 +258,7 @@ export interface DmgOptions extends TargetSpecificOptions {
* The disk image format. `ULFO` (lzfse-compressed image (OS X 10.11+ only)).
* @default UDZO
*/
- format?: "UDRW" | "UDRO" | "UDCO" | "UDZO" | "UDBZ" | "ULFO";
+ format?: "UDRW" | "UDRO" | "UDCO" | "UDZO" | "UDBZ" | "ULFO" | "ULMO";
/**
* The filesystem for the DMG volume (e.g. `"APFS"` or `"HFS+"`)
* This will be changed to APFS in the next major release, so it is recommended to set it explicitly to HFS+ if you want to keep using HFS+ (e.g. for better compatibility with older macOS versions).
diff --git a/scheme.json b/scheme.json
index a637bab2668ef88e7382dd4aa5db62b74fdde898..ebcafac58971bdd7c69b78ceddcd401a75ffaa35 100644
--- a/scheme.json
+++ b/scheme.json
@@ -979,7 +979,8 @@
"UDRO",
"UDRW",
"UDZO",
- "ULFO"
+ "ULFO",
+ "ULMO"
],
"type": "string"
},
+6 -5
View File
@@ -15,6 +15,7 @@ patchedDependencies:
'@fortune-sheet/[email protected]': 8791a230763dbf853fd65d627c68c31de37209992851377855e16cf08ea70532
'@fortune-sheet/[email protected]': 2932e52e79afcd4ced08cfa123b5eded786c85043da32f622f3e80af6fc96c37
'@yao-pkg/[email protected]': 75891fc22b277c145cafeab83e41baf4a70f5b8fe6dc0801c6a0b922d7ee88c7
[email protected]: b70dc2a2a78ffabb80a4f14fafc7c103237f2b0a207e1f296fa1c1387ea29348
[email protected]: c1bf8ac8f319dab382f08e3a669b715e691d46c703ac5a4163eb383fbedd1d48
[email protected]: 9d30053266d0f39d3debe894c675867f6782da6bcadbc94a693b3cfb9eff8ed0
@@ -722,7 +723,7 @@ importers:
version: 8.18.1
app-builder-lib:
specifier: 26.17.0
version: 26.17.0([email protected])([email protected])([email protected])
version: 26.17.0(patch_hash=b70dc2a2a78ffabb80a4f14fafc7c103237f2b0a207e1f296fa1c1387ea29348)([email protected])([email protected])([email protected])
cos-nodejs-sdk-v5:
specifier: 3.0.0
version: 3.0.0
@@ -26194,7 +26195,7 @@ snapshots:
[email protected]: {}
[email protected]([email protected])([email protected])([email protected]):
[email protected](patch_hash=b70dc2a2a78ffabb80a4f14fafc7c103237f2b0a207e1f296fa1c1387ea29348)([email protected])([email protected])([email protected]):
dependencies:
'@electron/asar': 3.4.1
'@electron/fuses': 1.8.0
@@ -27057,7 +27058,7 @@ snapshots:
[email protected]([email protected])([email protected]):
dependencies:
app-builder-lib: 26.17.0([email protected])([email protected])([email protected])
app-builder-lib: 26.17.0(patch_hash=b70dc2a2a78ffabb80a4f14fafc7c103237f2b0a207e1f296fa1c1387ea29348)([email protected])([email protected])([email protected])
builder-util: 26.16.0([email protected])
fs-extra: 10.1.0
js-yaml: 4.3.2
@@ -27108,7 +27109,7 @@ snapshots:
[email protected]([email protected])([email protected]):
dependencies:
app-builder-lib: 26.17.0([email protected])([email protected])([email protected])
app-builder-lib: 26.17.0(patch_hash=b70dc2a2a78ffabb80a4f14fafc7c103237f2b0a207e1f296fa1c1387ea29348)([email protected])([email protected])([email protected])
builder-util: 26.16.0([email protected])
electron-winstaller: 5.4.0([email protected])
transitivePeerDependencies:
@@ -27117,7 +27118,7 @@ snapshots:
[email protected]([email protected])([email protected]):
dependencies:
app-builder-lib: 26.17.0([email protected])([email protected])([email protected])
app-builder-lib: 26.17.0(patch_hash=b70dc2a2a78ffabb80a4f14fafc7c103237f2b0a207e1f296fa1c1387ea29348)([email protected])([email protected])([email protected])
builder-util: 26.16.0([email protected])
builder-util-runtime: 9.7.0([email protected])
chalk: 4.1.2
+1
View File
@@ -111,5 +111,6 @@ patchedDependencies:
'@fortune-sheet/[email protected]': patches/@[email protected]
'@fortune-sheet/[email protected]': patches/@[email protected]
'@yao-pkg/[email protected]': patches/@[email protected]
[email protected]: patches/[email protected]
[email protected]: patches/[email protected]
[email protected]: patches/[email protected]