How can I keep track of who entered a comment in a TFS work item

When working with a problem in other error tracking systems, there are ways to add notes to elements that are clearly indicated by the username and date entered by the authors. I am looking for a similar function in TFS work items. Is there such a function?

We are currently using a system that allows us to press a hot key to insert the current time and username into multi-line text fields. All users know how to insert this information above what they are typing. Although this manual is acceptable and easy. For example:

5/1/2009 1:20:00 am - AManagr-
Defered to next version, and here why ...

4/24/2009 1:20:00 am - ADev - 
QA machine had out of date XYZ gizmo component. Here the convoluted way this can happen ... blah blah ... This is difficult to fix.

4/22/2009 1:20:00 am - QAGuy - 
I can't save reports to PDF files.

Other tools that I used (Mantis, maybe?) Had the Notes function, which baked. Therefore, I could not forget to put my name in the comments or find out if new notes fall in the upper or lower part of the field, etc.

Manually entering a name and date / time is not a (good) option. But, by clicking on one key or button on the toolbar, everything will be fine.

"", , . , , . , , .

, . , . , ?

. , .

"" , .

, Stackoverflow .

+3
2

, . TFS . , , , .

. Notes Notes Notes " " . Notes - HTML, , . TFS Process Editor.

 <FIELD reportable="dimension" type="DateTime" name="Notes Date" refname="System.VSTS.Notes.Date">
    <DEFAULT from="clock" />
    <READONLY not="[Global]\Team Foundation Administrators" />
  </FIELD>
  <FIELD reportable="dimension" type="String" name="Notes Author" refname="System.VSTS.Notes.Author">
    <DEFAULT from="currentuser" />
    <READONLY not="[Global]\Team Foundation Administrators" />
  </FIELD>
  <FIELD type="HTML" name="Notes" refname="System.VSTS.Notes" />
</FIELDS>

, .

, , - Notes WorkItemChanged - . "" " " . , . - Team Foundation System <

[WebService(Namespace = "http://mynamespace.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class UpdateWorkItem : System.Web.Services.WebService
{
    private static TeamFoundationServer _Tfs;
    private static WorkItemStore _WorkItemStore;

    private static List<WorkItem> _ChangedWorkItems = new List<WorkItem>();

    [SoapDocumentMethod(Action = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03/Notify", RequestNamespace = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03")]
    [WebMethod]
    public void Notify(string eventXml, string tfsIdentityXml)
    {

        EventLog.WriteEntry("TFS Services", "Log Started: Notify Webmethod");


        // Load the recieved XML into a XMLDocument
        XmlDocument eventXmlDoc = new XmlDocument();
        eventXmlDoc.LoadXml(eventXml);
        XmlElement eventData = eventXmlDoc.DocumentElement;

        // Validate event data
        if (eventData != null)
        {
            // Get Work Item id from event data
            int id = GetWorkItemId(eventData);

            //EventLog.WriteEntry("TFS Services", String.Format("eventXmlDoc {0}", eventXmlDoc.InnerXml));
            EventLog.WriteEntry("TFS Services", String.Format("Got Id {0}", id));
            string changedby = GetWorkItemChangedBy(eventData);
            EventLog.WriteEntry("TFS Services", String.Format("Got changedby {0}", changedby));
            if (changedby != "TFSSERVICE")
            {
                //Add a 15 second delay in order to make sure all workitems are saved first before starting to update them
                Thread.Sleep(15000);
                EventLog.WriteEntry("TFS Services", "Calling UpdateWorkItemInternal");
                UpdateWorkItemInternal(id);
            }
        }
    }

    private int GetWorkItemId(XmlElement eventData)
    {
        return Convert.ToInt32(eventData.SelectSingleNode("CoreFields/IntegerFields/Field[ReferenceName='System.Id']/NewValue").InnerText);
    }

    private string GetWorkItemChangedBy(XmlElement eventData)
    {
        return Convert.ToString(eventData.SelectSingleNode("CoreFields/StringFields/Field[ReferenceName='System.ChangedBy']/NewValue").InnerText);
    }

    private static void UpdateWorkItemInternal(int id)
    {
        //Connect To TFS Server 
        EventLog.WriteEntry("TFS Services", string.Format("Updating Work Item {0}", id));
        _Tfs = TeamFoundationServerFactory.GetServer("TeamServer");

        _WorkItemStore = (WorkItemStore)_Tfs.GetService(typeof(WorkItemStore));
        WorkItem workItem = _WorkItemStore.GetWorkItem(id);

        switch ((string)workItem.Fields["System.WorkItemType"].Value)
        {
            case "Bug":
                UpdateNotes(workItem);
                break;
            default:
                break;
        }

        foreach (WorkItem item in _ChangedWorkItems)
        {
            if (item.IsDirty)
            {
                foreach (Field field in item.Fields)
                {
                    if (!field.IsValid)
                    {
                        Console.Write("Not valid");
                    }
                }
                EventLog.WriteEntry("TFS Services", string.Format("Saving WorkItem: {0}", item.Id));
                try
                {
                    item.Save();
                }
                catch (Exception ex)
                {
                }
            }
        }

        _ChangedWorkItems.Clear();
    }

    private static void UpdateNotes(WorkItem workItem)
    {
       Field notes = workitem.Fields["System.VSTS.Notes"];
       if (notes != null)
       {
         notes = string.Format("{0} - {1}", workItem.ChangedDate, workItem.ChangedBy);
       } 

       if (workItem.IsDirty)
       {
           if (!_ChangedWorkItems.Contains(workItem))
           {
               _ChangedWorkItems.Add(workItem);
           }
       }
    }
 }

, , , .

+3

Source: https://habr.com/ru/post/1708290/


All Articles