Skip to content

Commit f0862ad

Browse files
authored
Merge pull request #12 from jdorrance/codex/deploy-readiness
Allow Cloudflare readiness checks to wait through propagation
2 parents 6e4bb21 + 9ee8538 commit f0862ad

2 files changed

Lines changed: 15 additions & 3 deletions

File tree

‎scripts/smoke-api.test.ts‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { manifestSchema } from '@av/contracts';
44
import { ApiClient, type PinnedBuild } from '@av/contracts/client';
55
import { probeApi, readResponseBytes, validateHealthContract, verifyWorkerReadiness } from './smoke-api';
66

7-
afterEach(() => vi.restoreAllMocks());
7+
afterEach(() => { vi.useRealTimers(); vi.restoreAllMocks(); });
88

99
const deploymentId = `${'a'.repeat(40)}-12345-2`;
1010

@@ -46,10 +46,22 @@ describe('Worker readiness after deployment', () => {
4646
expect(fetchImpl).toHaveBeenCalledTimes(2);
4747
});
4848

49+
it('waits through a rollout that keeps serving the previous version for 25 seconds', async () => {
50+
vi.useFakeTimers();
51+
const startedAt = Date.now();
52+
const fetchImpl = vi.fn(async () => Response.json({
53+
ok: true, deploymentId: Date.now() - startedAt >= 25_000 ? deploymentId : 'previous'
54+
}));
55+
const ready = expect(verifyWorkerReadiness({ url, expectedDeploymentId: deploymentId, fetchImpl })).resolves.toBeUndefined();
56+
await vi.advanceTimersByTimeAsync(25_000);
57+
await ready;
58+
expect(fetchImpl).toHaveBeenCalledTimes(6);
59+
});
60+
4961
it('fails after the default bounded retries if the URL keeps serving a different deployment', async () => {
5062
const fetchImpl = vi.fn(async () => Response.json({ ok: true, deploymentId: `${'b'.repeat(40)}-12345-2` }));
5163
await expect(verifyWorkerReadiness({ url, expectedDeploymentId: deploymentId, fetchImpl, delayMs: 0 })).rejects.toThrow(/Worker readiness verification failed:.*expected Worker deployment marker/);
52-
expect(fetchImpl).toHaveBeenCalledTimes(4);
64+
expect(fetchImpl).toHaveBeenCalledTimes(13);
5365
});
5466

5567
it('reports the final HTTP failure when readiness never succeeds', async () => {

‎scripts/smoke-api.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export async function readResponseBytes(response: Response, limit = 1024 * 1024)
2727
export interface RetryOptions { retries?: number; delayMs?: number }
2828
export async function retryProbe(label: string, check: () => Promise<void>, options: RetryOptions = {}): Promise<void> {
2929
let last = '';
30-
for (let attempt = 0; attempt <= (options.retries ?? 3); attempt++) {
30+
for (let attempt = 0; attempt <= (options.retries ?? 12); attempt++) {
3131
if (attempt) await new Promise(resolve => setTimeout(resolve, options.delayMs ?? 5000));
3232
try { await check(); return; }
3333
catch (error) { last = error instanceof Error ? error.message : String(error); }

0 commit comments

Comments
 (0)