Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions scripts/post-deploy-smoke.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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 ?? ''
Expand Down Expand Up @@ -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)`,
Expand Down
18 changes: 17 additions & 1 deletion tests/postDeploySmoke.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { describe, expect, it } from 'vitest'
import { afterEach, describe, expect, it, vi } from 'vitest'
import {
runPostDeploySmokeCheck,
validateDetailedHealthPayload,
validatePublicHealthPayload,
} from '../scripts/post-deploy-smoke.mjs'

describe('post-deploy smoke helpers', () => {
afterEach(() => {
vi.restoreAllMocks()
})

it('accepts valid public health payloads', () => {
expect(() =>
validatePublicHealthPayload({
Expand Down Expand Up @@ -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
Expand All @@ -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,
Expand Down Expand Up @@ -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', () => {
Expand Down