Skip to content

Commit d38757f

Browse files
committed
fix: align artifact identity checks across Windows
1 parent daad63f commit d38757f

3 files changed

Lines changed: 10 additions & 6 deletions

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,7 @@ jobs:
2323
node-version: ${{ matrix.node }}
2424
cache: npm
2525
- run: npm ci
26-
- name: Full check (temporary Windows Node diagnostics)
27-
env:
28-
ZCODE_DEBUG: '1'
29-
run: npm run check
26+
- run: npm run check
3027
- name: Clean packed production install and Node 22.13 native binding smoke
3128
run: node --test tests/integration/package-install.test.mjs
3229
- name: Production lockfile native binding smoke

scripts/lib/review.mjs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,12 @@ export async function readResultArtifact({ dataRoot, workspace, artifact }) {
9696
const pathInfo = await lstat(path); if (pathInfo.isSymbolicLink() || !pathInfo.isFile()) throw artifactError();
9797
if (await realpath(dirname(path)) !== root) throw artifactError();
9898
const handle = await open(path, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0));
99-
try { const before = await handle.stat(); const contents = await handle.readFile('utf8'); const after = await lstat(path); if (after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) throw artifactError(); return contents; }
99+
try {
100+
// Keep the before/after identity check on path stats as well. Mixing
101+
// FileHandle.stat with lstat is inconsistent on Node 22.13 Windows.
102+
const before = pathInfo; const contents = await handle.readFile('utf8'); const after = await lstat(path);
103+
if (after.isSymbolicLink() || before.dev !== after.dev || before.ino !== after.ino) throw artifactError(); return contents;
104+
}
100105
finally { await handle.close(); }
101106
});
102107
} catch (error) { throw new PluginError('RESULT_READ_FAILED', 'Could not safely read the result artifact.', { category: 'storage', remedy: 'Inspect the private workspace result store.', cause: error }); }

tests/windows-compat.test.mjs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ test('artifact identity checks do not mix handle and path stat implementations',
6565
import { mkdtemp, open, readFile, rm } from 'node:fs/promises';
6666
import { tmpdir } from 'node:os';
6767
import { join } from 'node:path';
68-
import { writeResultArtifact } from ${JSON.stringify(reviewModule)};
68+
import { readResultArtifact, writeResultArtifact } from ${JSON.stringify(reviewModule)};
6969
const directory = await mkdtemp(join(tmpdir(), 'zcode-stat-'));
7070
const probe = await open(join(directory, 'probe'), 'a+');
7171
const prototype = Object.getPrototypeOf(probe);
@@ -82,6 +82,8 @@ test('artifact identity checks do not mix handle and path stat implementations',
8282
try {
8383
const artifact = await writeResultArtifact({ dataRoot: directory, workspace: directory, jobId: 'b'.repeat(64), contents: 'done' });
8484
if (artifact !== 'results/' + 'b'.repeat(64) + '.md') throw new Error('artifact path did not persist');
85+
const contents = await readResultArtifact({ dataRoot: directory, workspace: directory, artifact });
86+
if (contents !== 'done') throw new Error('artifact contents did not read');
8587
} finally {
8688
prototype.stat = originalStat;
8789
await rm(directory, { recursive: true, force: true });

0 commit comments

Comments
 (0)