From 1a70a59ab16a95b6b767648a2ce592c735957d17 Mon Sep 17 00:00:00 2001 From: sudacode Date: Sun, 5 Apr 2026 10:55:55 -0700 Subject: [PATCH] fix: fail Linux packaging when libffmpeg staging is missing --- ...mage-child-process-libffmpeg-resolution.md | 6 ++- scripts/electron-builder-after-pack.cjs | 9 ++++- scripts/electron-builder-after-pack.test.ts | 38 ++++++++++++++----- 3 files changed, 40 insertions(+), 13 deletions(-) diff --git a/backlog/tasks/task-279 - Fix-Linux-AppImage-child-process-libffmpeg-resolution.md b/backlog/tasks/task-279 - Fix-Linux-AppImage-child-process-libffmpeg-resolution.md index e57a07c1..e4481d48 100644 --- a/backlog/tasks/task-279 - Fix-Linux-AppImage-child-process-libffmpeg-resolution.md +++ b/backlog/tasks/task-279 - Fix-Linux-AppImage-child-process-libffmpeg-resolution.md @@ -1,11 +1,11 @@ --- id: TASK-279 title: Fix Linux AppImage child-process libffmpeg resolution -status: Done +status: In Progress assignee: - '@codex' created_date: '2026-04-05 17:17' -updated_date: '2026-04-05 17:21' +updated_date: '2026-04-05 17:55' labels: [] dependencies: [] references: @@ -45,6 +45,8 @@ Chose a repo-local electron-builder `afterPack` hook instead of patching/forking Added regression coverage for both config wiring (`src/release-workflow.test.ts`) and the hook behavior (`scripts/electron-builder-after-pack.test.ts`), then wired the new script test into `test:fast` so the maintained lane keeps exercising the fix. Verification passed: `bun test scripts/electron-builder-after-pack.test.ts src/release-workflow.test.ts`, `bun run typecheck`, `bun run test:fast`, `bun run test:env`, `bun run build`, `bun run test:smoke:dist`. + +Addressed PR #45 CodeRabbit review thread: Linux `afterPack` staging now hard-fails when `libffmpeg.so` is missing instead of silently no-oping. Updated focused hook tests to assert the new failure contract and that `afterPack` propagates Linux staging errors. ## Final Summary diff --git a/scripts/electron-builder-after-pack.cjs b/scripts/electron-builder-after-pack.cjs index e2e776e8..54a9795b 100644 --- a/scripts/electron-builder-after-pack.cjs +++ b/scripts/electron-builder-after-pack.cjs @@ -17,8 +17,13 @@ async function stageLinuxAppImageSharedLibrary( try { await deps.access(sourceLibraryPath); - } catch { - return false; + } catch (error) { + if (error && typeof error === 'object' && error.code === 'ENOENT') { + throw new Error( + `Linux packaging requires ${LINUX_FFMPEG_LIBRARY} at ${sourceLibraryPath} so AppImage child processes can resolve it.`, + ); + } + throw error; } const targetLibraryDir = path.join(context.appOutDir, 'usr', 'lib'); diff --git a/scripts/electron-builder-after-pack.test.ts b/scripts/electron-builder-after-pack.test.ts index 6921ab9e..605d6bc6 100644 --- a/scripts/electron-builder-after-pack.test.ts +++ b/scripts/electron-builder-after-pack.test.ts @@ -6,9 +6,11 @@ import test from 'node:test'; const { LINUX_FFMPEG_LIBRARY, + default: afterPack, stageLinuxAppImageSharedLibrary, } = require('./electron-builder-after-pack.cjs') as { LINUX_FFMPEG_LIBRARY: string; + default: (context: { appOutDir: string; electronPlatformName: string }) => Promise; stageLinuxAppImageSharedLibrary: (context: { appOutDir: string; electronPlatformName: string; @@ -63,21 +65,39 @@ test('stageLinuxAppImageSharedLibrary skips non-Linux packaging contexts', async } }); -test('stageLinuxAppImageSharedLibrary no-ops when libffmpeg.so is absent', async () => { +test('stageLinuxAppImageSharedLibrary throws when Linux packaging is missing libffmpeg.so', async () => { const workspace = createWorkspace('subminer-after-pack-missing-library'); const appOutDir = path.join(workspace, 'SubMiner-linux-x64'); - const targetLibraryPath = path.join(appOutDir, 'usr', 'lib', LINUX_FFMPEG_LIBRARY); fs.mkdirSync(appOutDir, { recursive: true }); try { - const staged = await stageLinuxAppImageSharedLibrary({ - appOutDir, - electronPlatformName: 'linux', - }); - - assert.equal(staged, false); - assert.equal(fs.existsSync(targetLibraryPath), false); + await assert.rejects( + stageLinuxAppImageSharedLibrary({ + appOutDir, + electronPlatformName: 'linux', + }), + new RegExp(`Linux packaging requires ${LINUX_FFMPEG_LIBRARY} at .*${LINUX_FFMPEG_LIBRARY}`), + ); + } finally { + fs.rmSync(workspace, { recursive: true, force: true }); + } +}); + +test('afterPack propagates Linux staging failures', async () => { + const workspace = createWorkspace('subminer-after-pack-propagates-linux-failure'); + const appOutDir = path.join(workspace, 'SubMiner-linux-x64'); + + fs.mkdirSync(appOutDir, { recursive: true }); + + try { + await assert.rejects( + afterPack({ + appOutDir, + electronPlatformName: 'linux', + }), + /Linux packaging requires libffmpeg\.so/, + ); } finally { fs.rmSync(workspace, { recursive: true, force: true }); }