From eff904b60d05dabe5026565cf430b11c48854228 Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Fri, 15 May 2026 02:04:12 +0200 Subject: [PATCH] fix(sl): skip TS/Python schema contract test when uv is unavailable The TypeScript checks CI job does not install uv or Python, so the module-level `execFileSync('uv', ...)` in schemas.contract.test.ts threw ENOENT and failed the suite. Wrap the schema dump in a try/catch and guard the describe block with `describe.skipIf` so the test skips in environments without uv. Local dev and any CI job that has uv on PATH still runs the cross-language contract assertion. --- .../context/src/sl/schemas.contract.test.ts | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/packages/context/src/sl/schemas.contract.test.ts b/packages/context/src/sl/schemas.contract.test.ts index f27a455f..1b0dac20 100644 --- a/packages/context/src/sl/schemas.contract.test.ts +++ b/packages/context/src/sl/schemas.contract.test.ts @@ -6,12 +6,20 @@ import { resolvedSourceSchema } from './schemas.js'; import { toResolvedWire } from './semantic-layer.service.js'; import type { SemanticLayerSource } from './types.js'; -const sourceDefinitionJsonSchema = JSON.parse( - execFileSync('uv', ['run', 'python', '-m', 'semantic_layer', 'dump-schema'], { - cwd: new URL('../../../../', import.meta.url), - encoding: 'utf8', - }), -) as Record; +function loadPythonSourceDefinitionSchema(): Record | null { + try { + const stdout = execFileSync('uv', ['run', 'python', '-m', 'semantic_layer', 'dump-schema'], { + cwd: new URL('../../../../', import.meta.url), + encoding: 'utf8', + stdio: ['ignore', 'pipe', 'ignore'], + }); + return JSON.parse(stdout) as Record; + } catch { + return null; + } +} + +const sourceDefinitionJsonSchema = loadPythonSourceDefinitionSchema(); const fixtures: SemanticLayerSource[] = [ { @@ -46,10 +54,10 @@ const fixtures: SemanticLayerSource[] = [ }, ]; -describe('resolved source JSON Schema contract', () => { +describe.skipIf(sourceDefinitionJsonSchema === null)('resolved source JSON Schema contract', () => { it('keeps TS resolved-source fixtures accepted by the Python SourceDefinition schema', () => { const ajv = new Ajv2020({ allErrors: true, strict: false }); - const validate = ajv.compile(sourceDefinitionJsonSchema); + const validate = ajv.compile(sourceDefinitionJsonSchema as Record); for (const fixture of fixtures) { const wire = toResolvedWire(fixture);