fix: fail Linux packaging when libffmpeg staging is missing

This commit is contained in:
2026-04-05 10:55:55 -07:00
parent fa89c43f74
commit 1a70a59ab1
3 changed files with 40 additions and 13 deletions

View File

@@ -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.
<!-- SECTION:NOTES:END -->
## Final Summary

View File

@@ -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');

View File

@@ -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<void>;
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 });
}