@@ -3,7 +3,7 @@ import * as azdev from "azure-devops-node-api"
3
3
import { IHeaders , IRequestHandler } from "azure-devops-node-api/interfaces/common/VsoBaseInterfaces" ;
4
4
import util from "util"
5
5
import * as CoreInterfaces from 'azure-devops-node-api/interfaces/CoreInterfaces' ;
6
- import { GitVersionDescriptor , GitVersionType , GitRefUpdate , GitCommitRef , GitPush , GitChange , VersionControlChangeType , GitItem , ItemContentType , GitRef , GitImportRequest , GitRepositoryCreateOptions , GitImportRequestParameters , GitImportGitSource , GitAsyncOperationStatus } from 'azure-devops-node-api/interfaces/GitInterfaces' ;
6
+ import { GitVersionDescriptor , GitVersionType , GitRefUpdate , GitCommitRef , GitPush , GitChange , VersionControlChangeType , GitItem , ItemContentType , GitRef , GitImportRequest , GitRepositoryCreateOptions , GitImportRequestParameters , GitImportGitSource , GitAsyncOperationStatus , VersionControlRecursionType } from 'azure-devops-node-api/interfaces/GitInterfaces' ;
7
7
import * as gitm from "azure-devops-node-api/GitApi"
8
8
import * as BuildInterfaces from 'azure-devops-node-api/interfaces/BuildInterfaces' ;
9
9
import { GitHubCommand } from './github' ;
@@ -940,28 +940,40 @@ class DevOpsCommand {
940
940
let newGitCommit = < GitCommitRef > { }
941
941
newGitCommit . comment = "Add DevOps Pipeline"
942
942
if ( typeof args . settings [ "environments" ] === "string" ) {
943
- newGitCommit . changes = await this . getGitCommitChanges ( args , gitApi , pipelineRepo , args . destinationBranch , this . withoutRefsPrefix ( projectRepo . defaultBranch ) , args . settings [ "environments" ] . split ( '|' ) . map ( element => {
943
+ newGitCommit . changes = await this . getGitCommitChanges ( args , gitApi , projectRepo , pipelineRepo , sourceRef [ 0 ] . name , args . destinationBranch , this . withoutRefsPrefix ( projectRepo . defaultBranch ) , args . settings [ "environments" ] . split ( '|' ) . map ( element => {
944
944
return element . toLowerCase ( ) ;
945
945
} ) )
946
946
}
947
947
else {
948
- newGitCommit . changes = await this . getGitCommitChanges ( args , gitApi , pipelineRepo , args . destinationBranch , this . withoutRefsPrefix ( projectRepo . defaultBranch ) , [ 'validation' , 'test' , 'prod' ] )
948
+ newGitCommit . changes = await this . getGitCommitChanges ( args , gitApi , projectRepo , pipelineRepo , sourceRef [ 0 ] . name , args . destinationBranch , this . withoutRefsPrefix ( projectRepo . defaultBranch ) , [ 'validation' , 'test' , 'prod' ] )
949
949
}
950
- let gitPush = < GitPush > { }
951
- gitPush . refUpdates = [ newRef ]
952
- gitPush . commits = [ newGitCommit ]
953
-
954
- this . logger ?. info ( util . format ( 'Pushing new branch %s' , args . destinationBranch ) )
955
- await gitApi . createPush ( gitPush , projectRepo . id , project . name )
956
-
957
- if ( repositoryName ?. length > 0 ) {
958
- this . logger ?. info ( util . format ( "Repo %s not found" , repositoryName ) )
959
- this . logger ?. info ( 'Did you mean?' )
960
- projectRepos . forEach ( repo => {
961
- if ( repo . name . startsWith ( repositoryName [ 0 ] ) ) {
962
- this . logger ?. info ( repo . name )
963
- }
964
- } ) ;
950
+ if ( newGitCommit . changes . length == 0 ) {
951
+ //Create new branch without any changes
952
+ let newRef = < GitRefUpdate > { } ;
953
+ newRef . newObjectId = sourceRef [ 0 ] . objectId
954
+ newRef . oldObjectId = "0000000000000000000000000000000000000000"
955
+ newRef . name = util . format ( "refs/heads/%s" , args . destinationBranch )
956
+ gitApi . updateRefs ( [ newRef ] , projectRepo . id , project . name )
957
+ this . logger ?. info ( `Created branch ${ args . destinationBranch } ` )
958
+ }
959
+ else {
960
+ //Create new branch with updates to pipeline templates
961
+ let gitPush = < GitPush > { }
962
+ gitPush . refUpdates = [ newRef ]
963
+ gitPush . commits = [ newGitCommit ]
964
+
965
+ this . logger ?. info ( util . format ( 'Pushing new branch %s: %s' , args . destinationBranch , JSON . stringify ( gitPush ) ) )
966
+ await gitApi . createPush ( gitPush , projectRepo . id , project . name )
967
+
968
+ if ( repositoryName ?. length > 0 ) {
969
+ this . logger ?. info ( util . format ( "Repo %s not found" , repositoryName ) )
970
+ this . logger ?. info ( 'Did you mean?' )
971
+ projectRepos . forEach ( repo => {
972
+ if ( repo . name . startsWith ( repositoryName [ 0 ] ) ) {
973
+ this . logger ?. info ( repo . name )
974
+ }
975
+ } ) ;
976
+ }
965
977
}
966
978
}
967
979
return projectRepo ;
@@ -1193,7 +1205,7 @@ class DevOpsCommand {
1193
1205
}
1194
1206
}
1195
1207
1196
- async getGitCommitChanges ( args : DevOpsBranchArguments , gitApi : gitm . IGitApi , pipelineRepo : GitRepository , destinationBranch : string , defaultBranch : string , names : string [ ] ) : Promise < GitChange [ ] > {
1208
+ async getGitCommitChanges ( args : DevOpsBranchArguments , gitApi : gitm . IGitApi , projectRepo : GitRepository , pipelineRepo : GitRepository , sourceBranch : string , destinationBranch : string , defaultBranch : string , names : string [ ] ) : Promise < GitChange [ ] > {
1197
1209
let pipelineProject = args . pipelineProject ?. length > 0 ? args . pipelineProject : args . projectName
1198
1210
let results : GitChange [ ] = [ ]
1199
1211
@@ -1213,40 +1225,46 @@ class DevOpsCommand {
1213
1225
1214
1226
for ( var i = 0 ; i < names . length ; i ++ ) {
1215
1227
this . logger ?. info ( util . format ( "Getting changes for %s" , names [ i ] ) ) ;
1216
- let version : GitVersionDescriptor = < GitVersionDescriptor > { } ;
1217
- version . versionType = GitVersionType . Branch ;
1218
- let templatePath = util . format ( "/Pipelines/build-deploy-%s-SampleSolution.yml" , names [ i ] )
1219
- if ( typeof args . settings [ `${ names [ i ] } -buildtemplate` ] === "string" ) {
1220
- templatePath = args . settings [ `${ names [ i ] } -buildtemplate` ]
1221
- }
1222
1228
1223
- let devOpsOrgUrl = Environment . getDevOpsOrgUrl ( args ) ;
1224
- let contentUrl = `${ devOpsOrgUrl } ${ pipelineProject } /_apis/git/repositories/${ args . pipelineRepository } /items?path=${ templatePath } &includeContent=true&versionDescriptor.version=${ this . withoutRefsPrefix ( pipelineRepo . defaultBranch ) } &versionDescriptor.versionType=branch&api-version=5.0`
1225
- this . logger ?. info ( util . format ( "Getting content from %s" , contentUrl ) ) ;
1226
-
1227
- let response : any = await this . getUrl ( contentUrl , config )
1228
- if ( response ?. content != null ) {
1229
- let commit = < GitChange > { }
1230
- commit . changeType = VersionControlChangeType . Add
1231
- commit . item = < GitItem > { }
1232
- commit . item . path = util . format ( "/%s/deploy-%s-%s.yml" , destinationBranch , names [ i ] , destinationBranch )
1233
- commit . newContent = < ItemContent > { }
1234
-
1235
- commit . newContent . content = response ?. content . toString ( ) . replace ( / B r a n c h C o n t a i n i n g T h e B u i l d T e m p l a t e s / g, defaultBranch )
1236
- commit . newContent . content = ( commit . newContent . content ) ?. replace ( / R e p o s i t o r y C o n t a i n i n g T h e B u i l d T e m p l a t e s / g, `${ pipelineProject } /${ pipelineRepo . name } ` )
1237
- commit . newContent . content = ( commit . newContent . content ) ?. replace ( / S a m p l e S o l u t i o n N a m e / g, destinationBranch )
1238
-
1239
- let variableGroup = args . settings [ names [ i ] + "-variablegroup" ]
1240
- if ( typeof variableGroup !== "undefined" && variableGroup != '' ) {
1241
- commit . newContent . content = ( commit . newContent . content ) ?. replace ( / a l m - a c c e l e r a t o r - v a r i a b l e - g r o u p / g, variableGroup )
1229
+ let repoTemplatePath = util . format ( "/%s/deploy-%s-%s.yml" , destinationBranch , names [ i ] , destinationBranch )
1230
+ let existingItem = await gitApi . getItem ( projectRepo . id , repoTemplatePath , args . projectName , null , VersionControlRecursionType . None , false , true , false , < GitVersionDescriptor > { versionType : GitVersionType . Branch , version : this . withoutRefsPrefix ( sourceBranch ) } )
1231
+
1232
+ this . logger ?. info ( util . format ( "Existing item %s" , existingItem ?. path ) ) ;
1233
+ if ( typeof existingItem === "undefined" || existingItem == null ) {
1234
+ this . logger ?. info ( util . format ( "Pipeline template does not exist %s" , repoTemplatePath ) ) ;
1235
+ let templatePath = util . format ( "/Pipelines/build-deploy-%s-SampleSolution.yml" , names [ i ] )
1236
+ if ( typeof args . settings [ `${ names [ i ] } -buildtemplate` ] === "string" ) {
1237
+ templatePath = args . settings [ `${ names [ i ] } -buildtemplate` ]
1242
1238
}
1243
1239
1244
- commit . newContent . contentType = ItemContentType . RawText
1240
+ let devOpsOrgUrl = Environment . getDevOpsOrgUrl ( args ) ;
1241
+ let contentUrl = `${ devOpsOrgUrl } ${ pipelineProject } /_apis/git/repositories/${ args . pipelineRepository } /items?path=${ templatePath } &includeContent=true&versionDescriptor.version=${ this . withoutRefsPrefix ( pipelineRepo . defaultBranch ) } &versionDescriptor.versionType=branch&api-version=5.0`
1242
+ this . logger ?. info ( util . format ( "Getting content from %s" , contentUrl ) ) ;
1243
+
1244
+ let response : any = await this . getUrl ( contentUrl , config )
1245
+ if ( response ?. content != null ) {
1246
+ let commit = < GitChange > { }
1247
+ commit . changeType = VersionControlChangeType . Add
1248
+ commit . item = < GitItem > { }
1249
+ commit . item . path = util . format ( "/%s/deploy-%s-%s.yml" , destinationBranch , names [ i ] , destinationBranch )
1250
+ commit . newContent = < ItemContent > { }
1251
+
1252
+ commit . newContent . content = response ?. content . toString ( ) . replace ( / B r a n c h C o n t a i n i n g T h e B u i l d T e m p l a t e s / g, defaultBranch )
1253
+ commit . newContent . content = ( commit . newContent . content ) ?. replace ( / R e p o s i t o r y C o n t a i n i n g T h e B u i l d T e m p l a t e s / g, `${ pipelineProject } /${ pipelineRepo . name } ` )
1254
+ commit . newContent . content = ( commit . newContent . content ) ?. replace ( / S a m p l e S o l u t i o n N a m e / g, destinationBranch )
1255
+
1256
+ let variableGroup = args . settings [ names [ i ] + "-variablegroup" ]
1257
+ if ( typeof variableGroup !== "undefined" && variableGroup != '' ) {
1258
+ commit . newContent . content = ( commit . newContent . content ) ?. replace ( / a l m - a c c e l e r a t o r - v a r i a b l e - g r o u p / g, variableGroup )
1259
+ }
1245
1260
1246
- results . push ( commit )
1247
- } else {
1248
- this . logger ?. info ( `Error creating new pipeline definition for ${ names [ i ] } : ${ JSON . stringify ( response ) } ` ) ;
1249
- throw response
1261
+ commit . newContent . contentType = ItemContentType . RawText
1262
+
1263
+ results . push ( commit )
1264
+ } else {
1265
+ this . logger ?. info ( `Error creating new pipeline definition for ${ names [ i ] } : ${ JSON . stringify ( response ) } ` ) ;
1266
+ throw response
1267
+ }
1250
1268
}
1251
1269
}
1252
1270
return results ;
0 commit comments