Recentemente surgiu a seguinte pergunta no canal de ALM do Slack da Brasil.NET:

amigos
é possível no VSTS realizar queries cross projects utilizando a variável @CurrentIteration, pra trazer a sprint atual de vários projetos no filtro?
tentei de algumas maneiras aqui e não rolou

Minha resposta foi:

Não vai rolar. O problema é que a macro @CurrentIteration depende do contexto do time atual. Por isso, não dá para fazer cross-project.
Uma alternativa seria, via script, obter a iteração padrão de cada time e concatenar numa única query WIQL com OR.

E este post é exatamente sobre como criar o script que faz isso.

TfsCmdlets to the rescue!

Claro que o script vai ser em PowerShell. E como estamos falando de TFS, o TfsCmdlets pode ajudar muito aqui.

Depois de instala-lo (Install-Module TfsCmdlets), a primeira providência é obter uma lista de times e seus GUIDs:

Connect-TfsTeamProjectCollection -Collection http://<url-do-meu-tfs> -Interactive

$teams = Get-TfsTeamProject | Get-TfsTeam | Select Name, @{L='Id'; E={$_.Identity.TeamFoundationId}}

$teams

O resultado vai ser algo parecido com isto aqui:

PS C:\Users\igor.abade> $teams = Get-TfsTeamProject | Get-TfsTeam | Select Name, @{L='Id'; E={$_.Identity.TeamFoundationId}}
PS C:\Users\igor.abade> $teams

Name                  Id
----                  --
NorthwindTraders Team c8c4ec89-b014-4cea-972b-1d80d08d3e8f
TfsSearch Team        6715a4db-66a3-4d23-960f-80fa6b975d83
Database Team         78cde248-c29a-4a1a-88a9-7ac064669c9a
Web Team              0ef068be-c17a-4a95-b2bc-ac77ee81be12
FabrikamFiber Mast... e78f7de9-bfeb-4a49-afd5-af1c120ec3a4
PartsUnlimited Team   b80b113e-aa73-4c35-8bfb-5f7f559e9930
Archive Team          b49ec8aa-3393-44d6-aa79-f881da720fa3
Personal Team         f64cc2e8-2d16-4d55-996e-206534513418
SAC Team              444e07b2-2643-498d-b380-2e823be2a4a3
Tfs Team              7e1ccc5b-b96c-4f22-a351-dc35ee4b257d
TfsRegedit Team       67458414-2a6b-415f-93ed-8df10999437b
OpenSource Team       4cde10ce-fd29-4f70-855b-e495f6a03c97
New team              149edcf0-d6a1-4b7c-a9e5-323127f34faa
NewProject Team       ee0925d1-95ed-472e-a2ba-b56650ec6929
Another team          7a4a27ae-fb08-410b-9847-b5748d0102e5

Agora, para obter a iteração atual, vc precisa da classe TeamSettingsConfigurationService. Por, por padrão, o assembly que contém essa classe não está carregado na memória, precisamos usar primeiro Add-Type e, só então, chamar o método GetTeamConfigurations:

Add-Type -AssemblyName Microsoft.TeamFoundation.ProjectManagement

$guids = [guid[]] ($teams | Select -ExpandProperty Id)

$configSvc = (Get-TfsTeamProjectCollection -Current).GetService([type]'Microsoft.TeamFoundation.ProcessConfiguration.Client.TeamSettingsConfigurationService')

$configs = $configSvc.GetTeamConfigurations($guids)

$teamDefaultIterations = $configs | Select TeamName, @{L='Iteration'; E={$_.TeamSettings.CurrentIterationPath}}

Quase lá. Agora temos os nomes dos times e suas respectivas iterações atuais:

PS C:\Users\igor.abade> $teamDefaultIterations

TeamName                  Iteration
--------                  ---------
NorthwindTraders Team     NorthwindTraders\Release 1\Sprint 1
TfsSearch Team            TfsSearch\Release 1\Sprint 1
Database Team
Web Team
FabrikamFiber Master Team FabrikamFiber\Release 1\Sprint 1
PartsUnlimited Team       PartsUnlimited\Iteration 1
Archive Team              Archive\Release 1\Sprint 1
Personal Team             Personal\Release 1\Sprint 1
SAC Team                  SAC\Release 1\Sprint 1
Tfs Team                  Tfs\Release 1\Sprint 1
TfsRegedit Team
OpenSource Team           OpenSource\Release 1\Sprint 1
New team
NewProject Team           NewProject\Sprint 2
Another team

Neste ponto, você já está com as informações necessárias para montar sua query WIQL.

Vamos supor que você queira pesquisar todas as tasks que estejam “in progress” em todos os times de todos os projetos. Sua query seria montada assim:

$iterations = ([string[]]($teamDefaultIterations | Where Iteration  | % {"[System.IterationPath] = '$($_.Iteration)'"}) -join ' OR ')

$wiql = "SELECT [System.Id], [System.Title], [System.State], [System.AreaPath], [System.IterationPath], [System.AssignedTo] FROM WorkItems Where [System.WorkItemType] = 'Task' AND [System.State] = 'In progress' AND ($iterations)"

Ufa! Agora é só rodar a query 😃

Get-TfsWorkItem -Query $wiql

E voilà!

PS C:\Users\igor.abade> Get-TfsWorkItem -Query $wiql

Id       Rev  Type                 State           Changed              Assigned To               Title
--       ---  ----                 -----           -------              -----------               -----
214      4    Task                 In Progress     22/07/2016 10:38:33  Igor Abade (MSA)          Criar os ícones
215      3    Task                 In Progress     22/07/2016 10:41:14                            Implantar os ícones
284      2    Task                 In Progress     23/03/2017 14:48:36                            Criar tela de cadastro

Conclusão

O PowerShell, em combinação com o TfsCmdlets, permite fazer coisas muito legais ao interagir com o TFS/VSTS. Neste caso em específico, nosso código ficou razoavelmente comprido porque precisamos usar a API do TFS diretamente para obter informações sobre os times que, neste momento, não são expostas pelo TfsCmdlets.

Entretanto, na próxima release, teremos dois cmdlets novos (Get-TfsTeamIteration e Set-TfsTeamIteration) que retornam a informação desejada e eliminariam a necessidade de, neste caso, usar a API do TFS diretamente.

E aí, já usou o TfsCmdlets para resolver algum problema na sua empresa? Compartilhe aqui nos comentários a sua experiência!

Um abraço,
Igor

(Cross-post de http://www.tshooter.com.br/2017/04/13/como-obter-iteracao-atual-de-varios-times/)

Igor Abade

Igor Abade V. Leite ([email protected]) é Microsoft MVP (Most Valuable Professional) de Visual Studio ALM desde 2006. Palestrante em diversos eventos da comunidade de desenvolvimento de software (TechEd Brasil, The Developers’ Conference, DevOps Summit Brasil, Agile Brazil, Visual Studio Summit, QCON e outros), é também autor de artigos em revistas e sites como o MSDN Brasil. Desde março de 2011 é um dos sócios da Lambda3, uma consultoria especializada em ALM, desenvolvimento de software e treinamentos. Siga-o no Twitter @igorabade.