@@ -4,6 +4,7 @@ import { spawnSync } from "node:child_process";
44import fs from "node:fs" ;
55import os from "node:os" ;
66import path from "node:path" ;
7+ import { waitForDeployment } from "./deployment-status.mjs" ;
78
89const root = path . resolve ( import . meta. dirname , ".." ) ;
910const localStaging = process . argv . includes ( "--local-staging" ) ;
@@ -56,6 +57,28 @@ function authentication(tokenKey) {
5657 return requireValue ( tokenKey ) ;
5758}
5859
60+ async function confirmReady ( result , cwd , project , token , label ) {
61+ return waitForDeployment ( result . deployment ?. id , {
62+ label,
63+ read : async id => {
64+ if ( ! token ) {
65+ const inspected = vercel ( [ "inspect" , id , "--json" ] , cwd , project ) ;
66+ return inspected . deployment ?? inspected ;
67+ }
68+ const endpoint = new URL ( `https://api.vercel.com/v13/deployments/${ id } ` ) ;
69+ endpoint . searchParams . set ( "teamId" , requireValue ( "VERCEL_ORG_ID" ) ) ;
70+ const response = await fetch ( endpoint , {
71+ headers : { Authorization : `Bearer ${ token } ` } ,
72+ signal : AbortSignal . timeout ( 30_000 ) ,
73+ } ) ;
74+ if ( ! response . ok ) throw new Error ( `${ label } status lookup failed (${ response . status } ).` ) ;
75+ const deployment = await response . json ( ) ;
76+ if ( deployment . projectId !== project ) throw new Error ( `${ label } deployment belongs to a different project.` ) ;
77+ return { id : deployment . id , readyState : deployment . readyState } ;
78+ } ,
79+ } ) ;
80+ }
81+
5982function deploySource ( ) {
6083 const result = spawnSync ( "git" , [ "ls-files" , "-z" ] , { cwd : root , encoding : "utf8" , windowsHide : true } ) ;
6184 if ( result . status !== 0 ) throw new Error ( "Cannot enumerate tracked deployment source." ) ;
@@ -103,8 +126,9 @@ async function main() {
103126 const frontendSource = deploySource ( ) ;
104127 fs . copyFileSync ( path . join ( backendSource , "vercel.backend.json" ) , path . join ( backendSource , "vercel.json" ) ) ;
105128 const deployArgs = [ "deploy" , "--prod" , "--yes" , "--json" , "--meta" , `sourceCommit=${ sha } ` , "--meta" , `sourceBranch=${ branch } ` ] ;
106- const backend = vercel ( [ ...deployArgs , "--project" , backendProject ] , backendSource , backendProject , authentication ( "VERCEL_BACKEND_TOKEN" ) ) ;
107- if ( backend . status === "error" || backend . deployment ?. readyState !== "READY" ) throw new Error ( "Backend deployment did not become ready." ) ;
129+ const backendToken = authentication ( "VERCEL_BACKEND_TOKEN" ) ;
130+ const backend = vercel ( [ ...deployArgs , "--project" , backendProject ] , backendSource , backendProject , backendToken ) ;
131+ await confirmReady ( backend , backendSource , backendProject , backendToken , "Backend" ) ;
108132 await check ( `${ backendOrigin } /api/platform/health` , async r => r . ok && ( await r . json ( ) ) . status === "ok" ) ;
109133 await check ( `${ backendOrigin } /api/platform/auth/session` , async r => {
110134 if ( ! r . ok ) return false ;
@@ -113,8 +137,9 @@ async function main() {
113137 } ) ;
114138 console . log ( "Backend is ready; database-backed session check passed." ) ;
115139
116- const frontend = vercel ( [ ...deployArgs , "--project" , frontendProject ] , frontendSource , frontendProject , authentication ( "VERCEL_FRONTEND_TOKEN" ) ) ;
117- if ( frontend . status === "error" || frontend . deployment ?. readyState !== "READY" ) throw new Error ( "Frontend deployment did not become ready." ) ;
140+ const frontendToken = authentication ( "VERCEL_FRONTEND_TOKEN" ) ;
141+ const frontend = vercel ( [ ...deployArgs , "--project" , frontendProject ] , frontendSource , frontendProject , frontendToken ) ;
142+ await confirmReady ( frontend , frontendSource , frontendProject , frontendToken , "Frontend" ) ;
118143 await check ( publicOrigin , async r => r . ok && ( branch === "main" || r . headers . get ( "x-robots-tag" ) ?. includes ( "noindex" ) ) ) ;
119144 console . log ( `Frontend is ready: ${ publicOrigin } ` ) ;
120145 const summary = `### ${ branch === "main" ? "Production" : "Staging" } deployment\n\nCommit: \`${ sha } \`\n\n- Frontend: ${ publicOrigin } \n- Backend: ${ backendOrigin } \n- Health and database-backed session checks passed.\n` ;
0 commit comments