@@ -23,6 +23,7 @@ async function packNextRuntimeImpl() {
2323}
2424
2525let packNextRuntimePromise : ReturnType < typeof packNextRuntimeImpl > | null = null
26+ let nextRuntimePacked = false
2627function packNextRuntime ( ) {
2728 if ( ! packNextRuntimePromise ) {
2829 packNextRuntimePromise = packNextRuntimeImpl ( )
@@ -38,13 +39,60 @@ export class NextDeployInstance extends NextInstance {
3839 private _shouldDeleteDeploy : boolean = false
3940 private _isCurrentlyDeploying : boolean = false
4041 private _deployOutput : string = ''
42+ private _setupStartTime = Date . now ( )
43+ private _intervalsToClear : NodeJS . Timeout [ ] = [ ]
4144
4245 public get buildId ( ) {
4346 // get deployment ID via fetch since we can't access
4447 // build artifacts directly
4548 return this . _buildId
4649 }
4750
51+ private packNextRuntime ( ) {
52+ if ( ! packNextRuntimePromise ) {
53+ if ( ! nextRuntimePacked ) {
54+ this . _deployOutput += this . getTimestampPrefix ( ) + 'Pack Next Runtime ...\n'
55+ }
56+ packNextRuntimePromise = packNextRuntimeImpl ( )
57+ packNextRuntimePromise . then ( ( ) => {
58+ nextRuntimePacked = true
59+ } )
60+ if ( ! nextRuntimePacked ) {
61+ this . _deployOutput += this . getTimestampPrefix ( ) + 'Pack Next Runtime DONE\n'
62+ }
63+ }
64+
65+ return packNextRuntimePromise
66+ }
67+
68+ private clearIntervals ( ) {
69+ for ( const interval of this . _intervalsToClear ) {
70+ clearInterval ( interval )
71+ }
72+ this . _intervalsToClear = [ ]
73+ }
74+
75+ private getTimestampPrefix ( ) {
76+ return `[${ new Date ( ) . toISOString ( ) } ] (+${ ( ( Date . now ( ) - this . _setupStartTime ) / 1000 ) . toFixed ( 3 ) } s) `
77+ }
78+
79+ private async ps ( ) {
80+ const netlifyStatusPromise = execa ( 'ps' , [ 'aux' ] )
81+
82+ netlifyStatusPromise . stdout . on ( 'data' , this . handleOutput )
83+ netlifyStatusPromise . stderr . on ( 'data' , this . handleOutput )
84+
85+ await netlifyStatusPromise
86+ }
87+
88+ private handleOutput ( chunk ) {
89+ const timestampPrefix = this . getTimestampPrefix ( )
90+
91+ this . _deployOutput +=
92+ ( this . _deployOutput === '' || this . _deployOutput . endsWith ( '\n' ) ? timestampPrefix : '' ) +
93+ chunk . toString ( ) . replace ( / \n (? = .) / gm, `\n${ timestampPrefix } ` )
94+ }
95+
4896 public async setup ( parentSpan : Span ) {
4997 if ( process . env . SITE_URL && process . env . BUILD_ID ) {
5098 require ( 'console' ) . log ( 'Using existing deployment: ' + process . env . SITE_URL )
@@ -54,51 +102,47 @@ export class NextDeployInstance extends NextInstance {
54102 return
55103 }
56104
57- let deployStartTime = Date . now ( )
58-
59105 this . _isCurrentlyDeploying = true
60106
61- const setupStartTime = Date . now ( )
62-
107+ this . _deployOutput += this . getTimestampPrefix ( ) + 'Setting up test dir ...\n'
63108 // create the test site
64109 await super . createTestDir ( { parentSpan, skipInstall : true } )
110+ this . _deployOutput += this . getTimestampPrefix ( ) + 'Setting up test dir DONE\n'
65111
66112 // If the test fixture has node modules we need to move them aside then merge them in after
67113
68114 const nodeModules = path . join ( this . testDir , 'node_modules' )
69115 const nodeModulesBak = `${ nodeModules } .bak`
70116
71117 if ( fs . existsSync ( nodeModules ) ) {
118+ this . _deployOutput += this . getTimestampPrefix ( ) + 'Rename node_modules ...\n'
72119 await fs . rename ( nodeModules , nodeModulesBak )
120+ this . _deployOutput += this . getTimestampPrefix ( ) + 'Rename node_modules DONE\n'
73121 }
74122
75- const { runtimePackageName, runtimePackageTarballPath } = await packNextRuntime ( )
76-
77- const handleOutput = ( chunk ) => {
78- const timestampPrefix = `[${ new Date ( ) . toISOString ( ) } ] (+${ ( ( Date . now ( ) - deployStartTime ) / 1000 ) . toFixed ( 3 ) } s) `
79-
80- this . _deployOutput +=
81- ( this . _deployOutput === '' || this . _deployOutput . endsWith ( '\n' ) ? timestampPrefix : '' ) +
82- chunk . toString ( ) . replace ( / \n (? = .) / gm, `\n${ timestampPrefix } ` )
83- }
123+ const { runtimePackageName, runtimePackageTarballPath } = await this . packNextRuntime ( )
84124
85125 // install dependencies
126+ this . _deployOutput += this . getTimestampPrefix ( ) + 'Install dependencies ...\n'
86127 const installResPromise = execa ( 'npm' , [ 'i' , runtimePackageTarballPath , '--legacy-peer-deps' ] , {
87128 cwd : this . testDir ,
88129 } )
89130
90- installResPromise . stdout . on ( 'data' , handleOutput )
91- installResPromise . stderr . on ( 'data' , handleOutput )
131+ installResPromise . stdout . on ( 'data' , this . handleOutput )
132+ installResPromise . stderr . on ( 'data' , this . handleOutput )
92133
93134 await installResPromise
135+ this . _deployOutput += this . getTimestampPrefix ( ) + 'Install dependencies DONE\n'
94136
95137 if ( fs . existsSync ( nodeModulesBak ) ) {
96138 // move the contents of the fixture node_modules into the installed modules
139+ this . _deployOutput += this . getTimestampPrefix ( ) + 'Move fixture node_modules ...\n'
97140 for ( const file of await fs . readdir ( nodeModulesBak ) ) {
98141 await fs . move ( path . join ( nodeModulesBak , file ) , path . join ( nodeModules , file ) , {
99142 overwrite : true ,
100143 } )
101144 }
145+ this . _deployOutput += this . getTimestampPrefix ( ) + 'Move fixture node_modules DONE\n'
102146 }
103147
104148 // use next runtime package installed by the test runner
@@ -133,8 +177,8 @@ export class NextDeployInstance extends NextInstance {
133177 try {
134178 const netlifyStatusPromise = execa ( 'npx' , [ 'netlify' , 'status' , '--json' ] )
135179
136- netlifyStatusPromise . stdout . on ( 'data' , handleOutput )
137- netlifyStatusPromise . stderr . on ( 'data' , handleOutput )
180+ netlifyStatusPromise . stdout . on ( 'data' , this . handleOutput )
181+ netlifyStatusPromise . stderr . on ( 'data' , this . handleOutput )
138182
139183 await netlifyStatusPromise
140184 } catch ( err ) {
@@ -163,11 +207,75 @@ export class NextDeployInstance extends NextInstance {
163207 } ,
164208 )
165209
166- deployResPromise . stdout . on ( 'data' , handleOutput )
167- deployResPromise . stderr . on ( 'data' , handleOutput )
210+ this . _deployOutput +=
211+ this . getTimestampPrefix ( ) + `Started deploy, PID: ${ deployResPromise . pid } \n`
212+ require ( 'console' ) . log ( `Started deploy, PID: ${ deployResPromise . pid } ` )
213+
214+ deployResPromise . stdout . on ( 'data' , this . handleOutput )
215+ deployResPromise . stderr . on ( 'data' , this . handleOutput )
216+
217+ deployResPromise . on ( 'error' , ( err ) => {
218+ this . _deployOutput += this . getTimestampPrefix ( ) + `Error during deployment: ${ err . message } \n`
219+ require ( 'console' ) . error ( `Error during deployment: ${ err . message } ` )
220+ } )
221+
222+ deployResPromise . on ( 'spawn' , ( err ) => {
223+ this . _deployOutput += this . getTimestampPrefix ( ) + `Process spawned\n`
224+ require ( 'console' ) . error ( `Process spawned` )
225+ } )
226+
227+ deployResPromise . on ( 'disconnect' , ( err ) => {
228+ this . _deployOutput += this . getTimestampPrefix ( ) + `Process disconnected\n`
229+ require ( 'console' ) . error ( `Process disconnected` )
230+ } )
231+
232+ deployResPromise . on ( 'close' , ( code , signal ) => {
233+ this . _deployOutput +=
234+ this . getTimestampPrefix ( ) + `Process closed with code: ${ code } / signal: ${ signal } \n`
235+ require ( 'console' ) . error ( `Process closed with code: ${ code } / signal: ${ signal } ` )
236+ } )
237+
238+ deployResPromise . on ( 'exit' , ( code , signal ) => {
239+ this . _deployOutput +=
240+ this . getTimestampPrefix ( ) + `Process exited with code: ${ code } / signal: ${ signal } \n`
241+ require ( 'console' ) . error ( `Process exited with code: ${ code } / signal: ${ signal } ` )
242+ } )
243+
244+ this . _intervalsToClear . push (
245+ setInterval ( ( ) => {
246+ this . _deployOutput +=
247+ this . getTimestampPrefix ( ) +
248+ 'Waiting for netlify deploy process to finish ... (killed: ${deployResPromise.killed}, connected: ${deployResPromise.connected})\n'
249+ } , 5000 ) ,
250+ )
251+
252+ this . _intervalsToClear . push (
253+ setInterval ( ( ) => {
254+ this . ps ( )
255+ } , 30_000 ) ,
256+ )
257+
258+ deployResPromise
259+ . then ( ( result ) => {
260+ require ( 'console' ) . log ( `Netlify deploy process finished.` )
261+ this . _deployOutput += this . getTimestampPrefix ( ) + 'Netlify deploy process finished.\n'
262+ } )
263+ . catch ( ( err ) => {
264+ require ( 'console' ) . log ( `Netlify deploy process failed. ` + err )
265+ this . _deployOutput += this . getTimestampPrefix ( ) + 'Netlify deploy process failed. ' + err
266+ } )
267+ . finally ( ( ) => {
268+ require ( 'console' ) . log ( `Netlify deploy process finally.` )
269+ this . _deployOutput += this . getTimestampPrefix ( ) + 'Netlify deploy process finally.\n'
270+ this . clearIntervals ( )
271+ } )
168272
169273 const deployRes = await deployResPromise
170274
275+ this . clearIntervals ( )
276+
277+ require ( 'console' ) . log ( `Deploy finished. Processing output...` )
278+
171279 if ( deployRes . exitCode !== 0 ) {
172280 // clear deploy output to avoid printing it again in destroy()
173281 this . _deployOutput = ''
@@ -210,12 +318,13 @@ export class NextDeployInstance extends NextInstance {
210318 ) . trim ( )
211319
212320 require ( 'console' ) . log ( `Got buildId: ${ this . _buildId } ` )
213- require ( 'console' ) . log ( `Setup time: ${ ( Date . now ( ) - setupStartTime ) / 1000.0 } s` )
321+ require ( 'console' ) . log ( `Setup time: ${ ( Date . now ( ) - this . _setupStartTime ) / 1000.0 } s` )
214322
215323 this . _isCurrentlyDeploying = false
216324 }
217325
218326 public async destroy ( ) : Promise < void > {
327+ this . clearIntervals ( )
219328 if ( this . _shouldDeleteDeploy ) {
220329 require ( 'console' ) . log ( `Deleting project with deploy_id ${ this . _deployId } ` )
221330
0 commit comments