import { IBuildApi } from "azure-devops-node-api/BuildApi" ; import { Build , BuildDefinitionReference , BuildStatus , } from "azure-devops-node-api/interfaces/BuildInterfaces" ; import path from "path" ; import { installHldToManifestPipeline } from "../../commands/hld/pipeline" ; import { installLifecyclePipeline } from "../../commands/project/pipeline" ; import { installBuildUpdatePipeline } from "../../commands/service/pipeline" ; import { BUILD_SCRIPT_URL , SERVICE_PIPELINE_FILENAME , } from "../../lib/constants" ; import { sleep } from "../../lib/util" ; import { logger } from "../../logger" ; import { APP_REPO , APP_REPO_BUILD , APP_REPO_LIFECYCLE , HLD_REPO , RequestContext , MANIFEST_REPO , } from "./constants" ; import { getAzureRepoUrl } from "./gitService" ; import { build as buildError } from "../../lib/errorBuilder" ; import { errorStatusCode } from "../../lib/errorStatusCode" ; param status export const getBuildStatusString = ( status ) : "Unknown" | "None" | "In Progress" | "Completed" | "Cancelling" | "Postponed" | "Not Started" => { if ( status === undefined ) { return "Unknown" ; } if ( status === BuildStatus . None ) { return "None" ; } if ( status === BuildStatus . InProgress ) { return "In Progress" ; } if ( status === BuildStatus . Completed ) { return "Completed" ; } if ( status === BuildStatus . Cancelling ) { return "Cancelling" ; } if ( status === BuildStatus . Postponed ) { return "Postponed" ; } if ( status === BuildStatus . NotStarted ) { return "Not Started" ; } return "Unknown" ; } ; param buildApi param projectName param pipelineName export const getPipelineByName = async ( buildApi , projectName , pipelineName ) : Promise < BuildDefinitionReference | undefined > => { try { logger . info ( `Finding pipeline ${ pipelineName }` ) ; const defs = await buildApi . getDefinitions ( projectName ) ; return defs . find ( ( d ) => d . name === pipelineName ) ; } catch ( err ) { throw buildError ( errorStatusCode . PIPELINE_ERR , "pipeline-get-by-name-err" , err ) ; } } ; param buildApi param projectName param pipelineName param pipelineId export const deletePipeline = async ( buildApi , projectName , pipelineName , pipelineId ) : Promise < void > => { try { logger . info ( `Deleting pipeline ${ pipelineName }` ) ; await buildApi . deleteDefinition ( projectName , pipelineId ) ; } catch ( err ) { throw buildError ( errorStatusCode . PIPELINE_ERR , "pipeline-del-err" , err ) ; } } ; param buildApi param projectName param pipelineName export const getPipelineBuild = async ( buildApi , projectName , pipelineName ) : Promise < Build > => { try { logger . info ( `Getting queue ${ pipelineName }` ) ; return await buildApi . getLatestBuild ( projectName , pipelineName ) ; } catch ( err ) { throw buildError ( errorStatusCode . PIPELINE_ERR , "pipeline-get-by-buildid-err" , err ) ; } } ; param buildApi param projectName param pipelineName param waitDuration export const pollForPipelineStatus = async ( buildApi , projectName , pipelineName , waitDuration = 15000 ) : Promise < void > => { const oPipeline = await getPipelineByName ( buildApi , projectName , pipelineName ) ; if ( ! oPipeline ) { throw buildError ( errorStatusCode . PIPELINE_ERR , { errorKey : "pipeline-get-status-err-not-found" , values : [ pipelineName ] , } ) ; } let build ; do { await sleep ( waitDuration ) ; build = await getPipelineBuild ( buildApi , projectName , pipelineName ) ; logger . info ( `Status build of ${ pipelineName }: ${ getBuildStatusString ( build ?. status ) }` ) ; } while ( ! build || build . result === 0 ) ; } ; const deletePipelineIfExist = async ( buildApi , rc , pipelineName ) : Promise < void > => { const pipeline = await getPipelineByName ( buildApi , rc . projectName , pipelineName ) ; if ( pipeline && pipeline . id ) { logger . info ( `Pipeline ${ pipelineName } was found - deleting pipeline` ) ; await deletePipeline ( buildApi , rc . projectName , pipelineName , pipeline . id ) ; } } ; param buildApi param rc export const createHLDtoManifestPipeline = async ( buildApi , rc ) : Promise < void > => { const manifestUrl = getAzureRepoUrl ( rc . orgName , rc . projectName , MANIFEST_REPO ) ; const hldUrl = getAzureRepoUrl ( rc . orgName , rc . projectName , HLD_REPO ) ; const pipelineName = `${ HLD_REPO }-to-${ MANIFEST_REPO }` ; try { await deletePipelineIfExist ( buildApi , rc , pipelineName ) ; await installHldToManifestPipeline ( { buildScriptUrl : BUILD_SCRIPT_URL , devopsProject : rc . projectName , hldName : HLD_REPO , hldUrl , manifestUrl , orgName : rc . orgName , personalAccessToken : rc . accessToken , pipelineName , yamlFileBranch : "master" , } ) ; await pollForPipelineStatus ( buildApi , rc . projectName , pipelineName ) ; rc . createdHLDtoManifestPipeline = true ; } catch ( err ) { throw buildError ( errorStatusCode . PIPELINE_ERR , "pipeline-hld-manifest-create-err" , err ) ; } } ; param buildApi param rc export const createLifecyclePipeline = async ( buildApi , rc ) : Promise < void > => { const pipelineName = APP_REPO_LIFECYCLE ; try { await deletePipelineIfExist ( buildApi , rc , pipelineName ) ; await installLifecyclePipeline ( { buildScriptUrl : BUILD_SCRIPT_URL , devopsProject : rc . projectName , orgName : rc . orgName , personalAccessToken : rc . accessToken , pipelineName , repoName : APP_REPO , repoUrl : getAzureRepoUrl ( rc . orgName , rc . projectName , APP_REPO ) , yamlFileBranch : "master" , } ) ; await pollForPipelineStatus ( buildApi , rc . projectName , pipelineName ) ; rc . createdLifecyclePipeline = true ; } catch ( err ) { throw buildError ( errorStatusCode . PIPELINE_ERR , "pipeline-lifecycle-create-err" , err ) ; } } ; param buildApi param rc export const createBuildPipeline = async ( buildApi , rc ) : Promise < void > => { const pipelineName = APP_REPO_BUILD ; try { await deletePipelineIfExist ( buildApi , rc , pipelineName ) ; await installBuildUpdatePipeline ( path . join ( "." , SERVICE_PIPELINE_FILENAME ) , { buildScriptUrl : BUILD_SCRIPT_URL , devopsProject : rc . projectName , orgName : rc . orgName , packagesDir : undefined , personalAccessToken : rc . accessToken , pipelineName , repoName : APP_REPO , repoUrl : getAzureRepoUrl ( rc . orgName , rc . projectName , APP_REPO ) , yamlFileBranch : "master" , } ) ; await pollForPipelineStatus ( buildApi , rc . projectName , pipelineName ) ; rc . createdBuildPipeline = true ; } catch ( err ) { throw buildError ( errorStatusCode . PIPELINE_ERR , "pipeline-build-create-err" , err ) ; } } ;