diff --git a/scripts/post-deploy-smoke.mjs b/scripts/post-deploy-smoke.mjs index 2ef612e..4e9c056 100644 --- a/scripts/post-deploy-smoke.mjs +++ b/scripts/post-deploy-smoke.mjs @@ -82,6 +82,24 @@ export function validateDetailedHealthPayload(payload, expectedRuntimeMode) { } } +function formatHealthWarnings(payload) { + if (!Array.isArray(payload?.warnings) || payload.warnings.length === 0) { + return null + } + + return payload.warnings + .map((warning) => { + if (!warning || typeof warning.message !== 'string') { + return null + } + + const code = typeof warning.code === 'string' && warning.code.length > 0 ? `${warning.code}: ` : '' + return `${code}${warning.message}` + }) + .filter(Boolean) + .join(' | ') +} + export async function runPostDeploySmokeCheck(options = {}) { const healthUrl = options.healthUrl ?? process.env.DJD_HEALTHCHECK_URL ?? 'https://djdagentscore.dev/health' const adminKey = options.adminKey ?? process.env.DJD_ADMIN_KEY ?? '' @@ -126,6 +144,10 @@ export async function runPostDeploySmokeCheck(options = {}) { console.log( `[smoke] OK after ${attempt} attempt(s): public + admin health verified for runtime=${expectedRuntimeMode}${expectedReleaseSha ? ` release=${expectedReleaseSha.slice(0, 7)}` : ''}`, ) + const warningSummary = formatHealthWarnings(detailedPayload) + if (warningSummary) { + console.log(`[smoke] Admin health warnings: ${warningSummary}`) + } } else { console.log( `[smoke] OK after ${attempt} attempt(s): public health verified${expectedReleaseSha ? ` release=${expectedReleaseSha.slice(0, 7)}` : ''} (admin runtime verification skipped; DJD_ADMIN_KEY not set)`, diff --git a/tests/postDeploySmoke.test.ts b/tests/postDeploySmoke.test.ts index d79e4bc..d725719 100644 --- a/tests/postDeploySmoke.test.ts +++ b/tests/postDeploySmoke.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from 'vitest' +import { afterEach, describe, expect, it, vi } from 'vitest' import { runPostDeploySmokeCheck, validateDetailedHealthPayload, @@ -6,6 +6,10 @@ import { } from '../scripts/post-deploy-smoke.mjs' describe('post-deploy smoke helpers', () => { + afterEach(() => { + vi.restoreAllMocks() + }) + it('accepts valid public health payloads', () => { expect(() => validatePublicHealthPayload({ @@ -40,6 +44,7 @@ describe('post-deploy smoke helpers', () => { }) it('retries through transient failures and succeeds once health is good', async () => { + const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {}) let callCount = 0 const fetchMock = async (_url, init) => { callCount += 1 @@ -57,6 +62,12 @@ describe('post-deploy smoke helpers', () => { status: 'ok', modelVersion: '2.5.0', experimentalStatus: true, + warnings: [ + { + code: 'github_token_missing', + message: 'GITHUB_TOKEN not set — GitHub verification is limited to unauthenticated rate limits.', + }, + ], runtime: { mode: 'combined', apiEnabled: true, @@ -97,6 +108,11 @@ describe('post-deploy smoke helpers', () => { ).resolves.toBeUndefined() globalThis.fetch = originalFetch + expect(consoleSpy).toHaveBeenCalledWith( + expect.stringContaining( + '[smoke] Admin health warnings: github_token_missing: GITHUB_TOKEN not set — GitHub verification is limited to unauthenticated rate limits.', + ), + ) }) it('rejects a release SHA mismatch when one is expected', () => {