chore(packaging): CI + package guards for the Windows frame-copy helper

Package validation now requires iptvnator_mpv_helper.exe and the frame
reader next to the addon on win32 (mirroring darwin); the after-pack hook
resolves the .exe name and skips the POSIX execute-bit fixup there. The
build-and-make win32 dist check asserts the helper, the reader and an mpv
DLL beside the helper at the native/ top level. The dist asset copy stops
shipping MSVC intermediates (pdb/iobj/ipdb/ilk/exp/obj) and build-time
import libraries (.lib/.dll.a) — the runtime DLLs are what packages need.
The release-files regex in the identity test tolerates CRLF so the suite
stays host-agnostic on Windows checkouts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
4grayandClaude Fable 5 authored and 4gray committed 2026-07-15 20:44:54 +02:00
1 parent b04448636c
commit 41bedb67ad
4 files changed
+67 -8

No files matched your search

+6
View File
@@ -323,6 +323,12 @@ jobs:
;;
win32)
test -f dist/apps/electron-backend/native/lib/mpv-2.dll || test -f dist/apps/electron-backend/native/lib/libmpv-2.dll || test -f dist/apps/electron-backend/native/lib/mpv.dll || test -f dist/apps/electron-backend/native/lib/libmpv.dll
# Frame-copy engine artifacts ship on Windows. The helper
# resolves the mpv DLL from its own directory, so the DLL
# must sit beside it at the native/ top level too.
test -f dist/apps/electron-backend/native/iptvnator_mpv_helper.exe
test -f dist/apps/electron-backend/native/embedded_mpv_frame_reader.node
find dist/apps/electron-backend/native -maxdepth 1 \( -name 'mpv-2.dll' -o -name 'libmpv-2.dll' -o -name 'mpv.dll' -o -name 'libmpv.dll' \) -print -quit | grep -q .
;;
linux)
node -e "const manifest = require('./dist/apps/electron-backend/native/embedded-mpv-runtime.json'); if (manifest.origin !== 'external-mpv-process') { throw new Error('Linux embedded MPV manifest must use external-mpv-process origin.'); }"
+20 -2
View File
@@ -52,7 +52,16 @@
".deps/**",
"obj.target/**",
"**/.deps/**",
"**/obj.target/**"
"**/obj.target/**",
"obj/**",
"**/obj/**",
"**/*.pdb",
"**/*.iobj",
"**/*.ipdb",
"**/*.ilk",
"**/*.exp",
"**/*.lib",
"**/*.dll.a"
]
}
]
@@ -105,7 +114,16 @@
".deps/**",
"obj.target/**",
"**/.deps/**",
"**/obj.target/**"
"**/obj.target/**",
"obj/**",
"**/obj/**",
"**/*.pdb",
"**/*.iobj",
"**/*.ipdb",
"**/*.ilk",
"**/*.exp",
"**/*.lib",
"**/*.dll.a"
]
}
]
@@ -119,8 +119,10 @@ test('Linux package identity does not expose the internal Electron backend proje
});
test('GitHub Releases auto-update metadata is generated and uploaded', () => {
// \r?\n keeps this host-agnostic: Windows checkouts with autocrlf see
// CRLF in the workflow file.
const releaseFiles = buildAndMakeWorkflow.match(
/files: \|\n([\s\S]*?)\n\s+env:/
/files: \|\r?\n([\s\S]*?)\r?\n\s+env:/
)?.[1];
assert.ok(releaseFiles, 'release upload files block must exist');
@@ -307,7 +309,13 @@ test('embedded MPV package validation accepts Windows runtime files and Linux pr
['windows', join('lib', 'mpv.dll')],
['windows', join('lib', 'libmpv.dll')],
]) {
const resourceDir = join(tempDir, platform);
// One fixture dir per runtime-file scenario: the frame-copy
// artifacts written below must not leak into the next
// iteration's missing-artifact assertions.
const resourceDir = join(
tempDir,
`${platform}-${runtimeFile.replace(/[\\/]/g, '_')}`
);
const nativeDir = join(
resourceDir,
'app.asar.unpacked',
@@ -322,6 +330,29 @@ test('embedded MPV package validation accepts Windows runtime files and Linux pr
);
fs.writeFileSync(join(nativeDir, runtimeFile), '');
// Windows packages that ship the addon must also ship the
// frame-copy engine artifacts built by the same binding.gyp run.
const missingWindowsFrameCopyErrors = validatePackagedEmbeddedMpv(
resourceDir,
{ platform, required: true }
);
assert.ok(
missingWindowsFrameCopyErrors.some((error) =>
error.includes('iptvnator_mpv_helper.exe')
)
);
assert.ok(
missingWindowsFrameCopyErrors.some((error) =>
error.includes('embedded_mpv_frame_reader.node')
)
);
fs.writeFileSync(join(nativeDir, 'iptvnator_mpv_helper.exe'), '');
fs.writeFileSync(
join(nativeDir, 'embedded_mpv_frame_reader.node'),
''
);
assert.deepEqual(
validatePackagedEmbeddedMpv(resourceDir, {
platform,
+8 -4
View File
@@ -540,12 +540,16 @@ function validatePackagedEmbeddedMpv(resourceDir, options = {}) {
return errors;
}
if (platform === 'darwin') {
if (platform === 'darwin' || platform === 'win32') {
// The frame-copy engine artifacts are built by the same binding.gyp
// run as the addon; a macOS package that ships the addon without
// them would silently lose the engine (support probe hides it).
// run as the addon; a macOS/Windows package that ships the addon
// without them would silently lose the engine (support probe hides
// it). Linux packages intentionally strip the helper until the
// bundled-libmpv runtime lands (see electron-after-pack.cjs).
const missingFrameCopyArtifacts = [
'iptvnator_mpv_helper',
platform === 'win32'
? 'iptvnator_mpv_helper.exe'
: 'iptvnator_mpv_helper',
'embedded_mpv_frame_reader.node',
]
.map((name) => path.join(unpackedNativeDir, name))