Files
iptvnator/tools/packaging/validate-snap-release-boundary.mjs
T
4gray 8fdac824fd feat(packaging): ship Linux embedded MPV frame-copy runtime (#1200)
* docs: design Linux frame-copy packaging

* docs: plan Linux frame-copy packaging

* feat(packaging): define Linux frame-copy profiles

* fix(packaging): reject inherited profile names

* feat(embedded-mpv): validate staged Linux runtime

* fix(embedded-mpv): require Linux source packages

* fix(embedded-mpv): harden Linux runtime staging

* feat(embedded-mpv): build LGPL Linux runtime

* fix(embedded-mpv): pin Linux runtime inputs

* feat(embedded-mpv): build relocatable Linux helper

* fix(embedded-mpv): require bundled Linux runtime

* fix(embedded-mpv): make Linux runtime portable

* feat(packaging): ship Linux frame-copy artifacts

* fix(embedded-mpv): verify Linux helper linkage

* fix(packaging): enforce Linux frame-copy isolation

* fix(embedded-mpv): pin Linux display data

* docs(embedded-mpv): document Linux frame-copy packaging

* feat(embedded-mpv): probe Linux frame-copy runtime

* test(embedded-mpv): smoke packaged Linux frame-copy

* docs(embedded-mpv): clarify Linux system runtime baseline

* fix(embedded-mpv): harden Linux runtime capability gate

* ci: verify Linux frame-copy packages

* test(embedded-mpv): harden packaged Linux smoke

* test(embedded-mpv): preserve packaged GL mode

* test(packaging): harden Linux package probes

* fix(embedded-mpv): enable private Snap shared memory

* fix(embedded-mpv): sanitize Linux helper environment

* fix(packaging): enforce private Snap memory semantics

* fix(packaging): reject ambiguous Snap memory metadata

* fix(embedded-mpv): prioritize trusted Snap GL

* fix(packaging): reject advanced Snap YAML semantics

* fix(packaging): reject arbitrary Snap YAML aliases

* feat(packaging): ship Linux runtime license notices

* docs(embedded-mpv): document Linux runtime distribution

* fix(packaging): parse Snap trailing comments safely

* fix(release): gate Snap publish on public source release

* fix(packaging): strip VCS metadata from source bundle

* docs(packaging): clarify Linux source release gate

* test(embedded-mpv): smoke missing bundled libmpv

* style(embedded-mpv): format final validation inputs

* fix(e2e): satisfy fixture index signature typing

* fix(ci): declare fontconfig gperf generator

* fix(embedded-mpv): hash runtime cache identities

* fix(packaging): harden Linux frame-copy delivery

* fix(packaging): tighten runtime delivery gates

* fix(ci): decouple Linux runtime matrix

* fix(packaging): harden Linux frame-copy delivery

* fix(packaging): validate Linux frame-copy runtimes

* fix(packaging): scope Snap Electron library checks

* feat(packaging): ship Linux frame-copy runtimes

* fix(packaging): improve Linux runtime smoke diagnostics

* fix(packaging): expose bounded helper probe details

* test(packaging): trace Snap EGL probe failures

* fix(packaging): prefer core22 ABI in Snap helper

* fix(packaging): bound helper probe capture

* fix(packaging): harden Linux frame-copy releases

* fix(packaging): canonicalize libplacebo submodule identity

* fix(packaging): make source archive inspection portable

* fix(packaging): harden Snap release verification
2026-07-18 17:28:22 +02:00

109 lines
2.8 KiB
JavaScript

#!/usr/bin/env node
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import {
collectEmbeddedMpvNativeArchiveEntries,
listAsarPackageEntries,
} from './asar-dependency-closure.mjs';
import { validateExtractedSnapMetadata } from './verify-linux-frame-copy-runtime.mjs';
const scriptPath = fileURLToPath(import.meta.url);
const SNAP_RELEASE_BOUNDARY_SCHEMA_VERSION = 1;
export function validateExtractedSnapReleaseBoundary(
extractionRoot,
{ asarListPackage = listAsarPackageEntries } = {}
) {
const errors = [...validateExtractedSnapMetadata(extractionRoot)];
const asarPath = path.join(
extractionRoot,
'usr',
'lib',
'iptvnator',
'resources',
'app.asar'
);
let asarStat;
try {
asarStat = fs.lstatSync(asarPath);
} catch {
errors.push(
`Public-release Snap must contain its canonical app.asar: ${asarPath}`
);
return errors;
}
if (
!asarStat.isFile() ||
asarStat.isSymbolicLink() ||
asarStat.size === 0
) {
errors.push(
`Public-release Snap app.asar must be a non-empty regular file: ${asarPath}`
);
return errors;
}
let nativeEntries;
try {
nativeEntries = collectEmbeddedMpvNativeArchiveEntries(
asarListPackage(asarPath)
);
} catch (error) {
errors.push(
`Unable to inspect public-release Snap app.asar at ${asarPath}: ${
error instanceof Error ? error.message : String(error)
}`
);
return errors;
}
if (nativeEntries.length > 0) {
errors.push(
`Public-release Snap app.asar must not contain embedded MPV native payloads: ${nativeEntries.join(
', '
)}`
);
}
return errors;
}
function main() {
const args = process.argv.slice(2);
if (args.length !== 1 || args[0].length === 0) {
throw new Error(
'Usage: validate-snap-release-boundary.mjs <extracted-snap-root>'
);
}
const errors = validateExtractedSnapReleaseBoundary(path.resolve(args[0]));
process.stdout.write(
`${JSON.stringify({
schemaVersion: SNAP_RELEASE_BOUNDARY_SCHEMA_VERSION,
errors,
})}\n`
);
}
function isMainModule() {
if (!process.argv[1]) {
return false;
}
try {
return fs.realpathSync(process.argv[1]) === fs.realpathSync(scriptPath);
} catch {
return false;
}
}
if (isMainModule()) {
try {
main();
} catch (error) {
process.stderr.write(
`${error instanceof Error ? error.message : String(error)}\n`
);
process.exitCode = 1;
}
}