Instantly share code, notes, and snippets.

Embed
What would you like to do?
Create a markdown file with badges from all Azure DevOps build and release definitions.
<#
.SYNOPSIS
Create a markdown file with badges from all Azure DevOps build and release definitions.
.PARAMETER Token
A PAT for Azure DevOps with at read (and write) rights for: Agent Pools, Build and Release. See next parameter why write/manage rights make sense as well.
.PARAMETER CanUpdate
Defaults to true. The script assumes that the PAT has write/manage access and uses it to enable badges on any build/release where they are not yet enabled automatically. The output will then contain all build/releases.
If false, only badges from build/releases where someone has manually enabled the badge are included in the output. (New release definitions have the badge disabled by default).
.PARAMETER AccountName
Name of your DevOps account (dev.azure.com/your-name-is-here).
.PARAMETER ExcludeProjectNameFilter
Optional. If set projects matching the names in the (string) array will be excluded.
.PARAMETER ExcludeBuildNameFilter
Optional. If set builds matching the names in the (string) array will be excluded. Filter is additive with ProjectNameFilter.
.PARAMETER ExcludeReleaseNameFilter
Optional. If set releases matching the names in the (string) array will be excluded. Filter is additive with ProjectNameFilter.
#>
param(
[parameter(mandatory=$true)]
[string] $Token,
[bool] $CanUpdate = $true,
[parameter(mandatory=$true)]
[string] $AccountName,
[array] $ExcludeProjectNameFilter,
[array] $ExcludeBuildNameFilter,
[array] $ExcludeReleaseNameFilter
)
$ErrorActionPreference = "Stop"
$baseUrl = "https://$($AccountName)@dev.azure.com/$($AccountName)"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("$($AccountName):$Token"))
$projectApiUrl = "$baseUrl/_apis/projects?api-version=4.1"
$projectResponse = Invoke-RestMethod -Headers @{Authorization="Basic $base64AuthInfo"} -Uri $projectApiUrl -Method Get
Write-Output "# Azure DevOps Status"
Write-Output ""
ForEach($p in $projectResponse.value | Sort-Object -property name) {
$projectName = $p.name
if ($ExcludeProjectNameFilter -contains $projectName) {
continue
}
function Write-Header {
Write-Output "___"
Write-Output "## $projectName"
Write-Output ""
}
$hasHeader = $false
# get badges on all build definitions
$buildDefinitionsUrl = "$baseUrl/$projectName/_apis/build/definitions?api-version=4.1"
$buildResponse = Invoke-RestMethod -Headers @{Authorization="Basic $base64AuthInfo"} -Uri $buildDefinitionsUrl -Method Get
if ($buildResponse.count -gt 0) {
Write-Header
$hasHeader = $true
Write-Output "| Build | Status |"
Write-Output "|:---|---|"
}
$buildResponse.value | Sort-Object -property name | foreach {
if ($ExcludeBuildNameFilter -contains $_.name) {
continue
}
Write-Output "| [$($_.name)]($($_._links.web.href)) | ![$($_.name)]($($_._links.badge.href)) |"
}
Write-Output ""
# get badges for all release definitions
# note the use of "vsrm" in the url (without it, it won't work).
# all the "sample urls" in the doc use the ".vsrm." subdomain, but there is no mention of it elsewhere
# https://www.visualstudio.com/en-us/docs/integrate/api/rm/definitions
# https://stackoverflow.com/a/41585777
$releaseDefinitionsUrl = "https://$($AccountName).vsrm.visualstudio.com/$projectName/_apis/release/definitions?api-version=4.1"
$releaseResponse = Invoke-RestMethod -Headers @{Authorization="Basic $base64AuthInfo"} -Uri $releaseDefinitionsUrl -Method Get
if ($releaseResponse.count -gt 0) {
if (!$hasHeader) {
Write-Header
}
Write-Output ""
Write-Output "| Release | Status |"
Write-Output "|:---|---|"
}
$releaseResponse.value | Sort-Object -property name | foreach {
if ($ExcludeReleaseNameFilter -contains $_.name) {
continue
}
$updateRequired = $false
$rr = $_
# Download the release definition
$separator = if ($_.url.Contains("?")) { "&" } else { "?" }
$updateUrl = "$($_.url)$($separator)api-version=4.1"
$definition = Invoke-RestMethod -Headers @{Authorization="Basic $base64AuthInfo"} -Uri $updateUrl -Method Get
$definition.environments | foreach {
if (!$_.environmentOptions.badgeEnabled) {
if ($CanUpdate) {
$_.environmentOptions.badgeEnabled = $true
$updateRequired = $true
}
# can't write to output as the output is piped to a file
}
}
if ($updateRequired) {
$json = $definition | ConvertTo-Json -Depth 99
# now upload the changed definition to enable badges
$definition = Invoke-RestMethod -Headers @{Authorization="Basic $base64AuthInfo"} -Uri $updateUrl -ContentType "application/json" -Method Put -Body $json
}
$definition.environments | foreach {
Write-Output "| [$($rr.name) - $($_.name)]($($rr._links.web.href)) | ![$($_.name)]($($_.badgeUrl)) |"
}
}
Write-Output ""
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment