none
Como extrair do TFS uma alteração que houve em um workitem RRS feed

  • Pergunta

  • Objetivo: Saber quando iniciada uma tarefa e quando foi finalizada (para calcular quanto tempo levou cada tarefa)

    Com a classe WorkItem {Microsoft.TeamFoundation.WorkItemTracking.Client} eu tenho a propriedade Revisions {Microsoft.TeamFoundation.WorkItemTracking.Client.RevisionCollection} correto, mas como vou retirar (programaticamente) dessa propriedade o dia que foi alterado o campo State de "To Do" para "In progress" e quando foi alterado de "In progress" para "Done".

    Essa informação é exibida no workitem do TFS, mas eu precisava buscar programaticamente para preencher uma classe.

    Por exemplo na imagem abaixo:

     

    Alguem pode me ajudar?


    Test Analyst in Mobile Vision Paulo Tiago C. Mariano
    terça-feira, 13 de setembro de 2011 17:33

Respostas

  • Thiago,

    Eu passei por uma situação semelhante, mas acabou que depois o pessoal do cliente desistiu da idéia porque virão que não entregaria valor, já que nem sempre o desenvolvedor fecharia a tarefa no mesmo dia.

    Passei pelo mesmo problema de performance quando fiz a "primeira" versão, mas diretamente pela API não tem jeito, você é obrigado a percorrer o history inteiro para saber o momento.

    ´Comecei a procurar algumas outras possibilidades, não cheguei a implementar, mas achei esse post aqui que fala do modelo de revisão e onde acessar na base Wharehouse... http://blogs.msdn.com/b/teams_wit_tools/archive/2009/04/29/previous-state-and-state-change-count.aspx

    Acho que pode ser um caminho. A informação de quando saiu de um e foi para o outro tem lá como descrito no post, então acredito que provavelmente tenha a informação de datas tb, mas sinceramente não cheguei a terminar de olhar o modelo.

    Se resolver ou melhorar dá uma avisada e qualquer duvida, se puder ajudar é só falar.

    Abs


    Claudio Leite Visual Studio ALM Ranger | PSD Trainner by Scrum.org Twitter: @claudiobernardo Blog: http://www.claudioleite.com
    • Editado Claudio Leite quarta-feira, 14 de setembro de 2011 20:35
    • Marcado como Resposta ptcmariano sexta-feira, 23 de setembro de 2011 11:27
    quarta-feira, 14 de setembro de 2011 20:35

Todas as Respostas

  • Consegui de uma maneira que não ficou boa....

    Para cada revisão da tarefa:

    Quando o State é "In progress" e o estado anterior é "To do" nessa data foi iniciada a trabalhar com a tarefa.

    Quando o State é "Done" essa data de modificação foi quando a tarefa foi terminada a programação.

     

    O código pode ser representado dessa maneira:

    private TeamProjectPicker pick;
    private TfsTeamProjectCollection teamProjectCollection;
    
    
    public ManageTFS() 
    {
    pick = new TeamProjectPicker(TeamProjectPickerMode.SingleProject, false);
    pick.ShowDialog();
    teamProjectCollection = pick.SelectedTeamProjectCollection;
    }
    
    public List<TaskInfoModel> listaDurationTaskByInteration(string interationPath)
            {
                WorkItemStore workItemStore = (WorkItemStore)teamProjectCollection.GetService(typeof(WorkItemStore));
    
                WorkItemCollection wicollection = 
                    workItemStore.Query
                    ("select [ID],[State] from Workitems where [Iteration Path] Under '"
                    +interationPath+"' AND [Work Item Type] = 'Task'");
    
                List<TaskInfoModel> lista = new List<TaskInfoModel>();
    
                foreach (WorkItem wi in wicollection)
                {
                    TaskInfoModel bo = new TaskInfoModel();
    
                    atribuiBOInfo(workItemStore, wi, bo);
    
                    lista.Add(bo);
                }
                return lista;
    
    }
    
    private TaskInfoModel atribuiBOInfo(WorkItemStore wis, WorkItem wi, TaskInfoModel bo)
    {
                bo.Title = wi.Title;
                bo.DataCriacao = wi.CreatedDate;
    
                string statePreview = "To Do";
                
                for (int c = 1; c <= wi.Rev; c++)
                {
                    WorkItem task = wis.GetWorkItem(wi.Id, c);
                    if (task.Fields["Remaining Work"].Value != null)
                    { bo.RemainingWork = task.Fields["Remaining Work"].Value.ToString(); }
    
                    if (task.State.Equals("In Progress") //se o estado for igual a in progress 
                        && !task.State.Equals(statePreview))//e o estado anterior não for igual ao atual
                    {
                        bo.DataInicio = task.ChangedDate;//entao iniciou na data
                        statePreview = task.State;
                    }
    
                    if (task.State.Equals("Done")) //se o estado for igual a done a data é quando finalizou
                    {
                        bo.DataFim = task.ChangedDate;
                        TimeSpan diferenca = bo.DataFim.Subtract(bo.DataInicio);
                        bo.Diferenca = diferenca.Days + " Dias, " + diferenca.Hours + " Horas, " + diferenca.Minutes + " Minutos";
                        return bo;
                    }
    
                }
                return bo;
    }
    
    public class TaskInfoModel
        {
            public string Title { get; set; }
            public DateTime DataCriacao { get; set; }
            public string RemainingWork { get; set; }
            public DateTime DataInicio { get; set; }
            public DateTime DataFim { get; set; }
            public string Diferenca { get; set; }
        }
    


    Porém como tem um for dentro de um foreach está demorando muito tempo pois em um sprint temos +60 tasks.

     

    Alguem conhece uma forma de buscar diretamente a revisão que foi alterado To Do para In Progress?


    Test Analyst in Mobile Vision Paulo Tiago C. Mariano
    quarta-feira, 14 de setembro de 2011 11:27
  • Thiago,

    Eu passei por uma situação semelhante, mas acabou que depois o pessoal do cliente desistiu da idéia porque virão que não entregaria valor, já que nem sempre o desenvolvedor fecharia a tarefa no mesmo dia.

    Passei pelo mesmo problema de performance quando fiz a "primeira" versão, mas diretamente pela API não tem jeito, você é obrigado a percorrer o history inteiro para saber o momento.

    ´Comecei a procurar algumas outras possibilidades, não cheguei a implementar, mas achei esse post aqui que fala do modelo de revisão e onde acessar na base Wharehouse... http://blogs.msdn.com/b/teams_wit_tools/archive/2009/04/29/previous-state-and-state-change-count.aspx

    Acho que pode ser um caminho. A informação de quando saiu de um e foi para o outro tem lá como descrito no post, então acredito que provavelmente tenha a informação de datas tb, mas sinceramente não cheguei a terminar de olhar o modelo.

    Se resolver ou melhorar dá uma avisada e qualquer duvida, se puder ajudar é só falar.

    Abs


    Claudio Leite Visual Studio ALM Ranger | PSD Trainner by Scrum.org Twitter: @claudiobernardo Blog: http://www.claudioleite.com
    • Editado Claudio Leite quarta-feira, 14 de setembro de 2011 20:35
    • Marcado como Resposta ptcmariano sexta-feira, 23 de setembro de 2011 11:27
    quarta-feira, 14 de setembro de 2011 20:35
  • Olá Claudio,

     

    Entendi que para acessar diretamente é necessário utilizar a base Warehouse. Já tinha uma idéia que as informações específicas seria minerada de outra base.

     

    Mas surgiu uma dúvida (trivial até certo ponto) como acessar o cubo [Work Item] e a tabela [Work Item History].

     

    Com "work item query language" não consegui, qual seria outra forma de extrair os dados pela API?


    Paulo T. C. Mariano
    sexta-feira, 16 de setembro de 2011 14:00
  • Após alguma pesquisa descobri como acessar o cubo.

     

    Até onde sei, é com relatórios de BI do Excel e Report Builder.

     

    Não vai ter como vou ter que trabalhar com estes.


    Paulo T. C. Mariano
    sexta-feira, 23 de setembro de 2011 11:26
  • Paulo,

     

    Desculpa a demora na resposta, mas acabou que o alerta aqui ficou perdido na minha caixa e só vi hoje olhando os posts. Espero que ainda de tempo.

    Mas seguinte, você não precisa acessar o cubo através de queries MDX diretamente. Para jogar as informações para o cubo, existe um banco relacional que é criado e ele que é a origem dos dados para montar o cubo do tfs.

    Da uma olhada no seu servidor, e veja se não tem uma base de dados com o nome parecido com: Tfs_Wharehouse (isso varia com o nome que você deu).

    É nessa tabela que vc tem que fazer a query. Você tem que olhar nessa tabela aí.

     

    select * from DimWorkItem
    

     

    Algumas dicas para a sua consulta:

    WorkItemBK - é uma combinação de informações ela é montada da seguinte forma (id_do_workitem)|(revisao)|(id_interno) ex: 1|2|0dbefd88-ef2d-4fc6-8c29-0af11d913572 - primeiro workitem - na segunda revisão - do id interno xxx

    System_state = o estado que estava o workitem naquela alteração.

    PreviousState = esse é um campo que vc pode usar para controlar as mudanças de estado

    System_id = o id do workitem (vai facilitar sua pesquisa por esse campo ou vc pode tentar agrupar por esse campo)

     

    Depois vc pode fazer um inner join com select * from FactWorkItemHistory para essa tabela, siga a lógica que tá naquele link que passei anteriormente.

     

    Com isso você consegue montar seu relatorio fácil.

     

    Abs


    Claudio Leite Visual Studio ALM Ranger | PSD Trainner by Scrum.org Twitter: @claudiobernardo Blog: http://www.claudioleite.com
    quinta-feira, 6 de outubro de 2011 03:22
  • Excelente colocação, vou tentar essas consultas.

     

    Muito obrigado Cláudio.

     

    Abs.


    Paulo T. C. Mariano
    quinta-feira, 6 de outubro de 2011 12:54