Skip to content

Just My Blog

Just great and interesting articles and more!

  • Home
  • Tips & Tricks
  • Toggle search form

Create release notes via branch comparison (Part 2)

Posted on 18 Jun 202418 Jun 2024 By Frans van Es

In Part 1, I showed you how to compare two release branches within a repository. Now we dive into creating some release notes.

Let’s continue

In order to mark the work items which are candidate for the release notes, it is necessary to add a custom field to the work item, e.g. “Release branch”. Once that is done, the script can use it.

# Set Release branch field on workitems
foreach($workitem in $workitems) {

    $body = @( 
@{
op = 'add'
path = '/fields/Custom.Releasebranch'
value = "$($releaseCurrent)"
}
)

    $jsonBody = ConvertTo-Json $body
    $uri = "$serverUri/$project/_apis/wit/workitems/" + $workitem + "?api-version=7.1-preview.3"
    $results = Invoke-RestMethod -Uri $uri -Method Patch -ContentType "application/json-patch+json" -Body $jsonBody -Headers $headers
}

Create query

A query is needed to see which work items have the status “Ready for UAT” and will therefore be deployed to the UAT environment. Of course you can have different statuses.

Here is a very simple example, filtering on the status and the area path for a team.

Creating release notes

An Azure DevOps query will be used within the next script.

First some set up

# FIRST RUN set-private-token.ps1 to set environment variable
& $PSScriptRoot/set-private-token.ps1
$privateToken = $Env:privateToken

# Set default file location
$filePath = "$env:USERPROFILE\downloads"

$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "",$privateToken)))
$headers = @{Authorization=("Basic {0}" -f $base64AuthInfo)}

# ADO Project settings
$organisation = "myorganisation"
$serverUri = "https://dev.azure.com/$organisation"
$project = "myproject"

$startDate = Get-Date

$query = "GUID of query, extract it from the url"

$outputfile = "$($filePath)\Release UAT $(Get-Date $startDate -f 'yyyy-MM-dd').html"
$relnotesversion = "UAT$(Get-Date $startDate -f 'yyyy-MM-dd')"

# Format date to a proper British date :)
[System.Threading.Thread]::CurrentThread.CurrentCulture = "en-GB"; $niceStartDate = get-date $startDate -f 'dd MMM yyyy'

Some simple HTML styling

This is needed to get a nice layout.

$style = @"
body {
    color:#333333;
    font-family:Calibri,Tahoma;
    font-size: 10pt;
}

h1 {
    text-align:left;
}

h2 {
    border-top:1px solid #666666;
}

th {
    font-weight:bold;
    color:#eeeeee;
    background-color:#333333;
    cursor:pointer;
    text-align:left
}

.odd  { background-color:#ffffff; }

.even { background-color:#dddddd; }

@media print {
  @page { margin: 0; }
  body { margin: 0.5cm; }
  html { zoom: 80%;}
}
"@

A lot of building HTML

Creating the HTML to show the query contents into a table. Toned down to simplify it somewhat.

$pagetitle = "Release notes for UAT"
$pageheader = "<html><style>$style</style><body>"
$pageheader2 = @"
<title>{0}</title>
<h1>{0}</h1>
<table>
<tr><td width=180><b>Deployment for</b></td><td width=180>UAT</td><td width=180><b>Version</b></td><td width=180>{1}</td></tr>
</table>
<hr>
"@ -f $pagetitle, $niceStartDate

$pagefooter = "</table></body></html>"

$tableheader = "<table><th width=70>Id</th><th width=180>Type</th><th width=600>Description</th><th width=120>Status</th>"

Write-Host "Running query to collect data for release notes." -ForegroundColor Green

$url = "$serverUri/$project/_apis/wit/wiql/$($query)?api-version=7.1-preview.2"
$results = Invoke-RestMethod -Uri $url -ContentType "application/json" -headers $headers -Method GET

if($results.workItems.Count -eq 0) { Write-Host "No results were found, exiting."; return }

$workitems =@()
foreach($workitem in $results.workItems) {
    
    # Get info for this work item
    $url2 = "$serverUri/$project/_apis/wit/workitems/" + $workitem.id + "?fields=System.WorkItemType,System.Title,System.State,System.AssignedTo,System.Tags,Custom.Releasebranch&api-version=7.1-preview.3"
    $results2 = Invoke-RestMethod -Uri $url2 -Method Get -ContentType "application/json" -Headers $headers
    $workitemUrl = "$serverUri/$project/_workitems/edit/$($workitem.id)"

    $workitems += [pscustomobject]@{Workitem=$workitem.id; Url=$workitemUrl; Type=$results2.fields.'System.WorkItemType'; Title=$results2.fields.'System.Title'; Status=$results2.fields.'System.State';}
}

Write-Host "Release notes are being generated..." -ForegroundColor Green

Write-Output $pageheader $pageheader2 | out-file $outputfile
Write-Output $tableheader | out-file -Append $outputfile

$even = $false
foreach($workitem in $workitems) {
    if($even) { $rowcolor = "even" } else { $rowcolor = "odd" }
    Write-Output "<tr valign=top class=$rowcolor><td><a href='$($workitem.Url)'>$($workitem.Workitem)</a></td><td>$($workitem.Type)</td><td>$($workitem.Title)</td><td>$($workitem.Status)</td></tr>"| out-file -Append $outputfile
    $even = -not $even
}

Write-Output $pagefooter | out-file -Append $outputfile

Write-Host "File '$outputfile' has been generated." -ForegroundColor Green

Converting to PDF

We can send out HTML via email, but converting to PDF will result in a more consistent document.

# Change to correct extension
$pdffile = $outputfile.Replace("html","pdf")

Write-Host "Transforming to PDF." -ForegroundColor Green
if (Test-Path $pdffile) {
    Remove-Item $pdffile -Force
}

# Use Microsoft Edge to do the transformation
Start-Process "msedge.exe" -ArgumentList @("--headless","--print-to-pdf=""$($pdffile)""","--disable-extensions","--no-margins","--no-pdf-header-footer","--disable-popup-blocking","--run-all-compositor-stages-before-draw","--disable-checker-imaging", """file:///$($outputfile)""")

# Removing HTML file and showing PDF file
while (!(Test-Path $pdffile)) { Start-Sleep 1 }
if (Test-Path $outputfile) {
    Remove-Item $outputfile -Force
}

Start-Process $pdffile

Wrapping up

I have shown you a simpler version of the actual version, as it would be too extensive for this article. With these script you have a basic version to extend, maybe even add sending the release notes with the script.

Azure DevOps Tags:DevOps

Post navigation

Previous Post: Create release notes via branch comparison (Part 1)
Next Post: Monitoring Cloud Flows

Categories

  • Azure (2)
  • Azure DevOps (2)
  • Dynamics CRM (4)

Tag cloud

Application Insights (1) Cloud flows (2) DevOps (3) FetchXML (2) Monitoring (2) Reports (1) SSRS (1)

Dynamics CRM Newsfeed

  • Smarter callbacks with availability-aware scheduling CCaaS APIs
  • AI in sales: Applying historical lessons to modern challenges 
  • Get started with agents for finance: Learnings from 2025 Gartner® CFO & Finance Executive Conference
  • The power of proactive engagement in Dynamics 365 Contact Center
  • Seamless scheduling across time zones in Dynamics 365 Field Service

Copyright © 2024 Just My Blog -

Powered by PressBook WordPress theme