Search code examples
c#tfstfs-sdk

How to change workflow state of the newly created TFS work item through API?


I'm creating a work item migration application from "something" to TFS 2013, and I want to have the TFS work items to be in corresponding workflow states as in source system. For instance, if the source work item is in "Closed" state, I want it to be in "Done" state in TFS.

I have followed advises in this article, which suggests to set BypassRules property of the WorkItemStore object to true in order to be able to set CreatedDate field. I suppose, the same applies to changing the workflow state, as it also requires bypassing rules.

So, I tried the following:

// obtain collection and authenticate towards it
var collection = new TfsTeamProjectCollection(new Uri(_tfsUrl), cred);
collection.Authenticate();

// get the work item store object
var store = new WorkItemStore(collection, WorkItemStoreFlags.BypassRules);

// creating the work item
var workItem = new WorkItem(store.Projects[_tfsProjectName].WorkItemTypes["Product Backlog Item"]);

// setting some standard fields
workItem.Title = "some name";
workItem.Description = "some description";

// validating the work item
if (workItem.Validate().Count > 0)
{
   // throw validation rules violated
}

// saving the work item
workItem.Save();    

As you can see, this sample doesn't violate any validation rules, and workItem.Validate().Count returns 0. But the call to workItem.Save() throws the following exception:

Additional information: TF26212: Team Foundation Server could not save your changes. There may be problems with the work item type definition. Try again or contact your Team Foundation Server administrator.

I double checked that BypassRules is set to true right before the call to Save() method. Besides, the workItem.IsValid is also true.

The interesting fact is that if I change the way I obtain the WorkItemStore object, from

var store = new WorkItemStore(collection, WorkItemStoreFlags.BypassRules);

to

var store = collection.GetService<WorkItemStore>();

it can save without any problem! But in this case I don't know how to set BypassRules to true. This property is read-only when the WorkItemStore object is created, and I get validation errors if I try to set workflow step to something other than "New".

So, my basic question is: how to create work items in TFS through API and be able to change State field in this newly created item?


Solution

  • Ok, folks, as it often happens, the answer is in manual. Let me explain.

    The article I referenced in my question clearly states:

    You need to be a member of the Project Collection Service Accounts

    But it doesn't mention that you can't easily add the user or group to Project Collection Service Accounts. If you try to do this via web access, you'll fail - the Add button is simply disabled. Besides, the screen shot is misleading, showing an account as a member of Project Collection Administrators group.

    By default, the Project Collection Service Accounts group contains a single group called Team Foundation Service Accounts. And this is the group you should add the account to. This can be done with the help of console application called TFSSecurity.exe:

    TFSSecurity.exe /g+ "Team Foundation Service Accounts" "Domain\my-service-account" /server:http://mytfsserver:8080/tfs
    

    This is explained in detail in this article, which describes exactly my case with the correct resolution. The TFSSecurity.exe can be found at the following location: %ProgramFiles(x86)%\Microsoft Visual Studio \Common7\IDE (e.g C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE)