@@ -17,6 +17,7 @@ import { z } from 'zod';
1717import { editToolParameters } from './editTool' ;
1818import { getAbsolutePath } from '~/lib/stores/files' ;
1919import { streamOutput } from '~/utils/process' ;
20+ import { outputLabels , type OutputLabels } from './deployToolOutputLabels' ;
2021
2122const logger = createScopedLogger ( 'ActionRunner' ) ;
2223
@@ -372,30 +373,79 @@ export class ActionRunner {
372373 case 'deploy' : {
373374 const container = await this . #webcontainer;
374375 await waitForContainerBootState ( ContainerBootState . READY ) ;
375- const convexProc = await container . spawn ( 'sh' , [
376- '-c' ,
377- 'convex dev --once && tsc --noEmit -p tsconfig.app.json' ,
378- ] ) ;
379- action . abortSignal . addEventListener ( 'abort' , ( ) => {
380- convexProc . kill ( ) ;
381- } ) ;
382376
383- const { output, exitCode } = await streamOutput ( convexProc , {
384- onOutput : ( output ) => {
385- this . terminalOutput . set ( output ) ;
386- } ,
387- debounceMs : 50 ,
377+ result = '' ;
378+
379+ const commandErroredController = new AbortController ( ) ;
380+ const abortSignal = AbortSignal . any ( [ action . abortSignal , commandErroredController . signal ] ) ;
381+
382+ /** Return a promise of output on success, throws an error containing output on failure. */
383+ const run = async (
384+ commandAndArgs : string [ ] ,
385+ errorPrefix : OutputLabels ,
386+ onOutput ?: ( s : string ) => void ,
387+ ) : Promise < string > => {
388+ logger . info ( 'starting to run' , errorPrefix ) ;
389+ const t0 = performance . now ( ) ;
390+ const proc = await container . spawn ( commandAndArgs [ 0 ] , commandAndArgs . slice ( 1 ) ) ;
391+ const abortListener : ( ) => void = ( ) => proc . kill ( ) ;
392+ abortSignal . addEventListener ( 'abort' , ( ) => {
393+ logger . info ( 'aborting' , commandAndArgs ) ;
394+ proc . kill ( ) ;
395+ } ) ;
396+ const { output, exitCode } = await streamOutput ( proc , { onOutput, debounceMs : 50 } ) ;
397+
398+ const cleanedOutput = cleanConvexOutput ( output ) ;
399+ const time = performance . now ( ) - t0 ;
400+ logger . debug ( 'finished' , errorPrefix , 'in' , Math . round ( time ) ) ;
401+ if ( exitCode !== 0 ) {
402+ // Kill all other commands
403+ commandErroredController . abort ( `${ errorPrefix } ` ) ;
404+ // This command's output will be reported exclusively
405+ throw new Error ( `[${ errorPrefix } ] Failed with exit code ${ exitCode } : ${ cleanedOutput } ` ) ;
406+ }
407+ abortSignal . removeEventListener ( 'abort' , abortListener ) ;
408+ if ( cleanedOutput . trim ( ) . length === 0 ) {
409+ return '' ;
410+ }
411+ return cleanedOutput + '\n\n' ;
412+ } ;
413+
414+ // START deploy tool call
415+ // /
416+ // /
417+ // codegen `convex typecheck` includes typecheck of convex/ dir
418+ // + typecheck
419+ // |
420+ // |
421+ // app typecheck `tsc --noEmit --project tsconfig.app.json
422+ // \
423+ // \
424+ // deploy `deploy` can fail
425+
426+ const runCodegenAndTypecheck = async ( onOutput ?: ( output : string ) => void ) => {
427+ // Convex codegen does a convex directory typecheck, then tsc does a full-project typecheck.
428+ let output = await run ( [ 'convex' , 'codegen' ] , outputLabels . convexTypecheck , onOutput ) ;
429+ output += await run (
430+ [ 'tsc' , '--noEmit' , '-p' , 'tsconfig.app.json' ] ,
431+ outputLabels . frontendTypecheck ,
432+ onOutput ,
433+ ) ;
434+ return output ;
435+ } ;
436+
437+ const t0 = performance . now ( ) ;
438+ result += await runCodegenAndTypecheck ( ( output ) => {
439+ this . terminalOutput . set ( output ) ;
388440 } ) ;
389- const cleanedOutput = cleanConvexOutput ( output ) ;
390- if ( exitCode !== 0 ) {
391- throw new Error ( `Convex failed with exit code ${ exitCode } : ${ cleanedOutput } ` ) ;
392- }
393- result = cleanedOutput ;
441+ result += await run ( [ 'convex' , 'dev' , '--once' , '--typecheck=disable' ] , outputLabels . convexDeploy ) ;
442+ const time = performance . now ( ) - t0 ;
443+ logger . info ( 'deploy action finished in' , time ) ;
394444
395445 // Start the default preview if it’s not already running
396446 if ( ! workbenchStore . isDefaultPreviewRunning ( ) ) {
397447 const shell = this . #shellTerminal( ) ;
398- await shell . startCommand ( 'npx vite --open' ) ;
448+ await shell . startCommand ( 'vite --open' ) ;
399449 result += '\n\nDev server started successfully!' ;
400450 }
401451
0 commit comments