import * as vscode from 'vscode' ; import { IActionContext , UserCancelledError } from 'vscode-azureextensionui' ; import { ext } from '../extensionVariables' ; import { localize } from '../localize' ; import { ScmType } from '../ScmType' ; import { taskUtils } from '../utils/taskUtils' ; import { IDeployContext } from './IDeployContext' ; export async function runPreDeployTask ( context , deployFsPath , scmType ) { const preDeployResult = await tryRunPreDeployTask ( context , deployFsPath , scmType ) ; if ( preDeployResult . failedToFindTask ) { throw new Error ( `Failed to find pre-deploy task "${ preDeployResult . taskName }". Modify your tasks or the setting "${ ext . prefix }.preDeployTask".` ) ; } else if ( preDeployResult . exitCode !== undefined && preDeployResult . exitCode !== 0 ) { await handleFailedPreDeployTask ( context , preDeployResult ) ; } } export async function tryRunPreDeployTask ( context , deployFsPath , scmType ) { const settingKey = 'preDeployTask' ; const taskName = vscode . workspace . getConfiguration ( ext . prefix , vscode . Uri . file ( deployFsPath ) ) . get ( settingKey ) ; context . telemetry . properties . hasPreDeployTask = String ( ! ! taskName ) ; let preDeployTaskResult = { taskName , exitCode : undefined , failedToFindTask : false } ; if ( taskName && shouldExecuteTask ( context , scmType , settingKey , taskName ) ) { const task = await taskUtils . findTask ( deployFsPath , taskName ) ; context . telemetry . properties . foundPreDeployTask = String ( ! ! task ) ; if ( task ) { const progressMessage = localize ( 'runningTask' , 'Running preDeployTask "{0}"...' , taskName ) ; await vscode . window . withProgress ( { location : vscode . ProgressLocation . Notification , title : progressMessage } , async ( ) => { await taskUtils . executeIfNotActive ( task ) ; preDeployTaskResult = await waitForPreDeployTask ( task , deployFsPath ) ; context . telemetry . properties . preDeployTaskExitCode = String ( preDeployTaskResult . exitCode ) ; } ) ; } else { preDeployTaskResult . failedToFindTask = true ; } } return preDeployTaskResult ; } /**
 * Starts the post deploy task, but doesn't wait for the result (not worth it)
 */ export async function startPostDeployTask ( context , deployFsPath , scmType , resourceName ) { const settingKey = 'postDeployTask' ; const taskName = vscode . workspace . getConfiguration ( ext . prefix , vscode . Uri . file ( deployFsPath ) ) . get ( settingKey ) ; context . telemetry . properties . hasPostDeployTask = String ( ! ! taskName ) ; if ( taskName && shouldExecuteTask ( context , scmType , settingKey , taskName ) ) { const task = await taskUtils . findTask ( deployFsPath , taskName ) ; context . telemetry . properties . foundPostDeployTask = String ( ! ! task ) ; if ( task ) { await taskUtils . executeIfNotActive ( task ) ; ext . outputChannel . appendLog ( localize ( 'startedPostDeployTask' , 'Started {0} "{1}".' , settingKey , taskName ) , { resourceName } ) ; } else { ext . outputChannel . appendLog ( localize ( 'noPostDeployTask' , 'WARNING: Failed to find {0} "{1}".' , settingKey , taskName ) , { resourceName } ) ; } } } export interface IPreDeployTaskResult { taskName : string | undefined ; exitCode : number | undefined ; failedToFindTask : boolean ; } function shouldExecuteTask ( context , scmType , settingKey , taskName ) { const shouldExecute = context . deployMethod === 'storage' || context . deployMethod === 'zip' || ( scmType !== ScmType . LocalGit && scmType !== ScmType . GitHub ) ; if ( ! shouldExecute ) { ext . outputChannel . appendLog ( localize ( 'ignoringDeployTask' , 'WARNING: Ignoring {0} "{1}" for non-zip deploy.' , settingKey , taskName ) ) ; } return shouldExecute ; } async function waitForPreDeployTask ( preDeployTask , deployFsPath ) { return await new Promise ( ( resolve ) : void => { const errorListener = vscode . tasks . onDidEndTaskProcess ( ( e ) => { if ( taskUtils . isTaskInScopeOfPath ( e . execution . task , deployFsPath ) && e . exitCode !== 0 ) { errorListener . dispose ( ) ; resolve ( { taskName : e . execution . task . name , exitCode : e . exitCode , failedToFindTask : false } ) ; } if ( taskUtils . isTaskEqual ( e . execution . task , preDeployTask ) ) { errorListener . dispose ( ) ; resolve ( { taskName : e . execution . task . name , exitCode : e . exitCode , failedToFindTask : false } ) ; } } ) ; } ) ; } export async function handleFailedPreDeployTask ( context , preDeployResult ) { const message = localize ( 'taskFailed' , 'Errors exist after running preDeployTask "{0}". See task output for more info.' , preDeployResult . taskName ) ; const deployAnyway = { title : localize ( 'deployAnyway' , 'Deploy Anyway' ) } ; const openSettings = { title : localize ( 'openSettings' , 'Open Settings' ) } ; const result = await vscode . window . showErrorMessage ( message , { modal : true } , deployAnyway , openSettings ) ; if ( result === deployAnyway ) { context . telemetry . properties . preDeployTaskResponse = 'deployAnyway' ; } else if ( result === openSettings ) { context . telemetry . properties . preDeployTaskResponse = 'openSettings' ; await vscode . commands . executeCommand ( 'workbench.action.openSettings' ) ; throw new UserCancelledError ( 'preDeployFailed|OpenSettings' ) ; } else { context . telemetry . properties . preDeployTaskResponse = 'cancel' ; throw new UserCancelledError ( 'preDeployFailed' ) ; } }