0
votes

We have TFS 2017 and we using TFVC.

We have vNext build definition with many source code mapping from many branches (all the code is required for the build).

At the end of the build (if he passed successfully) I want to take all the local code from the agent folder (with the local folder structure) and check-in all the code to separate branch ("release branch" for example) and keep the folders structure.

(We want one branch with all the "working" code, in the development, we can't work with one branch, because the build required many different sources).

I thought about something like this:

  • Create a new folder
  • Create a new workspace in this folder
  • Mapping the folder to "release branch"
  • Copy all the code to this folder
  • Check in the files to the branch

One thing to consider: we have many builds definitions and we want to do it for all, so for each build, we want to create a folder on the "release branch" and check in the code to there. so I need to check if the folder exist, if yes - check in, is not - create a folder and check in.

How can I do that? (tf.exe?)

UPDATE:

I succeed with tf.exe tool to achieve that unless one issue:

tf.exe can't detect automatically deleted files, I need to specify which items are deleted from the workspace. how can I do that? (I have a folder with hundreds of folders and subfolders)

1
It's difficult to answer this question without understanding why you have multiple branches in a single build. Ideally all of the code required to build your application would be in a single branch as merging from multiple sources in to a "Release" branch could very quickly become overwhelming, especially if the branching hierarchy is complex. Taking the source from the build server and using that to create a branch or check in isn't a good idea as you would lose traceability of where the code came from. If you could give us some more detail about your branching strategy that would helpJames Reed
@JamesReed Is a huge traditional project that use in many packages and source code from many branches and folders, I don't know really the branching strategy and I can't change it from my position...Shayki Abramczyk

1 Answers

0
votes

I figure it out by creating a branch in each succeed build (not the best way but is not CI and we don't have many builds).

Because tf barnch not create a branch (unless the source is from a branch) I copy all the source code from the agent to temp workspace, then I check-in to TFS, it creates a new folder with my code, then I convert the folder to a branch.

Param(
[string]$path
)
$newCodeFolderPath = "$($env:Agent_BuildDirectory)\newCode"
$tempWorkspacePath =  "$($env:Agent_BuildDirectory)\tempWorkspace"

New-Item -Path $newCodeFolderPath -ItemType directory

Copy-Item -Path "$($env:Build_SourcesDirectory)/*" -Recurse -Destination $newCodeFolderPath 

New-Item -Path $tempWorkspacePath -ItemType directory

cd $tempWorkspacePath 

$tfExe = "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\tf.exe"

& $tfExe workspace /collection:{TfsCollection} /new "TempWorkspace" /noprompt

& $tfExe workfold "$($path)/Release/$($env:Build_BuildNumber)" $tempWorkspacePath 

Copy-Item -Path "$($newCodeFolderPath)/*" -Recurse -Destination $tempWorkspacePath 

& $tfExe add * /recursive /noignore

& $tfExe checkin /recursive /comment:"from vNext build"

& $tfExe workspace /delete /collection:{TfsCollection} "Tempworkspace"

cd c:/
Remove-Item -Path $newCodeFolderPath -Force -Recurse
Remove-Item -Path $tempWorkspacePath -Force -Recurse

$releaseBranchPath = "$($path)/Release/$($env:Build_BuildNumber)
Write-Host ("##vso[task.setvariable variable=releaseBranchPath;]$releaseBranchPath")

In the build PowerShell task, I pass the $path variable, for example $/MyProject/V1/Name, the script will create folder Release (in the first time) and in the Release folder will create a folder with all the code.

After that, I need to convert the folder to a branch, so I write a small tool in C# (you need TFS API libraries):

try
{
  string collectionUrl = {myCollection};
  string releaseBranchPath = Environment.GetEnvironmentVariable("releaseBranchPath");
  var tp = TfsTeamProjectCollection(new Uri (collectionUrl));
  var versionControl = tp.GetService<VersionControlServer>();
  versionControl.CreateaBranchPbject(new BranchProperties(new ItemIdentifier(releaseBranchPath)));
}
catch (Execption e)
{
  Console.WriteLine(e.Message);
}

I compiled it and I run the .exe with Command Line task after the PowerShell task.