import { Context , VersionBumpType } from "./context" ; import { bumpDependencies } from "./bumpDependencies" ; import { bumpVersion } from "./bumpVersion" ; import { fatal , runPolicyCheckWithFix } from "./utils" ; import { MonoRepo , MonoRepoKind } from "../common/monoRepo" ; import { Package } from "../common/npmPackage" ; export function getPackageShortName ( pkgName ) { let name = pkgName . split ( "/" ) . pop ( ) ! ; if ( name . startsWith ( "fluid-" ) ) { name = name . substring ( "fluid-" . length ) ; } return name ; } /**
 * Bump package version of the client monorepo
 * If it has dependencies to the current version of the other monorepo packages, bump package version of those too
 *
 * If --commit or --release is specified, the bumpped version changes will be committed and a release branch will be created
 */ export async function releaseVersion ( context , releaseName , updateLock , releaseVersion ? ) { await runPolicyCheckWithFix ( context . gitRepo ) ; if ( releaseVersion === undefined ) { if ( ! context . originalBranchName . startsWith ( "release/" ) ) { fatal ( `Patch release should only be done on 'release/*' branches, but current branch is '${ context . originalBranchName }'` ) ; } } else if ( releaseVersion !== "patch" ) { fatal ( `Only patch release is allowed. ${ releaseVersion } specified` ) ; } const remote = await context . gitRepo . getRemote ( context . originRemotePartialUrl ) ; if ( ! remote ) { fatal ( `Unable to find remote for '${ context . originRemotePartialUrl }'` ) ; } if ( ! await context . gitRepo . isBranchUpToDate ( context . originalBranchName , remote ) ) { fatal ( `Local '${ context . originalBranchName }' branch not up to date with remote. Please pull from '${ remote }'.` ) ; } const depVersions = await context . collectBumpInfo ( releaseName ) ; let releaseGroup ; let packages = [ ] ; let monoRepo ; for ( const [ name ] of depVersions . repoVersions ) { if ( depVersions . needRelease ( name ) ) { if ( releaseGroup ) { const pkg = context . fullPackageMap . get ( name ) ; if ( pkg && pkg . name === releaseGroup ) { packages . push ( pkg ) ; } } else { if ( name === MonoRepoKind [ MonoRepoKind . Client ] ) { monoRepo = context . repo . clientMonoRepo ; break ; } if ( name === MonoRepoKind [ MonoRepoKind . Server ] ) { monoRepo = context . repo . serverMonoRepo ; break ; } const pkg = context . fullPackageMap . get ( name ) ; if ( ! pkg ) { fatal ( `Unable find package ${ name }` ) ; } releaseGroup = pkg . group ; packages . push ( pkg ) ; } } } if ( ! monoRepo && packages . length === 0 ) { fatal ( "Nothing to release" ) ; } if ( monoRepo ) { return releaseMonoRepo ( context , monoRepo , updateLock ) ; } return releasePackages ( context , packages , updateLock ) ; } /**
 * Release a set of packages
 */ async function releasePackages ( context , packages , updateLock ) { await context . gitRepo . fetchTags ( ) ; const packageShortName = [ ] ; const packageTags = [ ] ; const packageNeedBump = new Map < string , string | undefined > ( ) ; const packageToRelease = [ ] ; for ( const pkg of packages ) { const name = getPackageShortName ( pkg . name ) ; const tagName = `${ name }_v${ pkg . version }` ; packageShortName . push ( name ) ; packageTags . push ( tagName ) ; if ( ( await context . gitRepo . getTags ( tagName ) ) . trim ( ) !== tagName ) { packageToRelease . push ( pkg ) ; } else { packageNeedBump . set ( pkg . name , undefined ) ; } } if ( packageToRelease . length !== 0 ) { console . log ( "======================================================================================================" ) ; console . log ( `Please manually queue a release build for the following packages in ADO for branch ${ context . originalBranchName }` ) ; for ( const pkg of packageToRelease ) { console . log ( `  ${ pkg . name }` ) ; } console . log ( `After the build is done successfully run --release again to bump version and update dependency` ) ; return ; } const pkgBumpString = packageShortName . join ( " " ) ; return postRelease ( context , packageTags . join ( " " ) , pkgBumpString , packageNeedBump , updateLock ) ; } async function releaseMonoRepo ( context , monoRepo , updateLock ) { const kind = MonoRepoKind [ monoRepo . kind ] ; const kindLowerCase = MonoRepoKind [ monoRepo . kind ] . toLowerCase ( ) ; const tagName = `${ kindLowerCase }_v${ monoRepo . version }` ; await context . gitRepo . fetchTags ( ) ; if ( ( await context . gitRepo . getTags ( tagName ) ) . trim ( ) !== tagName ) { console . log ( "======================================================================================================" ) ; console . log ( `Please manually queue a release build for the following packages in ADO for branch ${ context . originalBranchName }` ) ; console . log ( `  ${ kindLowerCase }` ) ; console . log ( `After the build is done successfully run --release again to bump version and update dependency` ) ; return ; } const bumpDep = new Map < string , string | undefined > ( ) ; bumpDep . set ( kind , undefined ) ; return postRelease ( context , tagName , kindLowerCase , bumpDep , updateLock ) ; } async function postRelease ( context , tagNames , packageNames , bumpDep , updateLock ) { console . log ( `Tag ${ tagNames } exists.` ) ; console . log ( `Bump version and update dependency for ${ packageNames }` ) ; const bumpBranch = `patch_bump_${ Date . now ( ) }` ; await context . createBranch ( bumpBranch ) ; const fixPrereleaseCommitMessage = `Also remove pre-release dependencies for ${ packageNames }` ; const message = await bumpDependencies ( context , fixPrereleaseCommitMessage , bumpDep , updateLock , false , true ) ; await bumpVersion ( context , [ ... bumpDep . keys ( ) ] , "patch" , packageNames , message ? `\n\n${ fixPrereleaseCommitMessage }\n${ message }` : "" ) ; console . log ( "======================================================================================================" ) ; console . log ( `Please create PR for branch ${ bumpBranch } targeting ${ context . originalBranchName }` ) ; console . log ( `After PR is merged run --release list the next release` ) ; }