Skip to content

Commit 47a37fe

Browse files
authored
Update Measure-WorkItemTypesInIteration.ps1
Add example + formatting
1 parent 734e2d9 commit 47a37fe

File tree

1 file changed

+106
-92
lines changed

1 file changed

+106
-92
lines changed

scripts/Measure-WorkItemTypesInIteration.ps1

Lines changed: 106 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,117 +1,131 @@
11
<#
22
.SYNOPSIS
3-
Measures the percentage of work item types and the bug to rest of types ratio within an iteration
3+
Measures the percentage of work item types and the bug to rest of types ratio within an iteration
4+
45
.DESCRIPTION
5-
A PowerShell script that utilizes the Azure DevOps Services REST API to fetch work items within a specified iteration and calculates the percentage of each work item type and the ratio of bugs to the rest of the work item types
6+
A PowerShell script that utilizes the Azure DevOps Services REST API to fetch work items within a specified iteration and calculates the percentage of each work item type and the ratio of bugs to the rest of the work item types
7+
68
.PARAMETER PersonalAccessToken
7-
Azure DevOps personal access token (PAT) with the following scopes: Work Items (Read)
9+
Azure DevOps personal access token (PAT) with the following scopes: Work Items (Read)
10+
811
.PARAMETER OrganizationName
9-
Name of the Azure DevOps organization
12+
Name of the Azure DevOps organization
13+
1014
.PARAMETER ProjectName
11-
Name of the Azure DevOps project
15+
Name of the Azure DevOps project
16+
1217
.PARAMETER TeamName
13-
Name of the Azure DevOps team
18+
Name of the Azure DevOps team
19+
1420
.PARAMETER IterationPath
15-
The iteration path to measure work item types in
21+
The iteration path to measure work item types in
22+
1623
.PARAMETER WorkItemTypes
17-
The work item types to be considered
24+
The work item types to be considered
25+
1826
.INPUTS
19-
None
27+
None
28+
2029
.OUTPUTS
21-
The calculated percentages and ratios - printed to the console
30+
The calculated percentages and ratios - printed to the console
31+
2232
.NOTES
23-
Version: 1.0
24-
Author: Marc Rufer & GitHub Copilot Workspace
25-
Creation Date: 14.05.2024
26-
Purpose/Change: Initial script development
33+
Version: 1.0
34+
Author: Marc Rufer & GitHub Copilot Workspace
35+
Creation Date: 14.05.2024
36+
Purpose/Change: Initial script development
37+
38+
.EXAMPLE
39+
PS> .\Measure-WorkItemTypesInIteration.ps1 -PersonalAccessToken "PAT_HERE" -OrganizationName "ORG_NAME_HERE" -ProjectName "PROJECT_NAME_HERE" -TeamName "TEAM_NAME_HERE" -IterationPath "ITERATION_PATH_HERE"
40+
2741
.EXAMPLE
28-
.\Measure-WorkItemTypesInIteration.ps1 -PersonalAccessToken "PAT_HERE" -OrganizationName "ORG_NAME_HERE" -ProjectName "PROJECT_NAME_HERE" -TeamName "TEAM_NAME_HERE" -IterationPath "ITERATION_PATH_HERE"
42+
PS> .\Measure-WorkItemTypesInIteration.ps1 -PersonalAccessToken "PAT_HERE" -OrganizationName "ORG_NAME_HERE" -ProjectName "PROJECT_NAME_HERE" -TeamName "TEAM_NAME_HERE" -IterationPath "ITERATION_PATH_HERE" -WorkItemTypes "User Story" "Epic" "Bug"
2943
#>
3044
PARAM
3145
(
32-
[Parameter(Mandatory = $true, Position = 0, HelpMessage="Azure DevOps personal access token (PAT) with scopes: Work Items (Read).")]
33-
[string] $PersonalAccessToken
34-
,
35-
[Parameter(Mandatory = $true, Position = 1)]
36-
[string] $OrganizationName
37-
,
38-
[Parameter(Mandatory = $true, Position = 2)]
39-
[string] $ProjectName
40-
,
41-
[Parameter(Mandatory = $true, Position = 3)]
42-
[string] $TeamName
43-
,
44-
[Parameter(Mandatory = $true, Position = 4)]
45-
[string] $IterationPath
46-
,
47-
[Parameter(Mandatory = $false)]
48-
[string[]] $WorkItemTypes = "Bug", "User Story"
46+
[Parameter(Mandatory = $true, Position = 0, HelpMessage="Azure DevOps personal access token (PAT) with scopes: Work Items (Read).")]
47+
[string] $PersonalAccessToken
48+
,
49+
[Parameter(Mandatory = $true, Position = 1)]
50+
[string] $OrganizationName
51+
,
52+
[Parameter(Mandatory = $true, Position = 2)]
53+
[string] $ProjectName
54+
,
55+
[Parameter(Mandatory = $true, Position = 3)]
56+
[string] $TeamName
57+
,
58+
[Parameter(Mandatory = $true, Position = 4)]
59+
[string] $IterationPath
60+
,
61+
[Parameter(Mandatory = $false)]
62+
[string[]] $WorkItemTypes = "Bug", "User Story"
4963
)
5064

5165
function Get-WorkItemsInIteration {
52-
param (
53-
[string] $personalAccessToken,
54-
[string] $organizationName,
55-
[string] $projectName,
56-
[string] $teamName,
57-
[string] $iterationPath,
58-
[string[]] $workItemTypes
59-
)
60-
61-
$base64AuthInfo = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("`:$personalAccessToken"))
62-
$workItemsUri = "https://dev.azure.com/$organizationName/$projectName/$teamName/_apis/wit/wiql?api-version=6.0"
63-
$body = @{
64-
query = "SELECT [System.Id] FROM WorkItems WHERE [System.IterationPath] = '$iterationPath' AND [System.WorkItemType] IN ('$($workItemTypes -join "','")')"
65-
} | ConvertTo-Json
66-
67-
try {
68-
$response = Invoke-RestMethod -Uri $workItemsUri -Method Post -Body $body -ContentType "application/json" -Headers @{Authorization=("Basic $base64AuthInfo")}
69-
return $response.workItems.id
70-
}
71-
catch {
72-
Write-Error "Failed to fetch work items: $_"
73-
exit 1
74-
}
66+
param (
67+
[string] $personalAccessToken,
68+
[string] $organizationName,
69+
[string] $projectName,
70+
[string] $teamName,
71+
[string] $iterationPath,
72+
[string[]] $workItemTypes
73+
)
74+
75+
$base64AuthInfo = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("`:$personalAccessToken"))
76+
$workItemsUri = "https://dev.azure.com/$organizationName/$projectName/$teamName/_apis/wit/wiql?api-version=6.0"
77+
$body = @{
78+
query = "SELECT [System.Id] FROM WorkItems WHERE [System.IterationPath] = '$iterationPath' AND [System.WorkItemType] IN ('$($workItemTypes -join "','")')"
79+
} | ConvertTo-Json
80+
81+
try {
82+
$response = Invoke-RestMethod -Uri $workItemsUri -Method Post -Body $body -ContentType "application/json" -Headers @{Authorization=("Basic $base64AuthInfo")}
83+
return $response.workItems.id
84+
}
85+
catch {
86+
Write-Error "Failed to fetch work items: $_"
87+
exit 1
88+
}
7589
}
7690

7791
function Calculate-WorkItemTypesPercentage {
78-
param (
79-
[string] $personalAccessToken,
80-
[string] $organizationName,
81-
[string[]] $workItemIds
82-
)
83-
84-
$base64AuthInfo = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("`:$personalAccessToken"))
85-
$workItemTypes = @{}
86-
$totalWorkItems = $workItemIds.Count
87-
88-
$workItemsCountPerType = @{}
89-
90-
foreach ($id in $workItemIds) {
91-
$workItemUri = "https://dev.azure.com/$organizationName/_apis/wit/workitems/$($id)?api-version=6.0"
92-
try {
93-
$workItem = Invoke-RestMethod -Uri $workItemUri -Method Get -Headers @{Authorization=("Basic $base64AuthInfo")}
94-
$type = $workItem.fields.'System.WorkItemType'
95-
$workItemsCountPerType[$type] = $workItemsCountPerType[$type] + 1
96-
}
97-
catch {
98-
Write-Error "Failed to fetch work item details: $_"
99-
continue
100-
}
101-
}
102-
103-
foreach ($type in $workItemsCountPerType.Keys) {
104-
$percentage = ($workItemsCountPerType[$type] / $totalWorkItems) * 100
105-
Write-Host "$($type): $($percentage)%"
106-
}
107-
108-
if ($workItemsCountPerType['Bug']) {
109-
$bugRatio = ($workItemsCountPerType['Bug'] / ($totalWorkItems - $workItemsCountPerType['Bug'])) * 100
110-
Write-Host "Bug to rest of types ratio: $($bugRatio)%"
111-
}
112-
else {
113-
Write-Host "No bugs found in the iteration."
114-
}
92+
param (
93+
[string] $personalAccessToken,
94+
[string] $organizationName,
95+
[string[]] $workItemIds
96+
)
97+
98+
$base64AuthInfo = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("`:$personalAccessToken"))
99+
$workItemTypes = @{}
100+
$totalWorkItems = $workItemIds.Count
101+
102+
$workItemsCountPerType = @{}
103+
104+
foreach ($id in $workItemIds) {
105+
$workItemUri = "https://dev.azure.com/$organizationName/_apis/wit/workitems/$($id)?api-version=6.0"
106+
try {
107+
$workItem = Invoke-RestMethod -Uri $workItemUri -Method Get -Headers @{Authorization=("Basic $base64AuthInfo")}
108+
$type = $workItem.fields.'System.WorkItemType'
109+
$workItemsCountPerType[$type] = $workItemsCountPerType[$type] + 1
110+
}
111+
catch {
112+
Write-Error "Failed to fetch work item details: $_"
113+
continue
114+
}
115+
}
116+
117+
foreach ($type in $workItemsCountPerType.Keys) {
118+
$percentage = ($workItemsCountPerType[$type] / $totalWorkItems) * 100
119+
Write-Host "$($type): $($percentage)%"
120+
}
121+
122+
if ($workItemsCountPerType['Bug']) {
123+
$bugRatio = ($workItemsCountPerType['Bug'] / ($totalWorkItems - $workItemsCountPerType['Bug'])) * 100
124+
Write-Host "Bug to rest of types ratio: $($bugRatio)%"
125+
}
126+
else {
127+
Write-Host "No bugs found in the iteration."
128+
}
115129
}
116130

117131
Write-Host "Azure DevOps organization: $OrganizationName" -ForegroundColor Green

0 commit comments

Comments
 (0)