Search This Blog

Showing posts with label teamfoundationserver. Show all posts
Showing posts with label teamfoundationserver. Show all posts

Sunday, December 06, 2009

Deleting work item in TFS 2010

After the release of TFS 2010 power tools I have noticed that the command destroywi that is used for deleting work items was removed. Searching the Visual Studio installation directory I found a new command line utility called witadmin.exe. This new tool hosts all the known work item management commands like import, export... To delete work items you use the same command as in the power tools with the work items id as a parameter:
Example: witadmin destroywi 10

Wednesday, July 02, 2008

Shelveset as a Backup

Long time since I posted. Been busy (implementing TFS), long vacation and a new work place.
In the last implementation I did I have noticed that in some cases users work in a network drive that is always backed up by IT. This is a good solution for backing up your workspace without checking in your pending changes (like we used to do when we worked with SourceSafe...) or performing a shelve for backup purpose. I thought it would be nice to share the idea of automatic backup shelves with those of you that work locally without any automatic backup. When you shelve your pending changes the shelve is saved in PendingChange table. The pending changes will be removed from the table when you delete or replace the shelveset. So to perform an automatic backup of your workspace that does not overload your TFS database you can add a schedule task that will run the following command:
tf shelve {workspace name} /replace /noprompt
Remeber to set the current folder to the workspace local path before executing the command.
Enjoy.

Thursday, December 27, 2007

VersionControlPath - Class to Manipulate Version Control Items Path

I was navigating through TFS assemblies and I found out a static class that I wasn't aware of: Microsoft.TeamFoundation.VersionControl.Common.VersionControlPath. This class contains functions that help manipulating version control items path. It is like the System.IO.Path class. Here are some of the methods in the class:
  • GetFileName
  • GetExtension
  • GetFolderDepth
  • Combine
  • GetFolderName
  • ValidatePath

Very useful.

Thursday, December 06, 2007

TF20015: The field 'xxx' contains a value that is not in the list of supported values.

While trying to save a work item in TFS you might be facing a problem doing it when the error TF20015 is raised. This error is raised when you are trying to enter values that are not part of the allowed values of the field. The strange thing is that it can happen although the value was already saved before to the work item and the field is disabled. As a result you cannot change the value and therefor cannot save the work item. So why does it happen? I faced this problem in two cases:


  1. The user in one of the fields (which is implementing the valid user value list as the allowed values for the field) was renamed or deleted.

  2. The work item schema was changed in a way that made some of the existing work items have illegal values. For example, if you made one of the fields mandatory trough all of the work flow and you have some work items with a null value in the field.

So, how can you fix it?


There are 2 ways to do it:



  1. Changing the work item schema temporarily so the field won't be disabled and then you can change the value.

  2. Write some code the change the field value:

Here's a code sample on how to update work item field values:


public void UpdateWorkItem(string serverUri, int id, string fieldName, string fieldValue)
{
TeamFoundationServer tfs = new TeamFoundationServer(serverUri);
tfs.EnsureAuthenticated();
WorkItemStore wis = tfs.GetService(typeof(WorkItemStore)) as WorkItemStore;
WorkItem workItem = wis.GetWorkItem(id);
workItem.Open();
workItem.Fields[fieldName].Value = fieldValue;
workItem.Save();
}


Thursday, September 06, 2007

Filename Collision - Another item with the same name exists on the server.

At one of our merges we encountered an error saying that there is a file collision and we could not complete the process. The error is raised when you are performing the check in after the merge. The merge itself passes with no error. It seem that it happens when 2 files/folders with the same name and location are added to both branches. While performing the merge the source branch treats the new item as a branch action to the destination branch which results in adding the file in the check in process. The merge process does not check if the file already exists and when you perform the check in you get the error and the only option to resolve it is to delete the local file (the file from the merge action). The problem is that we wanted the file from the merge source branch. To fix this we needed to delete the file in the destination branch (after performing undo pending changes for the merge) and than perform the merge again.

Tuesday, August 28, 2007

Moving Team Foundation Server from a single-server deployment to a dual-server deployment

It's been a while since I've posted something. Shame on me!

The last weeked was dedicated to moving our Team Foundation Server from a single server deployment to a dual server deployment. I have already gone throught the process of moving a server from one hardware configuration to another so I was quite sure that this would work.

Our previous configuration was a virtual server on an IBM blade with 2GB memory serving about 50 users. We have decided to split the deployment and add a database server which is the number one consumer of resources.

I've started the process around 21:00 and finished at 02:30. The most problematic part was that for some reason I could not uninstall SQL Server and Visual Studio from the application sevrer (the new deployment requieres uninstall of current Team Foundation Server installation and installing as an application server). I had to use the windwos installer cleanup utility to remove them from windows installer database and then I reinstalled them to their previous state. After that again unistall and installing the Team Foundation Server application tier. You can imagine it took me sometime...

Some remarks regarding the document (How to: Move from a Single-Server to a Dual-Server Deployment):

  • In the section named To modify the Web.Config file to reflect the original Team Foundation data-tier server name: In 1.a there is a mistake when refering to the new data-tier server when locating the web.config file of the services. It should be the application-tier server.

  • In the section named To restore and verify Report Server on the new Team Foundation Server: In 17 you are suppose to execute SetupWarehouse.exe but it won't happen since the TFSAppPull is still down. SetupWarehouse.exe uses the web service to initilize the process of rebuilding the Team System OLAP cube. You need to execute it after you are restarting the services in the section named To restart services and verify operation.

Another problem I encountered was related to the databases restore. I must say that it was my mistake since I did not follow the process and restored the databases by detaching the new ones and attaching the old ones. The issue was that the 2 databases using full text search catalog (TfsWorkItemTracking and STS_Content_TFS) were attached with the wrong reference to the full text catalog. As a result the catalog could not be rebuilt and backups failed. In addition while searching work items using the Steps to Reproduce field (which is indexed in the catalog) an error raised specifing the query failed and there is a problem on the server.

I did some search using the errors I saw in the event viewer and in database logs and understood that the catalog needs to be rebuilt. When executing the rebuild using the management studio I got no error but the process ran for about 24 hours. I'm not a DBA but this seemed strange so I stopped it and continue searching using this keywords: "Full-Text Search is not enabled for the current database", "Property FullTextIndexSize is not available for FullTextCatalog" and with the names of the catalogs: ix_STS_Content_TFS and TeamFoundationServer10FullTextCatalog. I did not find much (except for this incomplete posts). Anyway, I understood that I have to drop and recreate the catalogs. After doing this the catalogs were rebuild and everything worked.

Here are the steps I took to recreate the catalogs.

Please notice that this part is done by the Team Foundation Server installation and I did this only because the catalogs were corrupted. If you are not familiar with this stuff I suggest you consult with a Team System advisor or try to reinstall the server. Any way don't forget to backup the database. Since in this case you have problem doing it because the corrupted catalogs disturb the backup I suggest you copy the data files (mdf and logs) to another location (after you stop the system...) or find a way to disable backing up the catalogs (I read about it some where).

Open Microsoft SQL Server Management Studio and connect to the Team Foundation Server database.

For recreating the ix_STS_Content_TFS catalog do the following:

  • In the object explorer expand: Databases --> STS_Content_TFS --> Storage and right click the ix_STS_Content_TFS catalog. Select Delete from the menu and press OK button in the Delete Object window. This will drop the corrupted catalog (if your catalog is corrupted you will see error when trying to open it's properties window).

Right click the Full Text Catalogs item and select New Full-Text Catalog... from the menu. In the New Full-Text Catalog - STS_Content_TFS enter the name of the catalog: ix_STS_Catalog_TFS, select a location for the files, select Primary in the Filegroup combo box and in the Owner text box select dbo. Press the OK button.
  • Double click the newly created catalog in the Object Explorer tree. In the Full-Text Catalog Properties - ix_STS_Content_TFS select the Tables/Views from the left list view. Add the tables: dbo.Docs, dbo.Lists, dbo.UserData and dbo.UserInfo to the Table/View objects assigned to the catalog and start setting the Eligible colums for the tables.
  • For dbo.Docs select the Content and LeafName. For both of them select the language English in the Language for Word Breaker setting column. For Content select Extension in the Data Type Column.
  • For the dbo.Lists table select the tp_Description and tp_Title columns. For both of them select the language English in the Language for Word Breaker setting column.
    • For the dbo.UserData table select all the columns except for tp_Ordering.

    • For the dbo.UserInfo table select the tp_Email, tp_Login and tp_Title columns. For all of them select English in the Language for Word Breaker setting column.
    • Press the OK button. The catalog should be processed for some time.

    For recreating the TeamFoundationServer10FullTextCatalog catalog do the following:

    • In the object explorer expand: Databases --> TfsWorkItemTracking --> Storage and right click the TeamFoundationServer10FullTextCatalog catalog. Select Delete from the menu and press OK button in the Delete Object window. This will drop the corrupted catalog.

    • Right click the Full Text Catalogs item and select New Full-Text Catalog... from the menu. In the New Full-Text Catalog - TfsWorkItemTracking enter the name of the catalog: TeamFoundationServer10FullTextCatalog, select a location for the files, select Primary in the Filegroup combo box and in the Owner text box select dbo. Check the Set as default catalog check box. Press the OK button.
    • Double click the newly created catalog in the Object Explorer tree. In the Full-Text Catalog Properties - TeamFoundationServer10FullTextCatalog select the Tables/Views from the left list view. Add the tables: dbo.WorkItemLongTexts to the Table/View objects assigned to the catalog. In the Eligible columns select the Words column and press the OK button. The catalog should be processed for some time and the window will be closed.

    That's it. The catalogs were created and you should be able to process them.

    Tuesday, July 17, 2007

    How to Expose the Work Item Editor Control

    I've used this while writing the Cropper TFS Work Item plugin. I needed a way to edit or create a new work item. The WorkItemFormControl located under the Microsoft.TeamFoundation.WorkItemTracking.Controls namespace is the same control used by Visual Studio work item plugin and also by the process template editor (which was the way I found how to use it).

    Here's an example for creating a new work item with the control.

    First we need to connect to a Team Foundation Server and obtain the WorkItemStore service:

    TeamFoundationServer tfs = new TeamFoundationServer(serverName);
    tfs.EnsureAuthenticated();
    WorkItemStore wis = tfs.GetService(typeof(WorkItemStore)) as WorkItemStore;

    After doing so we can now create the WorkItemFormControl:

    WorkItemFormControl wifc = new WorkItemFormControl();

    The WorkItemFormControl has a string property named FormDefinition. We need to set this property with an XML defining the work item type that we want to use. To do so we use the WorkItemStore service:

    WorkItemType wit = wis.Projects[teamProjectName].WorkItemTypes["Bug"];

    This will return the the Bug work item type.

    After doing so we can use the WorkItemType to set the FormDefinition property:

    XmlDocument xmlDocument = wit.Export(false);
    wifc.FormDefinition = xmlDocument.InnerXml;

    Now we can use the WorkItemFormControl with a newly created work item or an existing one:

    WorkItem wi = new WorkItem("Bug"); or WorkItem wi = wis.GetWorkItem(bugId);
    wifc.Item = wi;

    To show the control embed it to a form or a panel on a form.

    Wednesday, June 06, 2007

    Wednesday, May 30, 2007

    Cropper TFS Work Item Plugin

    It's been a while since I wrote here. Anyway, I hope this post will compensate for it. I read this week a post about SnagIt! integration with TFS. Since I use Cropper I've decided to write a plugin for TFS.
    The plugin enables you to capture images directly to a new TFS work item attachments field. You can also add an attachment to an existing work item. You can download it from here. Read the read me file for installation guide and how to use it.
    The plugin uses the WorkItemFormControl to edit the work item. I will explain in future posts on how to use it.
    I'm planning to add the sources to Cropper Plugins project in CodePlex.
    The plugin is in it's early stages. I would be happy to hear your comments.

    Tuesday, April 17, 2007

    How to Get Build Result Details using TFS API - Part 3

    The previous post in this series was about the build steps section of the build report. In this post we will see how to retrieve the associated changesets section details.

    Using the BuildStore object we have created in this post we can get a list of ChangeSetData objects that contain the needed information (an example on how to get the buildUri parameter value available in this post also):

    ChangeSetData[] changesets = buildStore.GetChangeSetsForBuild(buildUri);


    foreach (ChangeSetData changeset in buildReport.Changesets)

    {

    MessageBox.Show(changeset.ChangeSetId.ToString());

    MessageBox.Show(changeset.ChangeSetUri);

    MessageBox.Show(changeset.CheckedInBy);

    MessageBox.Show(changeset.Comment);

    }


    Thursday, April 12, 2007

    Extracting Images from Work Items Attachments

    In this example I will show how to use the WorkItemStore interface. This example will execute a stored query on the work items database and will extract the attachments from the work items returned from the query. This is a good training for working with the WorkItemStore interface.

    private void ExtractWorkItemsAttachments(string teamFoundationServer, string teamProject, string storedQuery,

    string saveTo)

    {
    //Logon to the server and create the needed objects
    TeamFoundationServer tfs = TeamFoundationServerFactory.GetServer(teamFoundationServer);
    tfs.EnsureAuthenticated();
    WorkItemStore store = (WorkItemStore)tfs.GetService(typeof(WorkItemStore));
    Project tfsProject = store.Projects[teamProject];
    StoredQueryCollection sqc = tfsProject.StoredQueries;
    string querystring;
    //Search for the query
    foreach (StoredQuery query in sqc)
    {
    if (query.Name == storedQuery)
    {
    //Execute the query
    querystring = query.QueryText;
    querystring = querystring.Replace("@project", "'" + tfsProject.Name + "'");
    WorkItemCollection workItems = store.Query(querystring);
    //Extract the attachments
    foreach (WorkItem workItem in workItems)
    {
    if (workItem.Attachments.Count > 0)
    {
    foreach (Attachment attachment in workItem.Attachments)
    {
    //Using WebClient to download the attachment
    WebClient webClient = new WebClient();
    webClient.Credentials = CredentialCache.DefaultCredentials;
    string fileName = Path.Combine(saveTo, attachment.Name);
    webClient.DownloadFile(attachment.Uri.AbsoluteUri, fileName);
    }
    }
    }
    }
    }
    }

    Tuesday, April 10, 2007

    How to Get Build Result Details using TFS API - Part 2

    The previous post in this series was about the summary section of the build report. In this post we will see how to retrieve the build steps section details.
    Using the BuildStore object we have created in the previous post we can get a list of BuildStepData objects that contain the needed information (an example on how to get the buildUri parameter value available in the previous post also):

    BuildStepData[] buildSteps = buildStore.GetBuildSteps(buildUri);

    Now we can go through all the objects in the collection and retrieve details for each one of them.

    foreach (BuildStepData in buildSteps)
    {
    MessageBox.Show(buildStep.BuildStepMessage);
    MessageBox.Show(buildStep.BuildStepName);
    MessageBox.Show(buildStep.FinishTime.ToString());
    MessageBox.Show(buildStep.Status.ToString());
    }

    Wednesday, March 14, 2007

    How to Get Build Result Details using TFS API - Part 1

    In this series of posts I would explain how to use TFS API in order to retrieve build result details as they appear in the build report.


    In order to retrieve result details for a build we need to create a BuildStore object. There is an example on how to create a BuildStore object on a previous post: Get Build Changes. The example take into consideration that you have already created the BuildStore object and it is named buildStore.

    In this post we will see how to retrive the details under the summary section of the build report. First, we need to get the BuildData object for the build. Here's how to get the BuildData object:

    BuildData buildData = buildStore.GetBuildDetails(buildStore.GetBuildUri(teamProject, buildNumber));

    Now that we've got the BuildData object we can retrieve the build details that appear in the summary section of the report:

    buildData.BuildNumber
    buildData.RequestedBy
    buildData.TeamProject
    buildData.BuildType
    buildData.BuildMachine
    buildData.StartTime
    buildData.FinishTime
    buildData.LastChangedBy
    buildData.LastChangedOn
    buildData.BuildQuality
    buildData.LogLocation

    On the next post for this series I will explain how to retrieve the details for the "Build Steps" section of the report.

    Sunday, February 25, 2007

    Start a Team Build Using BuildProgressForm

    I found out another way for starting a build using the BuildProgressForm. The BuildProgressForm is the same one used by Visual Studio Team Build intergration for starting a build.




    This method is very useful for my tool TFSBuildManger.
    Here's an example of how to do so:

    BuildParameters buildParameters = new BuildParameters();
    buildParameters.TeamFoundationServer = teamFoundationServer; buildParameters.TeamProject = teamProject;
    buildParameters.BuildType = buildType;
    buildParameters.BuildMachine = buildmachine;
    buildParameters.BuildDirectory = buildDirectory;
    BuildProgressForm frmBuildProgress = new BuildProgressForm(buildParameters, teamFoundationServer);
    frmBuildProgress.ShowDialog();

    Wednesday, February 21, 2007

    TFSBuildManager UI Change (Tabbed View)

    It been a while since my last post. Anyway, I have published a new release of TFSBuildManager under CodePlex. The main and only change for this release is that the UI now supports control of multiple build types simultaneously by using tabs. Hope you would like this change. You can download the new version here. I would appreciate your comments on this change and about the application.

    Wednesday, January 31, 2007

    TFSBuildManager New Version

    I have released a new version of TFSBuildManager. You can download it here. I made some changes to the edit build type form and added some advanced properties that are inherited from the imported Microsoft.TeamFoundation.Build.targets file. There are some other cool features like "Execute Without Get" which actually resumes a build from the compilation point disabling the process of creating a workspace. This feature is very handy when you setup a new build machine and the build fails because of errors regarding the machine configuration and not because of source files. For the full feature list see the release change log.
    Enjoy.

    Wednesday, January 10, 2007

    TFSBuildManager

    I wrote a utility to manage build types called TFSBuildManager. You can download it's first release here. It is hosted under CodePlex.
    Main features of this utility are:
    • Start, stop a build
    • Change build/s quality
    • Delete, backup build/s
    • Edit build type

    I wrote it because I needed the ability to manage build types outside Visual Studio environment. Also, I needed some features that are not available through Visual Studio IDE.

    I'm planning to add:

    • Advanced build log
    • Add new Build Type
    • Build list filtering
    • Edit advanced Build Type properties

    Enjoy.

    Monday, January 08, 2007

    Export Excel Chart To Image

    I'm working on a dashboard that will display TFS reports. I thought using "SQL Server Business Intelligence Development Studio" for creating reports but found it not so stable. Anyway, I think that using TFS Excel integration for creating reports is the best way (I will write about how to do it in a future post). Now I have some excel reports but I want them to be displayed in our dashboard automatically (soon will be displayed on a 42'' LCD...). The solution for this was to export the excel chart from the report to an image that will be displayed in the dashboard site.
    Here's the code to export the image:


    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Configuration;
    using Excel = Microsoft.Office.Interop.Excel;
    using System.Globalization;
    using System.Threading;
    using System.IO;

    private static void ExportExcelChartToImage(string excelFile, string outputFile)
    {

    //Object to send in com methods instead of null
    object missing = System.Reflection.Missing.Value;
    //Create a new excel application
    Excel.Application excelApplication = new Excel.ApplicationClass();
    //Saving the old culture info
    CultureInfo oldCultureInfo = Thread.CurrentThread.CurrentCulture;
    try
    {
    //Setting new culture info is en-us is not default (Disable exception)
    Thread.CurrentThread.CurrentCulture = new CultureInfo("en-us");
    //Open the excel document
    Excel.Workbook excelWorkbook = excelApplication.Workbooks.Open(excelFile,
    missing, missing, missing, missing, missing, missing, missing, missing,
    missing, missing, missing, missing, missing, missing);
    //Refresh the data from TFS
    excelWorkbook.RefreshAll();
    //Taking into consideration that there's only one sheet
    Excel.Worksheet activeSheet = (Excel.Worksheet)excelWorkbook.ActiveSheet;
    //Again, there's only one chart on the sheet
    Excel.ChartObjects chartObjects = (Excel.ChartObjects)activeSheet.ChartObjects(missing);
    Excel.ChartObject chartObject = (Excel.ChartObject)chartObjects.Item(1);
    Excel.Chart chart = chartObject.Chart;
    //Set the filter (bmp, jpg...)
    string extension = Path.GetExtension(outputFile).Replace(".", "");
    //Export the image
    chart.Export(outputFile, extension, missing);
    //Save and close the workbook
    excelWorkbook.Save();
    excelWorkbook.Close(false, excelFile, missing);
    }
    finally
    {
    //Set the old culture info
    Thread.CurrentThread.CurrentCulture = oldCultureInfo;
    //Close and free the excel application
    excelApplication.Quit();
    excelApplication = null;
    }
    }

    Tuesday, January 02, 2007

    Get List of Builds for Deleted Build Types

    To get a list of builds you can use:

    BuildData[] GetListOfBuilds(string teamProject, string buildType)

    How to get build types list I have mentions in: How to Get Build Types List.
    If you deleted a build type and you want to get list of builds from this type then you need to call GetListOfBuilds with String.Empty as the buildType parameter. This will return a full list of builds for the teamProject.

    public BuildData[] GetAllBuilds(string server, string project)
    {
    TeamFoundationServer tfs = new TeamFoundationServer(server, CredentialCache.DefaultCredentials);
    tfs.EnsureAuthenticated();
    BuildStore bs = (BuildStore)tfs.GetService(typeof(BuildStore));
    return bs.GetListOfBuilds(project, String.Empty);
    }

    Thursday, December 28, 2006

    Get Build Changes (ChangeSetData, Changeset, Change)

    To improve our custom build report that I have talked about before (Custom Build Logger) I wanted to add information regarding the users that are involved in this build and the changes that they made to source control.
    Here's an example how to go over build changes:


    using Microsoft.TeamFoundation.Client;
    using Microsoft.TeamFoundation.VersionControl.Client;
    using Microsoft.TeamFoundation.Build.Proxy;

    TeamFoundationServer tfs = new TeamFoundationServer(server);
    VersionControlServer vcs = (VersionControlServer)tfs.GetService(typeof(VersionControlServer));
    BuildStore bs = (BuildStore)tfs.GetService(typeof(BuildStore));
    ChangeSetData[] changeSetsData = bs.GetChangeSetsForBuild(bs.GetBuildUri(project, buildNumber));
    foreach (ChangeSetData changeSetData in changeSetsData)
    {
    //Here you can do something with the ChangeSetData properties
    //changeSetData.CheckedInBy...
    //Get the ChangeSetData Changeset
    Changeset changeSet = vcs.GetChangeset(changeSetData.ChangeSetId);
    //Go over the Changeset changes
    foreach (Change change in changeSet.Changes)
    {
    //Here you can do something with the Change
    //change.Item.ServerItem...
    }
    }