How to execute a special build on TFS using Team Foundation Object Model (TFS APIs) – Part 2

Posted by: Subodh Sohoni , on 7/6/2009, in Category VSTS & TFS (Azure DevOps)
Views: 39828
Abstract: In the first part of this article we have started with the case for creating code for an application which will allow the Build and Release Managers to configure a custom build and execute that. We have now come to the heart of the program where we will set the label to the files which are either in the base build or are added later on.
How to execute a special build on TFS using Team Foundation Object Model (TFS APIs) – Part 2
 
In the first part of this article How to execute a special build on TFS using Team Foundation Object Model (TFS APIs) – Part 1 we have started with the case for creating code for an application which will allow the Build and Release Managers to configure a custom build and execute that.
Through this tool, those Build and Managers will be able to:
* Select a previous build
* View changesets which are created after that build, with their comments 
* Select all or few changesets from the list to be included in the next build
* Label them with a temporary label
* Execute that build
* Finally, associate the selected changesets with the executed build while overriding the default behaviour of the Team Build.
In the first part of the article we have completed the code for selection of Build Definition, Build, Changesets after that build was executed and changesets which need to be considered for the next build. The entire set of code files is uploaded in a project at CodePlex at http://custombuildmanager.codeplex.com .
We have now come to the heart of the program where we will set the label to the files which are either in the base build or are added later on. We will omit build definition folder so that we do not build unnecessary files. Before we label the files we will delete any existing label of the same name. 
C# 
public void SetLabel(List<int> ichangeSets, string LabelName, string SelectedBuild)
        {
            //First get changesets for the build
            //for that create an array of items labeled with selected build number
            LabelVersionSpec LabelSpec = new LabelVersionSpec(SelectedBuild);           
            ItemSet LabeledItems = tfvc.GetItems("$/" + project, LabelSpec, RecursionType.Full);
            Item[] items = LabeledItems.Items;           
            // Now add the latest changeset associated with each item
            List<int> csInBuild = new List<int>();
            foreach (Item item in items)
            {
                csInBuild.Add(item.ChangesetId);
            }
            //now add changeset numbers passed by parameter ichangesets and remove duplicates if any and sort them
            foreach (int cs in ichangeSets)
            {
                csInBuild.Add(cs);
            }
            changeSets = removeDuplicates(csInBuild);
            changeSets.Sort();
            //Create a versioncontrol object
            VersionControlLabel labelToCreate = new VersionControlLabel(tfvc, LabelName,
fvc.AuthenticatedUser, "$/" + project, "Demo Label");
            //Create labeled items. Remove items which are for build configuration files
            List<LabelItemSpec> labelItemsSpecs = new List<LabelItemSpec>();
            for (int i = 0; i < changeSets.Count; i++)
            {
                foreach (Change change in tfvc.GetChangeset(changeSets[i]).Changes)
                {
                    if (!change.Item.ServerItem.Contains("TeamBuildTypes"))
                    {
                        ItemSpec changeSetItemSpec = new ItemSpec(change.Item.ServerItem,
RecursionType.Full);
                        labelItemsSpecs.Add(new LabelItemSpec(changeSetItemSpec, new
ChangesetVersionSpec(changeSets[i]), false));
                    }
               
            }
            //Now actually label the items. Remove the exisitng label if any.
            try
            {
                LabelResult[] PrevResults = tfvc.DeleteLabel(LabelName, "$/" + project);
            }
            catch
            {
            }
            LabelResult[] results = tfvc.CreateLabel(labelToCreate, labelItemsSpecs.ToArray(),
LabelChildOption.Replace);
        }
 
VB.NET 
Public Sub SetLabel(ByVal ichangeSets As List(Of Integer), ByVal LabelName As String, ByVal SelectedBuild As String)
                  'First get changesets for the build
                  'for that create an array of items labeled with selected build number
                  Dim LabelSpec As New LabelVersionSpec(SelectedBuild)
                  Dim LabeledItems As ItemSet = tfvc.GetItems("$/" & project, LabelSpec, RecursionType.Full)
                  Dim items() As Item = LabeledItems.Items
                  ' Now add the latest changeset associated with each item
                  Dim csInBuild As New List(Of Integer)()
                  For Each item As Item In items
                        csInBuild.Add(item.ChangesetId)
                  Next item
                  'now add changeset numbers passed by parameter ichangesets and remove duplicates if any and sort them
                  For Each cs As Integer In ichangeSets
                        csInBuild.Add(cs)
                  Next cs
                  changeSets = removeDuplicates(csInBuild)
                  changeSets.Sort()
                  'Create a versioncontrol object
                  Dim labelToCreate As New VersionControlLabel(tfvc, LabelName, fvc.AuthenticatedUser, "$/" & project, "Demo Label")
                  'Create labeled items. Remove items which are for build configuration files
                  Dim labelItemsSpecs As New List(Of LabelItemSpec)()
                  For i As Integer = 0 To changeSets.Count - 1
                        For Each change As Change In tfvc.GetChangeset(changeSets(i)).Changes
                              If (Not change.Item.ServerItem.Contains("TeamBuildTypes")) Then
                                    Dim changeSetItemSpec As New ItemSpec(change.Item.ServerItem, RecursionType.Full)
                                    labelItemsSpecs.Add(New LabelItemSpec(changeSetItemSpec, New ChangesetVersionSpec(changeSets(i)), False))
                              End If
 
                        Next change
                  'Now actually label the items. Remove the exisitng label if any.
                  Try
                        Dim PrevResults() As LabelResult = tfvc.DeleteLabel(LabelName, "$/" & project)
                  Catch
                  End Try
                  Dim results() As LabelResult = tfvc.CreateLabel(labelToCreate, labelItemsSpecs.ToArray(), LabelChildOption.Replace)
                  Next i
 
Now that we have the labelled version which we want to build, we will use the TFS Build APIs to actually execute the build and associate the changesets which we have gathered with that build.
 
C# 
public bool ModifyTfsBuildProj(string label, string SelectedBuild)
        {
            try
            {
                List<Changeset> changeSetList = new List<Changeset>();
                foreach(int cs in changeSets)
                {
                    changeSetList.Add(tfvc.GetChangeset(cs));
                }
                //Get the build defiition object
                IBuildDefinition buildDef = bs.GetBuildDefinition(project, SelectedBuildType);               
                //Create a build request object
                IBuildRequest request = buildDef.CreateBuildRequest();
                // Specify that we want to get labeled version
                request.GetOption = GetOption.Custom;
                request.CustomGetVersion = "LDemo";
                //Put the build in queue
                QueuedBuild = bs.QueueBuild(request);
                // Get the details object of the queued build so that we can associate changesets to it.
                IBuildDetail build = QueuedBuild.Build;              
                //Specify that we want to associate non-default changesets
                InformationNodeConverters.AddAssociatedChangesets(build, changeSetList.ToArray());
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        } 
 
VB.NET 
Public Function ModifyTfsBuildProj(ByVal label As String, ByVal SelectedBuild As String) As Boolean
                  Try
                        Dim changeSetList As New List(Of Changeset)()
                        For Each cs As Integer In changeSets
                              changeSetList.Add(tfvc.GetChangeset(cs))
                        Next cs
                        'Get the build defiition object
                        Dim buildDef As IBuildDefinition = bs.GetBuildDefinition(project, SelectedBuildType)
                        'Create a build request object
                        Dim request As IBuildRequest = buildDef.CreateBuildRequest()
                        ' Specify that we want to get labeled version
                        request.GetOption = GetOption.Custom
                        request.CustomGetVersion = "LDemo"
                        'Put the build in queue
                        QueuedBuild = bs.QueueBuild(request)
                        ' Get the details object of the queued build so that we can associate changesets to it.
                        Dim build As IBuildDetail = QueuedBuild.Build
                        'Specify that we want to associate non-default changesets
                        InformationNodeConverters.AddAssociatedChangesets(build, changeSetList.ToArray())
                        Return True
                  Catch ex As Exception
                        Return False
                  End Try
End Function
 
Only a small part of the code remains now that is to delete the label 
C# 
public void DeleLabel()
        {
            tfvc.DeleteLabel("Demo", "$/" + project);
        }
 
VB.NET 
Public Sub DeleLabel()
                  tfvc.DeleteLabel("Demo", "$/" & project)
End Sub
 
TfsBuild.Proj file of the build which needs to be executed should have an overriding target named CoreGetChangeSetsAndAssociateWorkItems. This target should be empty to override the default behaviour of Team Build. By default Team Build compares the labels of old build and new build of the same type and associates only the changesets which are not in the earlier label. It should appear as:
<Target Name="CoreGetChangesetsAndUpdateWorkItems" />
Summary: What this code has shown us is the functionality to handle various operations related to build and version control through code. We have seen how to find the build definitions, builds of specific definition, changesets which were considered for that build, latest changeset in the repository, label the files in a list of changesets, execute the build which does not get the latest version but a labelled version and finally associate certain changesets with the executing build.

The entire set of code is available for download from http://custombuildmanager.codeplex.com. It is just a boilerplate and beta code and author makes no explicit assertion about the completeness and accuracy of code but it should get you going on a path to create your own application.

If you liked the article,  Subscribe to the RSS Feed or Subscribe Via Email
  
Subodh Sohoni is a VSTS MVP, MCTS - Microsoft Team Foundation Server - Configuration and Development and also is a Microsoft Certified Trainer(MCT) since 2004. Subodh works as VP, Technology with SEED Infotech Ltd

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce the The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this eBook aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on .NET Standard and the upcoming C# 8.0 too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Subodh is a consultant and corporate trainer. He has overall 28+ years of experience. His specialization is Application Lifecycle Management and Team Foundation Server. He is Microsoft MVP – VS ALM, MCSD – ALM and MCT. He has conducted more than 300 corporate trainings and consulting assignments. He is also a Professional SCRUM Master. He guides teams to become Agile and implement SCRUM. Subodh is authorized by Microsoft to do ALM Assessments on behalf of Microsoft. Follow him on twitter @subodhsohoni


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by Zeppelin on Monday, March 8, 2010 10:12 AM
where do I download TFS SDK? I don't have the DLLs referenced in your solution
Comment posted by Subodh Sohoni on Wednesday, March 10, 2010 10:16 PM
Those dll are available when you install TFS or Team Explorer. I have not checked in the TFS SDK.

Categories

JOIN OUR COMMUNITY

POPULAR ARTICLES

C# .NET BOOK

C# Book for Building Concepts and Interviews

Tags

JQUERY COOKBOOK

jQuery CookBook