Tarun Arora

Visual Studio ALM MVP
posts - 58, comments - 187, trackbacks - 0

My Links

News


Tarun Arora is a Microsoft Certified professional developer for Enterprise Applications. He has extensively travelled around the world gaining experience learning and working in culturally diverse teams. Tarun has over 5 years of experience developing 'Energy Trading & Risk Management' solutions for leading Trading & Banking Enterprises. His passion for technology has earned him the Microsoft Community Contributor and Microsoft MVP Award.




View Tarun Arora's profile on LinkedIn

profile for Tarun Arora at Stack Overflow, Q&A for professional and enthusiast programmers

Tag Cloud

Article Categories

Archives

Post Categories

Image Galleries

Sunday, May 20, 2012

TFS API Find out who deleted your build?

 

I am sure you have been in the situation where you start following a change through the list of builds and suddenly realize a lot of the builds have been deleted by some one! The good news is, when the build is deleted from the build explorer in Visual Studio it is only soft deleted in the database.

Are you wondering who moved your cheese?

In this blog post, I'll give you a walkthrough on how to write a simple utility to get the list of deleted builds and their details using the TFS API.

Download the sample application – wpf, .net 4, you need to have vs sdk installed on your machine to run it.

image 

1. Connect to TFS using the API

If you are new to the TFS API, refer to this blog post on getting started with the Visual Studio SDK.

The below snippet will help present a connect to tfs pop up to the user

private TfsTeamProjectCollection _tfs;
private string _selectedTeamProject;

public bool ConnectToTfs()
{
      bool isSelected = false;
      TeamProjectPicker tfsPP = new TeamProjectPicker(TeamProjectPickerMode.SingleProject, false);
      tfsPP.ShowDialog();
      this._tfs = tfsPP.SelectedTeamProjectCollection;

      if (tfsPP.SelectedProjects.Count() > 0)
      {
          this._selectedTeamProject = tfsPP.SelectedProjects[0].Name;
          isSelected = true;
      }
      return isSelected;
 }
 

2. Get All the build definitions for the selected Team Project using the TFS API

By using the IBuildService you can get access to the QueryBuildDefinition method which takes team project and returns the build definitions associated to the team project.

private IBuildDefinition[] GetAllBuildDefinitionsFromTheTeamProject(_selectTeamProject)
{
      _bs = _tfs.GetService<IBuildServer>();
      return _bs.QueryBuildDefinitions(_selectedTeamProject);
}
 

3. Get all the deleted builds for the chosen build definition using the TFS API

By using the QueryBuilds methods it is possible to construct a query to confine the search to builds for the selected build definition that have been marked as deleted.

// bdef is the selected build definition
var bdef = (((ComboBox)sender).SelectedItem) as IBuildDefinition;

if (bdef != null)
{
        // _bs = IBuildServer service, create a new query
        var def = _bs.CreateBuildDetailSpec(_selectedTeamProject);
        // only bring back the last 100 deleted builds
        def.MaxBuildsPerDefinition = 100;
        // query for only deleted builds
        def.QueryDeletedOption = QueryDeletedOption.OnlyDeleted;
        // Last deleted should be returned 1st
        def.QueryOrder = BuildQueryOrder.FinishTimeDescending;
        // Only look for deleted builds in the chosen build definition
        def.DefinitionSpec.Name = bdef.Name;
        // Bring back deleted builds from any state
        def.Status = BuildStatus.All;
        // Pass this query for processing to the build service
        var builds = _bs.QueryBuilds(def).Builds;

        // Add each deleted build to a local buildDetail entity,
        // You could switch this with Console.WriteLine if you
        // would like to see the output instead. 
        foreach (var build in builds)
        {
              dgBuildDetails.Items.Add(new BuildDetail()
              {
                    BuildStatus = build.Status.ToString(),
                    BuildNumber = build.BuildNumber,
                    BuildDef = build.BuildDefinition.Name,
                    TeamProject = build.TeamProject,
                    RequestedBy = build.RequestedBy,
                    RequestedOn = build.FinishTime.ToString(),
                    DeletedBy = build.LastChangedBy,
                    DeletedOn = build.LastChangedOn.ToString()
              });
       }
}

 

4. Putting it all together

Download the sample application – wpf, .net 4, you need to have vs sdk installed on your machine to run it.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.TestManagement.Client;
using Microsoft.TeamFoundation.VersionControl.Client;

namespace TfsApiGetDeletedBuildDetails
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private TfsTeamProjectCollection _tfs;
        private string _selectedTeamProject;
        private IBuildServer _bs;
        private VersionControlServer _vcs;

        public bool ConnectToTfs()
        {
            bool isSelected = false;
            TeamProjectPicker tfsPP = new TeamProjectPicker(TeamProjectPickerMode.SingleProject, false);
            tfsPP.ShowDialog();
            this._tfs = tfsPP.SelectedTeamProjectCollection;

            if (tfsPP.SelectedProjects.Count() > 0)
            {
                this._selectedTeamProject = tfsPP.SelectedProjects[0].Name;
                isSelected = true;
            }
            return isSelected;
        }

        private void btnConnect_Click(object sender, RoutedEventArgs e)
        {
            if (ConnectToTfs())
            {
                cbBuildDef.IsEnabled = true;
                _vcs = _tfs.GetService<VersionControlServer>();
                cbBuildDef.ItemsSource = GetAllBuildDefinitionsFromTheTeamProject();
                cbBuildDef.DisplayMemberPath = "Name";
                cbBuildDef.SelectedValuePath = "Uri";
                cbBuildDef.SelectedIndex = 0;
            }
        }

        // Grab all build definitions
        private IBuildDefinition[] GetAllBuildDefinitionsFromTheTeamProject()
        {
            _bs = _tfs.GetService<IBuildServer>();
            return _bs.QueryBuildDefinitions(_selectedTeamProject);
        }

        public class BuildDetail
        {
            public string BuildStatus { get; set; }
            public string BuildNumber { get; set; }
            public string BuildDef { get; set; }
            public string TeamProject { get; set; }
            public string RequestedBy { get; set; }
            public string RequestedOn { get; set; }
            public string DeletedBy { get; set; }
            public string DeletedOn { get; set; }
        }

        // Get All Deleted Builds for the selected build definition 
        private void cbBuildDef_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            dgBuildDetails.Items.Clear();

            List<BuildDetail> buildDetails = new List<BuildDetail>();

            // bdef is the selected build definition
            var bdef = (((ComboBox)sender).SelectedItem) as IBuildDefinition;

            if (bdef != null)
            {
                // _bs = IBuildServer service, create a new query
                var def = _bs.CreateBuildDetailSpec(_selectedTeamProject);
                // only bring back the last 100 deleted builds
                def.MaxBuildsPerDefinition = 100;
                // query for only deleted builds
                def.QueryDeletedOption = QueryDeletedOption.OnlyDeleted;
                // Last deleted should be returned 1st
                def.QueryOrder = BuildQueryOrder.FinishTimeDescending;
                // Only look for deleted builds in the chosen build definition
                def.DefinitionSpec.Name = bdef.Name;
                // Bring back deleted builds from any state
                def.Status = BuildStatus.All;
                // Pass this query for processing to the build service
                var builds = _bs.QueryBuilds(def).Builds;

                // Add each deleted build to a local buildDetail entity,
                // You could switch this with Console.WriteLine if you
                // would like to see the output instead. 
                foreach (var build in builds)
                {
                    dgBuildDetails.Items.Add(new BuildDetail()
                                    {
                                        BuildStatus = build.Status.ToString(),
                                        BuildNumber = build.BuildNumber,
                                        BuildDef = build.BuildDefinition.Name,
                                        TeamProject = build.TeamProject,
                                        RequestedBy = build.RequestedBy,
                                        RequestedOn = build.FinishTime.ToString(),
                                        DeletedBy = build.LastChangedBy,
                                        DeletedOn = build.LastChangedOn.ToString()
                                    });
                }
            }
        }

        private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
        {
            Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri));
            e.Handled = true;

        }
    }
}

 

Thank you for taking the time out and reading this blog post. If you enjoyed the post, remember to subscribe to http://feeds.feedburner.com/TarunArora.

Check out the other posts on cool tools using TFS API. In love

Posted On Sunday, May 20, 2012 4:43 PM | Feedback (1) | Filed Under [ TFS API TFS SDK ]

Wednesday, May 16, 2012

Get Detailed Build Test Results using the TFS API

 

It’s a Friday evening and you have just checked in that last bit of code, you are waiting for the build to go all green so that you could call it a day. Just then the build summary page comes back red on the test results section. The build summary page tells you that 1 of the test namely HelloWorld.Tests.UnitTest1.Sum_TwoIntNumbers_IncorrectResult_TestMethod has failed…

image

To know why the test has failed, you have no option but to click on View Test Results link which in turn downloads the trx file from the server so that you can see the error message and possibly identify the root cause of failure from the description error message. If the test list contains more than a 1000 tests you will notice that it takes a lot of time in downloading the test results locally. That’s probably not what you would want to do on a Friday evening…

image

In this blog post I’ll show you how to use the TFS API to write a simple utility to pull down the test result details programmatically and a bonus power tool for those who read the complete post, let’s get started…

A peek at what we will get to…

image

1. Connecting to TFS using the API

If you are new to the TFS API, refer to this blog post on getting started with the Visual Studio SDK.

The below snippet will help present a connect to tfs pop up to the user

private TfsTeamProjectCollection _tfs;
private string _selectedTeamProject;

public void ConnectToTfs()
{
       TeamProjectPicker tfsPP = new TeamProjectPicker(TeamProjectPickerMode.SingleProject, false);
       tfsPP.ShowDialog();
       this._tfs = tfsPP.SelectedTeamProjectCollection;
       this._selectedTeamProject = tfsPP.SelectedProjects[0].Name;
}

 

2. Get All Build Definitions for the selected Team Project

By using the IBuildService you can get access to the QueryBuildDefinition method which takes team project and returns the build definitions associated to the team project.

private IBuildDefinition[] GetAllBuildDefinitionsFromTheTeamProject(_selectTeamProject)
{
      _bs = _tfs.GetService<IBuildServer>();
      return _bs.QueryBuildDefinitions(_selectedTeamProject);
}

 

3. Get All Builds Associated to the Build Definition

Get All Builds in the build definition for specific build Definition specifications programmatically, this helps you narrow down the search and get the selected few filtered results, like in the snippet below, we specify the maximum number of builds to return, what build quality builds to return, etc.

// Get All Builds for the selected build definition 
private void cbBuildDef_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
       var bdef = (((ComboBox)sender).SelectedItem) as IBuildDefinition;
       var def = _bs.CreateBuildDetailSpec(_selectedTeamProject);
       def.MaxBuildsPerDefinition = 10;
       def.QueryOrder = BuildQueryOrder.FinishTimeDescending;
       def.DefinitionSpec.Name = bdef.Name;
       def.Status = BuildStatus.All;
       var builds = _bs.QueryBuilds(def).Builds;

        cbBuild.ItemsSource = _bs.QueryBuilds(def).Builds;
        cbBuild.DisplayMemberPath = "BuildNumber";
        cbBuild.SelectedValuePath = "Uri";
        cbBuild.SelectedIndex = 0;
}

 

4. Get all the Test Results associated to a Build

I’ll be using the ITestManagementService to pull all test runs associated to a build. As you can see below by using the QueryResultsByOutcome I can query for tests that passed or failed or tests that errored. You could also use the QueryResultsByOwner to get test results by individual tfs users.

private void GetTestResult(Uri buildUri)
{
       _tms = _tfs.GetService<ITestManagementService>();
       var testRuns = _tms.GetTeamProject(_selectedTeamProject).TestRuns.ByBuild(buildUri);

        foreach (var testRun in testRuns)
        {
             lstTestRunDetails.Items.Add(string.Format("{0}", testRun.Title));
             lstTestRunDetails.Items.Add(string.Format("TestRunId: {0} | TestPlanId: {1}", testRun.Id, testRun.TestPlanId));
             lstTestRunDetails.Items.Add(string.Format("TestSettingsId: {0} | TestEnvironmentId {1} ", testRun.TestSettingsId, testRun.TestEnvironmentId));

             var totalTests = testRun.Statistics.TotalTests;

              foreach (var et in testRun.QueryResultsByOutcome(TestOutcome.Error))
              {
                    lstTestRunDetails.Items.Add(string.Format("{0}: {1} - {2}", et.Outcome, et.TestCaseTitle, et.ErrorMessage));
              }

              foreach (var tp in testRun.QueryResultsByOutcome(TestOutcome.Passed))
              {
                    lstTestRunDetails.Items.Add(string.Format("{0}: {1} ", tp.Outcome, tp.TestCaseTitle));
               }

                foreach (var tf in testRun.QueryResultsByOutcome(TestOutcome.Failed))
                {
                    lstTestRunDetails.Items.Add(string.Format("{0}: {1} - {2}", tf.Outcome, tf.TestCaseTitle, tf.ErrorMessage));
                }

                foreach (var tw in testRun.QueryResultsByOutcome(TestOutcome.Warning))
                {
                    lstTestRunDetails.Items.Add(string.Format("{0}: {1} - {2}", tw.Outcome, tw.TestCaseTitle, tw.ErrorMessage));
                }

                foreach (var ta in testRun.QueryResultsByOutcome(TestOutcome.Aborted))
                {
                    lstTestRunDetails.Items.Add(string.Format("{0}: {1} - {2}", ta.Outcome, ta.TestCaseTitle, ta.ErrorMessage));
                }

                foreach (var tb in testRun.QueryResultsByOutcome(TestOutcome.Blocked))
                {
                    lstTestRunDetails.Items.Add(string.Format("{0}: {1} - {2}", tb.Outcome, tb.TestCaseTitle, tb.ErrorMessage));
                }

                foreach (var ti in testRun.QueryResultsByOutcome(TestOutcome.Inconclusive))
                {
                    lstTestRunDetails.Items.Add(string.Format("{0}: {1} - {2}", ti.Outcome, ti.TestCaseTitle, ti.ErrorMessage));
                }

                foreach (var to in testRun.QueryResultsByOutcome(TestOutcome.Timeout))
                {
                    lstTestRunDetails.Items.Add(string.Format("{0}: {1} - {2}", to.Outcome, to.TestCaseTitle, to.ErrorMessage));
                }

                // Get the test results by user by passing in the Test Foundation Identity
                // testRun.QueryResultsByOwner(TeamFoundationIdentity);
            }

            if(testRuns.Count() == 0)
                lstTestRunDetails.Items.Add("No Test Results have been associated with the selected build");
 }

 

5. Putting it all together

Download the sample application – wpf, .net 4, you need to have vs sdk installed on your machine to run it.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.TestManagement.Client;
using Microsoft.TeamFoundation.VersionControl.Client;

namespace TfsApiGetTestResultsAndDetailsByStatus
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private TfsTeamProjectCollection _tfs;
        private string _selectedTeamProject;
        private IBuildServer _bs;
        private VersionControlServer _vcs;
        private ITestManagementService _tms;

        public void ConnectToTfs()
        {
            TeamProjectPicker tfsPP = new TeamProjectPicker(TeamProjectPickerMode.SingleProject, false);
            tfsPP.ShowDialog();
            this._tfs = tfsPP.SelectedTeamProjectCollection;
            this._selectedTeamProject = tfsPP.SelectedProjects[0].Name;
        }

        private void btnConnect_Click(object sender, RoutedEventArgs e)
        {
            ConnectToTfs();
            _vcs = _tfs.GetService<VersionControlServer>();
            cbBuildDef.ItemsSource = GetAllBuildDefinitionsFromTheTeamProject();
            cbBuildDef.DisplayMemberPath = "Name";
            cbBuildDef.SelectedValuePath = "Uri";
            cbBuildDef.SelectedIndex = 0;
        }

        private IBuildDefinition[] GetAllBuildDefinitionsFromTheTeamProject()
        {
            _bs = _tfs.GetService<IBuildServer>();
            return _bs.QueryBuildDefinitions(_selectedTeamProject);
        }

        // Get All Builds for the selected build definition 
        private void cbBuildDef_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var bdef = (((ComboBox)sender).SelectedItem) as IBuildDefinition;
            var def = _bs.CreateBuildDetailSpec(_selectedTeamProject);
            def.MaxBuildsPerDefinition = 10;
            def.QueryOrder = BuildQueryOrder.FinishTimeDescending;
            def.DefinitionSpec.Name = bdef.Name;
            def.Status = BuildStatus.All;
            var builds = _bs.QueryBuilds(def).Builds;

            cbBuild.ItemsSource = _bs.QueryBuilds(def).Builds;
            cbBuild.DisplayMemberPath = "BuildNumber";
            cbBuild.SelectedValuePath = "Uri";
            cbBuild.SelectedIndex = 0;
        }

        private void cbBuild_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var build = (((ComboBox)sender).SelectedItem) as IBuildDetail;
            if (build == null && ((ComboBox)sender).Items.Count != 0)
            {
                build = ((ComboBox)sender).Items[0] as IBuildDetail;
                var def = _bs.CreateBuildDetailSpec(_selectedTeamProject);
                GetTestResult(build.Uri);
            }
        }

        private void GetTestResult(Uri buildUri)
        {
            _tms = _tfs.GetService<ITestManagementService>();
            var testRuns = _tms.GetTeamProject(_selectedTeamProject).TestRuns.ByBuild(buildUri);

            foreach (var testRun in testRuns)
            {
                lstTestRunDetails.Items.Add(string.Format("{0}", testRun.Title));
                lstTestRunDetails.Items.Add(string.Format("TestRunId: {0} | TestPlanId: {1}", testRun.Id, testRun.TestPlanId));
                lstTestRunDetails.Items.Add(string.Format("TestSettingsId: {0} | TestEnvironmentId {1} ", testRun.TestSettingsId, testRun.TestEnvironmentId));

                var totalTests = testRun.Statistics.TotalTests;

                foreach (var et in testRun.QueryResultsByOutcome(TestOutcome.Error))
                {
                    lstTestRunDetails.Items.Add(string.Format("{0}: {1} - {2}", et.Outcome, et.TestCaseTitle, et.ErrorMessage));
                }

                foreach (var tp in testRun.QueryResultsByOutcome(TestOutcome.Passed))
                {
                    lstTestRunDetails.Items.Add(string.Format("{0}: {1} ", tp.Outcome, tp.TestCaseTitle));
                }

                foreach (var tf in testRun.QueryResultsByOutcome(TestOutcome.Failed))
                {
                    lstTestRunDetails.Items.Add(string.Format("{0}: {1} - {2}", tf.Outcome, tf.TestCaseTitle, tf.ErrorMessage));
                }

                foreach (var tw in testRun.QueryResultsByOutcome(TestOutcome.Warning))
                {
                    lstTestRunDetails.Items.Add(string.Format("{0}: {1} - {2}", tw.Outcome, tw.TestCaseTitle, tw.ErrorMessage));
                }

                foreach (var ta in testRun.QueryResultsByOutcome(TestOutcome.Aborted))
                {
                    lstTestRunDetails.Items.Add(string.Format("{0}: {1} - {2}", ta.Outcome, ta.TestCaseTitle, ta.ErrorMessage));
                }

                foreach (var tb in testRun.QueryResultsByOutcome(TestOutcome.Blocked))
                {
                    lstTestRunDetails.Items.Add(string.Format("{0}: {1} - {2}", tb.Outcome, tb.TestCaseTitle, tb.ErrorMessage));
                }

                foreach (var ti in testRun.QueryResultsByOutcome(TestOutcome.Inconclusive))
                {
                    lstTestRunDetails.Items.Add(string.Format("{0}: {1} - {2}", ti.Outcome, ti.TestCaseTitle, ti.ErrorMessage));
                }

                foreach (var to in testRun.QueryResultsByOutcome(TestOutcome.Timeout))
                {
                    lstTestRunDetails.Items.Add(string.Format("{0}: {1} - {2}", to.Outcome, to.TestCaseTitle, to.ErrorMessage));
                }

                // Get the test results by user by passing in the Test Foundation Identity
                // testRun.QueryResultsByOwner(TeamFoundationIdentity);
            }

            if(testRuns.Count() == 0)
                lstTestRunDetails.Items.Add("No Test Results have been associated with the selected build");
        }
    }
}

 

6. And the Bonus Power tool…

Thank you for reading this far. If you haven’t already download the Community TFS Build Manager extension from the visual studio extension gallery do so now. The Community TFS Build Manager (TBM) is an open source build management solution developed by the ALM rangers, the build manager simplifies the management of builds in medium to large Team Foundation Server environments. Some common limitations you may run into while dealing with builds through the Visual Studio Build Explorer are not being able to perform bulk operations on builds, create a relationship diagram of the build controller/agents, managing build process templates, etc. The community TFS build manager address that and many other such gaps you may encounter while managing builds through the visual studio build explorer. You can grab the source and read more about the project on CodePlex.

Recently a new feature namely Build Notes has been added to the community TFS Build Manager that let’s you generate an ms word report of the build summary. A sample attached below… Look at the test result section, the trx file is parsed for you to get you a test result list filtered by test result outcome, where failed test also carries the error message. Watch this video or read this post here on what you can achieve with the build notes.

image

 

 image

 

 

Thank you for taking the time out and reading this blog post. If you enjoyed the post, remember to subscribe to http://feeds.feedburner.com/TarunArora.

Check out the other posts on cool tools using TFS API. In love

Posted On Wednesday, May 16, 2012 11:37 PM | Feedback (0) | Filed Under [ TFS API TFS SDK ]

Friday, April 27, 2012

Community TFS Build Manager – Build Notes Preview

 

The Community TFS Build Manager (TBM) is an open source build management solution developed by the ALM rangers, the build manager simplifies the management of builds in medium to large Team Foundation Server environments. Some common limitations you may run into while dealing with builds through the Visual Studio Build Explorer are not being able to perform bulk operations on builds, create a relationship diagram of the build controller/agents, managing build process templates, etc. The community TFS build manager address that and many other such gaps you may encounter while managing builds through the visual studio build explorer. Since TBM is really an extension of the build explorer solution in Visual Studio it is available for download from the Visual Studio Extension Gallery. You can grab the source and read more about the project on CodePlex.

07 May 2012 - [TA] – The Community TFS Build Manager extension with the build notes functionality – version 1.4.0.1 has been released to the Visual Studio Extension Gallery now. Please download and install the extension from here.

30th April 2012 – [TA] – The change set 75829 includes Build Notes, this feature has not yet been released to Visual Studio Extension gallery. You can try build notes out by downloading the executable from here and run TFSBuildManager.Application.exe. Please note, this is currently in Preview, if you run into any issues (which you most likely will :) please raise them here.

                                                                   
Build Notes - An Introduction
   

1. Feature Introduction - Build Notes

I have worked with several clients implementing Agile/Waterfall where release notes are created using the information available in builds (such as work items resolved, change sets included, etc) but this is done manually. This makes the process of creating release notes laborious and error prone. Lately I have been working on a feature for the TBM which will help you automate much of the release note creation process by allowing you to generate a summary document from the build summary.

Let me give you a very brief taste of the level of details included in the build notes,

                        image

 

But that’s not all, look at the deep dive for the entire template :-]

2. Deep Dive into Build Notes

When I started writing this feature I wanted to give the user the ability to easily include exclude sections from the build notes. I am sure that the DEV team will be more interested in the Build Configuration summary details section more than the QA team, by being able to easily exclude sections that the audience may not be interested in you can keep the information relevant to the audience.

                                                                          image

Most of our customers use MS Word to distribute release notes across teams, hence Ms Word became the obvious choice for build notes. An interesting fact that came forward while I was still researching the requirements for this feature was that not all companies have ms word installed as part of the standard build which means that the build notes generation logic should not depend on ms word being installed on the machine where the notes are being generated and this is where Open XML SDK comes to the rescue.

Now that I was sure that I was using MS Word and Open XML SDK I needed to template what I wanted to distribute as part of the build notes. By extracting the build information from TFS using the TFS API and feeding that information into the standard word template I could generate the Build Notes. 

                                                                                 image         

The Build Notes Template

image

 

1. Header – The header includes the Build Number for which the notes has been generated

2. Introduction section – Includes images for build state and build retention state. Along with information on User who triggered the build, the build definition triggered and how it was triggered. How Long the build ran for, duration it was completed before. You also get to know the build URI (I know, I am working to make this a link, but wait this is still in progress), the source get version for the build, the shelve set name, the label name, build quality, drop location and location of the log file.

3. Latest Activity – Includes the name of the individual who last modified the build, when it was last modified and how long ago.

 

4. Build Configuration Summary – Includes information of the build platform, build flavour, no of errors, warnings, details of the solution(s) compiled by the build along with the error count, warning count and log file path.

 

5. Change set Details – The change set id, comment, when it was changed in and by whom it was checked in along with details of all the files included in the change set.

 

 

image

 

6. Work Item Details – The Work Item Id, Title, Type of work item, current state of the work item and the iteration path the work item is assigned to.

 

 

7. Footer – The footer includes the details of by who & when the build notes were generated.

 

 

 

8. Test Results – This feature has been highly requested by many customers. The customer does not want to download the trx file to see the list of tests that failed. Build notes not only gives you the information about the test run such as Test Result Id, Status, total test run, completed and Pass % it also parses the trx file to gives you a separate list of test passed, failed and inconclusive.

 

 

 

 

 

 

 

 

What more, you are not restricted to generating build notes for just one build, you can include as many builds as you want in one build notes, the template section is repeated for each build you choose to be included in the build notes. I have so far tested this for 25 builds in one go and it works just fine. Exciting or What? :-]

3. Feature Walkthrough

Enough of talk, let’s see this in action…

1. Fire up the Community Build Manager and select the team project collection you would like to work with. I am demoing this against my TFS preview team project collection https://geeks.tfspreview.com which is also using cloud Build Services.

image

2. Choose Builds from the show drop down list

image

3. From the completed builds tab right click any of the builds you would like to generate the build notes for, from the context menu choose ‘Experimental: Build Notes’. You can select random builds by holding the ctrl key or use the shift key to select sequential builds.

image

4. Select the Options you would like to include in the build notes document. By un-checking any of the options you can eliminate that from being included in the build notes. Click Generate to continue generating the build notes.

image

5. If all goes right you should get a build notes document, similar to the one below,

image    image

image

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Build Summary VS Build Notes

On the left you can see the build summary in the visual studio build explorer and on the right you can see the build notes generated using the TFS Build Manager.

 image

 

4. FAQ

1. Where can I download the Community TFS Build Manager – Build Notes Preview from?

It is planned that this will be available for download from Visual Studio Gallery, but for now you can download it from here. Please refer to the update comments, the extension is available for download and can directly be installed from the visual studio extension gallery here.

2. Where can I download the source code for the Build Notes Preview?

Since this is part of the community build extension codeplex project, you can download the source code from here.

3. Where do I report bugs or request enhancements to the Build Notes Preview?

You can raise a bug or enhancement request here. Alternatively you can contact me directly.

4. Can I customize the build Notes template?

YES! Absolutely, the whole purpose of taking the template approach for build notes was giving the user the flexibility to easily modify the build notes template as per their needs. You can edit as much as you like, I’ll be discussing this in great detail in the next blog post.

5. Am I looking at the Latest Blog post on TBM - Build Notes?

You can follow all posts related to TBM – Build Notes from http://geekswithblogs.net/TarunArora/category/13622.aspx 

Hope you like the feature enhancement, next I’ll be discussing ‘how to customize the build notes preview template’. Thank you for taking the time out and reading this blog post. If you enjoyed the post, remember to subscribe to http://feeds.feedburner.com/TarunArora. Special thanks to Mike Fourie, Jakob Ehn, Tiago Pascol, Anuthara Bharadwaj, Nivedita Bawa, Brian Keller and Ed Blankship for their great feedback. While I’ll be busy fixing the defects you raise, in case you have any feedback please feel free to leave a comment.

Cheers ;)

Posted On Friday, April 27, 2012 6:38 PM | Feedback (0) |

Wednesday, April 11, 2012

TFS API The All New Team Project Picker – Beautiful!

 

The Team Project Picker in TFS 2011 looks gorgeous. I specially like the status bar on the working state, at least let’s you know that the project picker is still working on getting the details and of course the new icons for team project collection and team projects are stunning too.

clip_image001  clip_image002

 

How do I get the Team Project Picker using the TFS API?

That is fairly straight forward. Add a reference to the Microsoft.TeamFoundation.Client dll available in C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\ReferenceAssemblies\v2.0 and use the below code,

public void ConnectToTfs()
        {
            TeamProjectPicker tfsPP = new TeamProjectPicker(TeamProjectPickerMode.MultiProject, false, new UICredentialsProvider());
            tfsPP.ShowDialog();
        }

 

Download a sample application here

Why does my project picker look different?

You might run into an issue, where the project picker looks like the below,

clip_image001[1] clip_image002[1]

When the Team Project Picker is run from inside of VS the colour theme will be picked up from VS itself. When running outside of VS the windows theme colours are used, so there can be differences between the two. Currently there isn’t a way to change that since the dialog itself is not public (just the wrapper that launches the dialog). So don’t be surprised if the Team Project Picker looks different then expected :-]

Posted On Wednesday, April 11, 2012 11:49 PM | Feedback (0) |

Tuesday, April 10, 2012

Walkthrough: Scheduling jobs using Quartz.net – Part 1: What is Quartz.Net?

 

Quartz.NET is a full-featured, open source enterprise job scheduling system written in .NET platform that can be used from smallest apps to large scale enterprise systems.

What is the problem that we trying to address?

I want to schedule the execution of a task but only when something happens. Let’s call that something a trigger, so... if the trigger is met => execute the task. image Sounds simple, why not use windows task scheduler for this?

Well, windows task scheduler is great for tasks where the trigger can be easily defined. With windows task scheduler will you be able to schedule a task to run on every working day according to the UK calendar (exclude all weekends & bank holidays) without either writing the logic for day check in the task or a wrapper script calling into the task.

The task should just contain the execution logic and should not have anything to do with the schedule for execution; Quartz.net allows you to achieve this and lots more. A quartz.net trigger gives you the flexibility for task invocation based on the following triggers,

  • 1. at a certain time of day (to the millisecond)
  • 2. on certain days of the week
  • 3. on certain days of the month
  • 4. on certain days of the year
  • 5. not on certain days listed within a registered Calendar (such as business holidays)
  • 6. repeated a specific number of times
  • 7. repeated until a specific time/date
  • 8. repeated indefinitely
  • 9. repeated with a delay interval

Did 8 – repeat indefinitely just ring a bell? I’ll be covering that in the future post.

Using Quartz.net as a windows service

You can have Quartz.net run as a standalone instance within its own .NET virtual machine instance via .NET Remoting. Let’s take a look at typical application architecture. In the figure below, I have the application tier set up on Machine 1, database set up on Machine 2 and Quartz.net set up on Machine 3 which is normally the architecture for most (if not all) enterprise applications.

image

Figure 1 -  Typical Application architecture while using Quartz.net as a windows service

What other options do I have if I don’t want to use Quartz.net?

Quartz.net is just one of the many job scheduling services. Have a look at this comprehensive list of free and paid enterprise job scheduling software along with their feature comparison. http://en.wikipedia.org/wiki/List_of_job_scheduler_software

This was first in the series of posts on enterprise scheduling using Quartz.net, in the next post I’ll be covering how to Install Quartz.net as a windows service. Thank you for taking the time out and reading this blog post. If you enjoyed the post, remember to subscribe to http://feeds.feedburner.com/TarunArora. Stay tuned!

Posted On Tuesday, April 10, 2012 9:50 PM | Feedback (2) |

Sunday, April 01, 2012

ALMing in Hinglish 2–Windows 8-Manual Testing Metro Style Apps using MTM11

 

What is ALMing in Hinglish => Introduction

   

दूसरे वीडियो में शुभ्रा माजी, आदित्य अग्रवाल और सृष्टि श्रीधर से चर्चा करेंगे विंडोज 8 मेट्रो स्टाइल ऍप्लिकेशन्स की मैनुअल टैस्टिंग के बारे में. टीम हमें माइक्रोसॉफ्ट टेस्ट प्रबंधक 2011 के माध्यम से एक डेमो देंगी विंडोज 8 मेट्रो स्टाइल ऍप्लिकेशन्स की मैनुअल टैस्टिंग की.

ALMing in Hinglish–Windows 8 Metro Style App manual testing using MTM11

 

In this second in the series of videos I bring to you Shubhra Maji who is a Program Manager on the Visual Studio dev tools team in Hyderabad along with the very seasoned Aditya Agarwal & Srishti Sridhar who have been working in the Visual Studio team from past several releases. The team wonderfully walks us through manually testing Metro Style Apps in Windows 8 using Microsoft Test Manager 11.

A great thank you for watching, if you have any questions/feedback/suggestions please contact us.

Stay Tuned for more…

Namaste!

 

You might also like

- ALMing in Hinglish 1-Exploratory Testing in VS11 with Nivedita Bawa

Posted On Sunday, April 01, 2012 11:07 PM | Feedback (0) |

Monday, March 05, 2012

ALMing in Hinglish 1-Exploratory Testing in VS11 with Nivedita Bawa

 

What is ALMing in Hinglish => Introduction

पहली वीडियो में निवेदिता बावा से चर्चा करेंगे खोजपूर्ण टैसटि़ग के बारे में. निवेदिता हमें बताएंगी खोजपूर्ण टैसटि़ग क्या है और इसके लाभ, और खोजपूर्ण टैसटि़ग पर माइक्रोसॉफ्ट टेस्ट प्रबंधक 2011 के माध्यम से एक डेमो देंगी.

image

In this first in the series of videos I interview Nivedita Bawa who is a Program Manager on the Visual Studio team. Nivedita wonderfully explains what exploratory testing is, what are it’s advantages, why people refrain from using it and a walkthrough of some exploratory testing scenarios using Microsoft Test Manager 2011.  

 

ALMing in Hinglish–Exploratory Testing with Nivedita Bawa.

 

Feel free to contact me directly if you have any questions/feedback/suggestions…

Stay Tuned…

Namaste!

Posted On Monday, March 05, 2012 11:13 PM | Feedback (1) |

Introduction to ALMing in Hinglish

 

पिछले साल अक्तूबर में मैने विजुअल स्टूडियो 11 लैब्स का पूर्वावलोकन किया था जो 1000 से अधिक बार डाउनलोड किया गया है. यह एक महान प्रेरणा राही है इसी तरह की पहल की दिशा में काम करने के लिए. मैं शुक्रिया अदा करना चाहूँगा चार्ल्स स्टर्लिंग और उनकी टीम का ‘ALMing in Hinglish’ मे समर्थन के लिये.

imageHinglish (हिन्दी + अंग्रेजी) वीडियो की श्रृंखला में हम माइक्रोसॉफ्ट विजुअल स्टूडियो ए.एल.एम विशेषताऒ की खोज करेंगे उत्पाद टीम के सदस्य से बात करके.

किसी भी प्रश्न / प्रतिक्रिया / सुझाव के लिए मुझसे संपर्क करें ...

 

In October last year I translated the Visual Studio 11 Preview Hands on Labs to Hindi which has received over 1000 downloads to date. This overwhelming response has been a great motivation in finding more interactive ways to deliver Visual Studio ALM content in Hindi & other regional languages. I would like to thank Charles Sterling & team for their support towards the ‘ALMing in Hinglish’ initiative.

In the series of Hinglish (English + Hindi) videos we will explore the various ALM offerings of Visual Studio by talking to people in the Microsoft Visual Studio product teams.

Feel free to contact me directly if you have any questions/feedback/suggestions…

Stay Tuned…

Namaste!

Posted On Monday, March 05, 2012 10:49 PM | Feedback (0) |

Saturday, March 03, 2012

My Big Fat Indian Wedding!

 

I have been off the circuit for over a month now for guys wondering if I have fallen off the planet, I was getting married! Indian Weddings are grand and the festivities start months in advance while the hang over carries on for weeks after. The Weddings in India are about bringing together friends & family, fun times with a lot of dance & music, spicy curries & royal beverages, blending of rituals, and a lot of culture.

Annu Weds Tarun

Before the wedding… 8, 9, 10 Feb 2012

A lot covered in 3 days, felt like running a marathon with rituals of purification, Mehndi, Hawan, … , Cocktail and finally getting engaged on the 10th of Feb 2012.

                          * Rituals *                                                             * & more rituals *                                                 * 10th Feb 2012 *

IMG_6794  IMG_6824 _MG_9435 

The Big Day – 11th Feb 2012

                     *All Set*                                                         **The Horse Ride**                                                                             *** The Wedding Vows***

 DSC_0147   DSC_0215  DSC_1011

Honeymoon in Paradise – Maldives | Soneva Gili |14th-19th Feb 2012

No Shoes… No News => Soneva Gili By Six Senses

                 * Over Water Villas *                                                * No Shoes/ No News *                                                * While Snorkelling *

 IMG_8384 IMG_7938    IMG_8391

My elder brother Amit Arora who knows everything there is to know about hotels, destinations and travel surprised us by booking us the perfect vacation @ the paradise island. For our honeymoon we wanted to travel to a destination where we could relax, yet be thrilled and occasionally surprised, where we were at the heart of nature but not too far from the lap of luxury! Soneva Gili proved to be just that “perfect” destination where our expectations were exceeded in all six senses.

             * The Wine Cellar *                                                 * Exploring the Island *                                            * The Palm Island *

IMG_7277 IMG_8277 IMG_8483

In our 6 day stay in the sumptuous over-water villa on the island we were pampered and looked after faultlessly. Though every experience & activity offered at Soneva Gili was unique our personal favourite were the so very romantic sun set sail in the traditional dhoni and the romantic theme dinner on the palm island.

                          * Dhoni *                                                            * Nature a real Mix! *                                               * Baby Shark *

IMG_7479 IMG_8538 IMG_8550

Our Mr Friday Ahmed made anything & everything possible, even on the day when the dolphins weren’t ready to show up he managed to get some dancing dolphins to pop out of the Indian ocean during the dolphin cruise. Hari our chef spoiled us for choice personalising every course, every meal, every day. Firdhaus in charge of room service provided in-despicable service. Iain (General Manager) & Alex (Resort Manager) managed everything to perfection. Just like any one else we were looking for the perfect holiday and the least I can say is we have been delighted in every possible way. I would highly recommend Soneva Gili to anyone looking for a memorable vacation. More Details, reviews, photos, … 

                    * Great Hosts - Alex & Ian *                                  * Fun In The Sand! *                                             * Beautiful Sun Set *

IMG_8490 IMG_8552 IMG_8622

 

I must have time travelled, it is still cold and wet here in London! Unfortunately all good things come to an end. Vacation is finally over and trust me it still feels awkward wearing shoes. But as they say C’est La Vie!

Namaste!

Posted On Saturday, March 03, 2012 3:36 PM | Feedback (2) |

Wednesday, January 18, 2012

Microsoft IE6 Migration

 

With support for Windows XP coming to an end on the 8th April 2014 and IE6 standing in so many people’s way of migration, what better time to start taking the leap to a more modern browser?

Microsoft have teamed up with Camwood, Citrix Systems and Quest Software, all application compatibility experts, to help jump-start your move. Join the road shows being organized around the UK between Feb and April to learn more about the technical challenges faced by departments and how you can get around it.

clip_image001

Join us at a date below for a packed agenda discussing the technical challenges faced by IT departments when migrating their users off of IE6. We will establish:

· Why you should go through the trouble of migrating;

· How you go about identifying those problem applications;

· What you can do about them.

There are a range of dates to choose from, each offering a slightly different spin and all promising to be thoroughly informative! Take your pick and use the links below to register with our partners.

Who, Where & When?
Tues 21st February

Microsoft & Quest Software
Manchester United Football Ground (Old Trafford)
09:30 – 14:00 (+Stadium Tour!)
More Information & Registration
Thurs 22nd March
Microsoft & Citrix Systems (Including newly acquired AppDNA)
Chalfont St. Peter (Easy access via the M40 & M25 as well as rail)
09:00 – 16:00
More Information & Registration
Tues 3rd April
Microsoft & Camwood
London, Cardinal Place
More Information & Registration TBC
Thurs 19th April
Microsoft & Quest Software
Reading Football Ground (Madejski Stadium)
09:30 – 14:00 (+Stadium Tour!)
More Information & Registration

On behalf of all the team at Microsoft, we hope to see you there!

clip_image002 clip_image003 clip_image004 clip_image006

 

Please share the word, after all, 2014 isn’t too far away now In love

Posted On Wednesday, January 18, 2012 7:07 PM | Feedback (0) |

Powered by: