Files
Firelink/scripts/engine-workspace.js
T
NimBold 725f5e40ec fix(build): isolate engine staging per invocation
- remove shared staging locks and the repository engine tree
- stage verified target payloads in private atomic workspaces
- fence Tauri bundles and process-tree cleanup across platforms
- align CI, AppImage packaging, smoke checks, and release docs
2026-08-31 01:11:56 +03:30

126 lines
3.9 KiB
JavaScript

import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { removePathWithRetry } from './engine-payload-promotion.js';
const ARCH_MAP = { x64: 'x86_64', arm64: 'aarch64' };
const PLATFORM_MAP = {
darwin: 'apple-darwin',
win32: 'pc-windows-msvc',
linux: 'unknown-linux-gnu',
};
const SAFE_TARGET_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
function argumentValue(args, name) {
const index = args.indexOf(name);
if (index >= 0) return args[index + 1];
const prefix = `${name}=`;
const inline = args.find(argument => argument.startsWith(prefix));
return inline?.slice(prefix.length);
}
export function assertSafeTarget(target) {
if (typeof target !== 'string' || !SAFE_TARGET_PATTERN.test(target)) {
throw new Error(`Invalid target triple: ${target ?? '<missing>'}`);
}
return target;
}
export function resolveTargetTriple(
args = process.argv.slice(2),
env = process.env,
platform = os.platform(),
arch = os.arch(),
) {
const hostTarget = ARCH_MAP[arch] && PLATFORM_MAP[platform]
? `${ARCH_MAP[arch]}-${PLATFORM_MAP[platform]}`
: undefined;
const target = argumentValue(args, '--target')
|| env.TAURI_ENV_TARGET_TRIPLE
|| env.FIRELINK_TARGET_TRIPLE
|| hostTarget;
return assertSafeTarget(target);
}
export function resolveOutputRoot(args = process.argv.slice(2), env = process.env) {
const outputRoot = argumentValue(args, '--output-root') || env.FIRELINK_ENGINE_OUTPUT_ROOT;
if (!outputRoot) {
throw new Error(
'No engine output workspace was provided. Run through npm run tauri or set FIRELINK_ENGINE_OUTPUT_ROOT.',
);
}
return path.resolve(outputRoot);
}
function canonicalPathWithMissingComponents(value) {
let cursor = path.resolve(value);
const missing = [];
while (true) {
try {
const canonical = fs.realpathSync.native(cursor);
return path.join(canonical, ...missing.reverse());
} catch (error) {
if (error?.code !== 'ENOENT') throw error;
const parent = path.dirname(cursor);
if (parent === cursor) throw error;
missing.push(path.basename(cursor));
cursor = parent;
}
}
}
function comparablePath(value) {
const normalized = path.normalize(value);
return process.platform === 'win32' ? normalized.toLowerCase() : normalized;
}
function isWithinPath(root, candidate) {
const relative = path.relative(comparablePath(root), comparablePath(candidate));
return relative === ''
|| (!relative.startsWith(`..${path.sep}`) && relative !== '..' && !path.isAbsolute(relative));
}
export function assertSafeOutputRoot(outputRoot, forbiddenRoots = []) {
const canonicalOutputRoot = canonicalPathWithMissingComponents(outputRoot);
for (const forbiddenRoot of forbiddenRoots) {
const canonicalForbiddenRoot = canonicalPathWithMissingComponents(forbiddenRoot);
if (isWithinPath(canonicalForbiddenRoot, canonicalOutputRoot)) {
throw new Error(
`Refusing to use a repository-shared engine workspace: ${outputRoot}`,
);
}
}
return canonicalOutputRoot;
}
export function createEngineWorkspace(target) {
assertSafeTarget(target);
const workspace = fs.realpathSync.native(
fs.mkdtempSync(path.join(os.tmpdir(), `firelink-engine-${target}-${process.pid}-`)),
);
const outputRoot = path.join(workspace, 'engine-dist');
fs.mkdirSync(outputRoot, { recursive: true, mode: 0o700 });
return { outputRoot, runtimeRoot: outputRoot, workspace };
}
export function engineResourceConfig(outputRoot) {
const source = `${path.resolve(outputRoot)}${path.sep}`;
return JSON.stringify({
bundle: {
resources: {
[source]: 'engine-dist/',
},
},
});
}
export async function removeEngineWorkspace(workspace) {
const resolved = path.resolve(workspace);
const basename = path.basename(resolved);
if (!basename.startsWith('firelink-engine-')) {
throw new Error(`Refusing to remove an unexpected engine workspace: ${resolved}`);
}
await removePathWithRetry(resolved);
}