fix(ci): canonicalize 8.3 short paths in publish-lock diagnostics matching
assertLockedTargetFailure compared the rename paths from the product publish-lock diagnostic against the expected output file with path.resolve only. On runners whose temporary directory surfaces as a Windows 8.3 short path the smoke passes a short-path output file while the product logs canonical long paths, so a correct atomic publish lock diagnostic was rejected and the cutter media matrix failed. sameResolvedPath now canonicalizes both sides through the existing resolveCanonicalPath helper with a resolve fallback, covered by a ShortPath contract test.
This commit is contained in:
@@ -665,10 +665,18 @@ function analyzeExport(environment, runtime, definition, source) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function canonicalComparablePath(candidatePath) {
|
||||||
|
try {
|
||||||
|
return resolveCanonicalPath(candidatePath);
|
||||||
|
} catch {
|
||||||
|
return path.resolve(candidatePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function sameResolvedPath(left, right) {
|
function sameResolvedPath(left, right) {
|
||||||
if (typeof left !== 'string' || typeof right !== 'string') return false;
|
if (typeof left !== 'string' || typeof right !== 'string') return false;
|
||||||
const resolvedLeft = path.resolve(left);
|
const resolvedLeft = canonicalComparablePath(left);
|
||||||
const resolvedRight = path.resolve(right);
|
const resolvedRight = canonicalComparablePath(right);
|
||||||
return process.platform === 'win32'
|
return process.platform === 'win32'
|
||||||
? resolvedLeft.toLowerCase() === resolvedRight.toLowerCase()
|
? resolvedLeft.toLowerCase() === resolvedRight.toLowerCase()
|
||||||
: resolvedLeft === resolvedRight;
|
: resolvedLeft === resolvedRight;
|
||||||
|
|||||||
@@ -458,6 +458,27 @@ test('runner lifecycle still restores and cleans up when bounded app close fails
|
|||||||
assert.equal(fs.existsSync(environment.rootDir), false);
|
assert.equal(fs.existsSync(environment.rootDir), false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('locked target accepts canonical long-path diagnostics for a short-path output file', { skip: process.platform !== 'win32' }, (t) => {
|
||||||
|
const environment = createEnvironment();
|
||||||
|
t.after(() => fs.rmSync(environment.rootDir, { recursive: true, force: true }));
|
||||||
|
const longRoot = fs.realpathSync.native(environment.rootDir);
|
||||||
|
const shortRoot = getWindowsShortPath(environment.rootDir);
|
||||||
|
if (!shortRoot || shortRoot.toLowerCase() === longRoot.toLowerCase()) {
|
||||||
|
t.skip('8.3 short names are unavailable');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const outputFile = path.join(shortRoot, 'result.mp4');
|
||||||
|
const before = '[2026-08-13T00:00:00.000Z] startup';
|
||||||
|
const after = `${before}\n[2026-08-13T00:00:01.000Z] video-editor-export-failed | Error: EBUSY: resource busy or locked, rename '${path.join(longRoot, '.result.tvm-edit.mp4')}' -> '${path.join(longRoot, 'result.mp4')}'`;
|
||||||
|
assert.doesNotThrow(() => assertLockedTargetFailure({
|
||||||
|
result: { success: false, outputName: null },
|
||||||
|
debugBefore: before,
|
||||||
|
debugAfter: after,
|
||||||
|
outputFile,
|
||||||
|
runtimeIssues: []
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
test('locked target requires a resolved production publish failure with a Windows lock diagnostic', () => {
|
test('locked target requires a resolved production publish failure with a Windows lock diagnostic', () => {
|
||||||
const before = '[2026-08-13T00:00:00.000Z] startup';
|
const before = '[2026-08-13T00:00:00.000Z] startup';
|
||||||
const outputFile = 'C:\\media\\result.mp4';
|
const outputFile = 'C:\\media\\result.mp4';
|
||||||
|
|||||||
Reference in New Issue
Block a user