13/04/2017 | Autor: Igor Abade V. Leite | Categoria: Técnico | Comentários

Como obter a iteração atual de vários times

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:

1
2
3
4
5
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:

1
PS C:\Users\igor.abade> $teams = Get-TfsTeamProject | Get-TfsTeam | Select Name, @{L='Id'; E={$_.Identity.TeamFoundationId}}
1
PS C:\Users\igor.abade> $teams
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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:

1
2
3
4
5
6
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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:

1
2
$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 ?

1
Get-TfsWorkItem -Query $wiql 

E voilà!

1
PS C:\Users\igor.abade> Get-TfsWorkItem -Query $wiql 
1
2
3
4
5
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