Merge pull request #1146 from anywhere-labs/ci/windows-store-compression

ci(windows): build CI smoke packages with store compression
This commit is contained in:
zp-home
2026-09-23 11:27:07 +08:00
committed by GitHub
7 changed files with 127 additions and 0 deletions
+3
View File
@@ -157,10 +157,13 @@ jobs:
- name: Build Windows installer
env:
DSH_PACKAGE_CHECK_ALREADY_RAN: '1'
# CI artifacts are never published; skipping compression saves minutes.
DSH_WINDOWS_PACKAGE_COMPRESSION: store
run: yarn workspace ${{ matrix.workspace }} dist:win
- name: Build Windows portable archive
env:
DSH_PACKAGE_CHECK_ALREADY_RAN: '1'
DSH_WINDOWS_PACKAGE_COMPRESSION: store
run: yarn workspace ${{ matrix.workspace }} dist:win-portable
# macOS-only universal packaging smoke on a real macOS runner: the signed
@@ -16,6 +16,29 @@ const WINDOWS_SIGNING_KEYS = [
'WIN_CSC_LINK',
] as const
const WINDOWS_COMPRESSION_LEVELS = new Set(['store', 'normal', 'maximum'])
/**
* Read an optional electron-builder compression override for unsigned CI
* artifacts. Compression dominates the Windows job while the smoke artifacts
* are never published, so CI may select `store`; release builds leave the
* variable unset and keep `build.win.compression`.
* @param environment - Environment of the packaging process.
* @returns The override, or `undefined` to keep the package configuration.
*/
export function windowsCompressionOverride(
environment: NodeJS.ProcessEnv,
): string | undefined {
const value = environment.DSH_WINDOWS_PACKAGE_COMPRESSION
if (value === undefined || value === '') return undefined
if (!WINDOWS_COMPRESSION_LEVELS.has(value)) {
throw new Error(
`DSH_WINDOWS_PACKAGE_COMPRESSION must be store, normal, or maximum; received ${JSON.stringify(value)}`,
)
}
return value
}
/** Injectable native Windows packaging boundary used by focused tests. */
export interface WindowsPackageOptions {
/** Environment inherited by the packaging command. */
@@ -132,9 +155,13 @@ export function packageWindowsArtifact(
artifact: 'installer' | 'portable archive',
): void {
assertWindowsPackageHost(options, artifact)
const compression = windowsCompressionOverride(options.env)
const cleanEnvironment = withoutWindowsSigningSecrets(options.env)
options.log(`Building an unsigned Windows x64 ${artifact}; Authenticode is a separate release step.`)
if (compression !== undefined) {
options.log(`Packaging the ${artifact} with ${compression} compression.`)
}
if (options.env.DSH_PACKAGE_CHECK_ALREADY_RAN !== '1') {
options.run(
options.commandShell,
@@ -163,6 +190,7 @@ export function packageWindowsArtifact(
'--config.win.signExecutable=false',
'--config.npmRebuild=false',
'--config.electronFuses.onlyLoadAppFromAsar=false',
...(compression === undefined ? [] : [`--config.win.compression=${compression}`]),
],
options.desktopRoot,
electronBuilderEnvironment({
@@ -152,6 +152,38 @@ describe('Windows x64 installer packaging', () => {
])
})
it('overrides electron-builder compression only when requested', () => {
const calls: CommandCall[] = []
const logs: string[] = []
const value = {
...options(calls, logs),
env: {
...options(calls).env,
DSH_PACKAGE_CHECK_ALREADY_RAN: '1',
DSH_WINDOWS_PACKAGE_COMPRESSION: 'store',
},
}
packageWindowsArtifact(value, 'zip', 'portable archive')
expect(calls).toHaveLength(2)
expect(calls[0]?.args.at(-1)).toBe('--config.win.compression=store')
expect(logs).toContain('Packaging the portable archive with store compression.')
})
it('rejects an unknown compression override before running commands', () => {
const calls: CommandCall[] = []
const value = {
...options(calls),
env: { ...options(calls).env, DSH_WINDOWS_PACKAGE_COMPRESSION: 'fast' },
}
expect(() => packageWindowsInstaller(value)).toThrow(
'DSH_WINDOWS_PACKAGE_COMPRESSION must be store, normal, or maximum',
)
expect(calls).toEqual([])
})
it.each([
['darwin', 'x64', '22.23.2', 'native Windows host'],
['win32', 'arm64', '22.23.2', 'requires x64 Node'],
@@ -1007,6 +1007,8 @@ describe('published package surface', () => {
expect(windowsJob).toContain('run: yarn workspace ${{ matrix.workspace }} dist:win')
expect(windowsJob).toContain('run: yarn workspace ${{ matrix.workspace }} dist:win-portable')
expect(windowsJob).toContain('DSH_PACKAGE_CHECK_ALREADY_RAN: \'1\'')
// Smoke artifacts are never published, so CI skips their compression.
expect(windowsJob.match(/DSH_WINDOWS_PACKAGE_COMPRESSION: store/g)).toHaveLength(2)
expect(macosJob).not.toContain('- run: yarn check')
expect(macosJob).toContain('workspace: [dsh-plugin-desktop, dsh-plugin-desktop-beta]')
expect(macosJob).toContain('- run: yarn workspace ${{ matrix.workspace }} check:mac-package:platform')
+28
View File
@@ -16,6 +16,29 @@ const WINDOWS_SIGNING_KEYS = [
'WIN_CSC_LINK',
] as const
const WINDOWS_COMPRESSION_LEVELS = new Set(['store', 'normal', 'maximum'])
/**
* Read an optional electron-builder compression override for unsigned CI
* artifacts. Compression dominates the Windows job while the smoke artifacts
* are never published, so CI may select `store`; release builds leave the
* variable unset and keep `build.win.compression`.
* @param environment - Environment of the packaging process.
* @returns The override, or `undefined` to keep the package configuration.
*/
export function windowsCompressionOverride(
environment: NodeJS.ProcessEnv,
): string | undefined {
const value = environment.DSH_WINDOWS_PACKAGE_COMPRESSION
if (value === undefined || value === '') return undefined
if (!WINDOWS_COMPRESSION_LEVELS.has(value)) {
throw new Error(
`DSH_WINDOWS_PACKAGE_COMPRESSION must be store, normal, or maximum; received ${JSON.stringify(value)}`,
)
}
return value
}
/** Injectable native Windows packaging boundary used by focused tests. */
export interface WindowsPackageOptions {
/** Environment inherited by the packaging command. */
@@ -132,9 +155,13 @@ export function packageWindowsArtifact(
artifact: 'installer' | 'portable archive',
): void {
assertWindowsPackageHost(options, artifact)
const compression = windowsCompressionOverride(options.env)
const cleanEnvironment = withoutWindowsSigningSecrets(options.env)
options.log(`Building an unsigned Windows x64 ${artifact}; Authenticode is a separate release step.`)
if (compression !== undefined) {
options.log(`Packaging the ${artifact} with ${compression} compression.`)
}
if (options.env.DSH_PACKAGE_CHECK_ALREADY_RAN !== '1') {
options.run(
options.commandShell,
@@ -163,6 +190,7 @@ export function packageWindowsArtifact(
'--config.win.signExecutable=false',
'--config.npmRebuild=false',
'--config.electronFuses.onlyLoadAppFromAsar=false',
...(compression === undefined ? [] : [`--config.win.compression=${compression}`]),
],
options.desktopRoot,
electronBuilderEnvironment({
@@ -152,6 +152,38 @@ describe('Windows x64 installer packaging', () => {
])
})
it('overrides electron-builder compression only when requested', () => {
const calls: CommandCall[] = []
const logs: string[] = []
const value = {
...options(calls, logs),
env: {
...options(calls).env,
DSH_PACKAGE_CHECK_ALREADY_RAN: '1',
DSH_WINDOWS_PACKAGE_COMPRESSION: 'store',
},
}
packageWindowsArtifact(value, 'zip', 'portable archive')
expect(calls).toHaveLength(2)
expect(calls[0]?.args.at(-1)).toBe('--config.win.compression=store')
expect(logs).toContain('Packaging the portable archive with store compression.')
})
it('rejects an unknown compression override before running commands', () => {
const calls: CommandCall[] = []
const value = {
...options(calls),
env: { ...options(calls).env, DSH_WINDOWS_PACKAGE_COMPRESSION: 'fast' },
}
expect(() => packageWindowsInstaller(value)).toThrow(
'DSH_WINDOWS_PACKAGE_COMPRESSION must be store, normal, or maximum',
)
expect(calls).toEqual([])
})
it.each([
['darwin', 'x64', '22.23.2', 'native Windows host'],
['win32', 'arm64', '22.23.2', 'requires x64 Node'],
+2
View File
@@ -939,6 +939,8 @@ describe('published package surface', () => {
expect(windowsJob).toContain('run: yarn workspace ${{ matrix.workspace }} dist:win')
expect(windowsJob).toContain('run: yarn workspace ${{ matrix.workspace }} dist:win-portable')
expect(windowsJob).toContain('DSH_PACKAGE_CHECK_ALREADY_RAN: \'1\'')
// Smoke artifacts are never published, so CI skips their compression.
expect(windowsJob.match(/DSH_WINDOWS_PACKAGE_COMPRESSION: store/g)).toHaveLength(2)
expect(macosJob).not.toContain('- run: yarn check')
expect(macosJob).toContain('workspace: [dsh-plugin-desktop, dsh-plugin-desktop-beta]')
expect(macosJob).toContain('- run: yarn workspace ${{ matrix.workspace }} check:mac-package:platform')