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:
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)
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.