Last active
January 13, 2023 10:42
-
-
Save akuryan/f1218dda7e4741c4acfe1a740a3c79c2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################### | |
<# | |
.SYNOPSIS | |
GetTicketsInBuld | |
.DESCRIPTION | |
GetTicketsInBuld collects Jira tickets in build, basing on last successful build in target environment | |
.PARAMETER authHeaderValue | |
Added for OutputDebugDetails purpose to allow one to specify Basic auth by passing string like "Basic ..." | |
For running in Azure DevOps - leave blank | |
Do not forget to allow your project build services to access environments, at least as Reader (go to Pipeline -> Environments -> Security (on top left) and add ther Project Collection Build Service (your-collection-name) as Reader) | |
.PARAMETER baseDoApiUri | |
Base URL for reaching API in Azure DO. When executing in scope of build - set to $env:SYSTEM_TEAMFOUNDATIONSERVERURI$env:SYSTEM_TEAMPROJECT | |
Locally: https://dev.azure.com/$(AzureDoProject)/$(AzureDoTeam) | |
.PARAMETER envNamePrefix | |
Azure DevOps environment name prefix to filter out only required project environments. Also I am using it to have short hand of my environment, like team-cms-env to store only env name in output variable for tickets | |
.PARAMETER OutputOutputDebugDetailsDetails | |
In Azure DO - pass the value of system.debug: -OutputDebugDetails $(system.debug) | |
.NOTES | |
.EXAMPLE | |
#> | |
# ' char inc as Notepad++ language recognition does not like get-help contents | |
############################################################################## | |
[CmdletBinding()] | |
param ( | |
[string] $authHeaderValue, | |
[string] $baseDoApiUri, | |
[string] $envNamePrefix = "team-cms-", | |
[bool] $OutputDebugDetails = $false | |
) | |
if ([string]::IsNullOrWhiteSpace($env:SYSTEM_ACCESSTOKEN)) { | |
$headers = @{ Authorization = "Basic $authHeaderValue" }; | |
} | |
else { | |
$headers = @{ Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN" }; | |
} | |
$allEnvironmentsUri = "$baseDoApiUri/_apis/distributedtask/environments"; | |
$allEnvsJson = Invoke-RestMethod -Method Get -Headers $headers -Uri $allEnvironmentsUri -Verbose:$OutputDebugDetails; | |
$ids = @(); | |
$allEnvsJson.value | ForEach-Object { if ($_.name -like "$envNamePrefix*") { $ids += "$($_.id)|$($_.name)"; } }; | |
if ($OutputDebugDetails) { | |
Write-Host "Auth header: $($headers.Authorization)"; | |
Write-Host "All environments URI: $allEnvironmentsUri"; | |
Write-Host "allEnvsJson: $allEnvsJson"; | |
Write-Host "Env's ID's: $ids"; | |
} | |
foreach ($envInfoRecord in $ids) { | |
$envId = $envInfoRecord.Split('|')[0]; | |
$envName = $envInfoRecord.Split('|')[1] -replace $envNamePrefix, ''; | |
$deploymentRecordsUri = "$baseDoApiUri/_apis/distributedtask/environments/$envId/environmentdeploymentrecords"; | |
$envDeploymentRecord = Invoke-RestMethod -Method Get -Headers $headers -Uri $deploymentRecordsUri -Verbose:$OutputDebugDetails; | |
if ($OutputDebugDetails) { | |
Write-Host "envId = $envId; envName = $envName; deploymentRecordsUri = $deploymentRecordsUri"; | |
Write-Host $envDeploymentRecord; | |
} | |
$jobNameToFilter = "some-job-name"; | |
# deployment at each environment consists of several stages - so, I wish to get successful stage, which is last in pipeline, to be sure that I am collecting correct commits | |
$build = $envDeploymentRecord.value | Where-Object { $_.jobName -eq $jobNameToFilter -and $_.result -eq "succeeded" } | Select-Object -First 1; | |
$changesInBetween = @(); | |
$result = @(); | |
if ($null -ne $build) { | |
# set the build from which we are grabbing our changes | |
$targetBuildId = $build.owner.id; | |
$uri = "$baseDoApiUri/_apis/build/builds/$targetBuildId/?api-version=7.0"; | |
$json = Invoke-RestMethod -Method Get -Headers $headers -Uri $uri -Verbose:$OutputDebugDetails; | |
if ($json.count -gt 0) { | |
$commit_id_after = $json.sourceVersion; | |
$changesInBetween = git log HEAD...$commit_id_after --no-merges --pretty='format:%s'; | |
if ($OutputDebugDetails) { | |
Write-Host "Changes commit id: $commit_id_after"; | |
} | |
} | |
else { | |
Write-Warning "No commits found in related build $targetBuildId" | |
} | |
} | |
# now to check, if $changesInBetween in between have something inside | |
if ($changesInBetween.Count -eq 0) { | |
# we was not able to grab last successful build from environment - so, we will use current build changes as source of changes | |
Write-Host "No successful builds have been found for environment $envName identified by id $envId, so we will grab changes for current build"; | |
$uri = "$baseDoApiUri/_apis/build/builds/$($env:BUILD_BUILDID)/changes?api-version=7.0" + '&$top=10000'; | |
$json = Invoke-RestMethod -Method Get -Headers $headers -Uri $uri -Verbose:$OutputDebugDetails; | |
if ($json.count -gt 0) { | |
$changesInBetween = $json.value | Select-Object -ExpandProperty message; | |
} | |
else { | |
Write-Warning "No commits found in current build $buildId" | |
} | |
} | |
else { | |
} | |
# we have strict rule, which requires each developer to mention ticket number prefixed by US or BUG in commit, so I could grab ticket numbers for JIRA from those commit messages | |
$numbers = $changesInBetween | Select-String -Pattern 'US\d+|BUG\d+' | |
# here I want to be sure that I have only unique tickets in report | |
$result = $numbers.Matches | Select-Object -ExpandProperty Value | ForEach-Object { [int]($_ -replace "US|BUG", "") } | Select-Object -Unique | Sort-Object | |
$tickets = "NO" | |
if ($result.Count -gt 0) { | |
$result = $result | ForEach-Object { "$jiraShortProjectName-" + $_ }; | |
$tickets = $result -join ","; | |
} | |
if ($OutputDebugDetails) { | |
Write-Host "changesInBetween: "; | |
$changesInBetween | ForEach-Object { Write-Host $_ }; | |
Write-Host "Result: "; | |
$result | ForEach-Object { Write-Host $_ }; | |
Write-Host "Current build uri: $uri"; | |
Write-Host "Build uri JSON: $json"; | |
} | |
# finally, I am writing to output variable postfixed with _environmentName to be able to consume this data later | |
Write-Host "##vso[task.setvariable variable=TICKETS_$envName;isOutput=true]$tickets" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment