#!/usr/bin/env node const DEFAULT_URL = 'http://127.0.0.1/api/v1/health/version'; const url = process.argv[2] || process.env.RUNTIME_VERSION_URL || DEFAULT_URL; const expectedVersion = process.argv[3] || process.env.APP_VERSION || process.env.GITHUB_SHA || ''; const attempts = Number.parseInt(process.env.RUNTIME_VERSION_ATTEMPTS || '30', 10); const intervalMs = Number.parseInt(process.env.RUNTIME_VERSION_INTERVAL_MS || '2000', 10); const timeoutMs = Number.parseInt(process.env.RUNTIME_VERSION_TIMEOUT_MS || '5000', 10); function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } function isVersionPayload(value) { return ( value && typeof value === 'object' && value.service === 'server' && typeof value.version === 'string' ); } async function fetchVersion() { const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), timeoutMs); try { const response = await fetch(url, { signal: controller.signal }); if (!response.ok) { throw new Error(`HTTP ${response.status}`); } const payload = await response.json(); if (!isVersionPayload(payload)) { throw new Error(`Unexpected payload: ${JSON.stringify(payload)}`); } return payload; } finally { clearTimeout(timeout); } } let lastError = null; for (let attempt = 1; attempt <= attempts; attempt += 1) { try { const payload = await fetchVersion(); if (expectedVersion && payload.version !== expectedVersion) { throw new Error(`Expected ${expectedVersion}, got ${payload.version}`); } console.log(`Runtime version verified: ${payload.version}`); process.exit(0); } catch (error) { lastError = error; if (attempt < attempts) { await sleep(intervalMs); } } } console.error(`Runtime version check failed for ${url}: ${lastError?.message || 'unknown error'}`); process.exit(1);