Skip to content

Instantly share code, notes, and snippets.

@phenixita
Created June 7, 2024 15:08
Show Gist options
  • Select an option

  • Save phenixita/8c21d334f665c121c434079d11665d51 to your computer and use it in GitHub Desktop.

Select an option

Save phenixita/8c21d334f665c121c434079d11665d51 to your computer and use it in GitHub Desktop.
Release Notes from azure devops work items
# Definisci i parametri
$organization = "micheleferracin" # Sostituisci con il nome della tua organizzazione
$project = "Parts Unlimited" # Sostituisci con il nome del tuo progetto
$pat = "YOUR PAT HERE" # with read work-item permission
$openApiPat = "YOUR OPEN API TOKEN HERE"
function Replace-ImageUrlsInMarkdown {
param (
[string]$markdownFilePath,
[string]$fixedFolder
)
# Leggi il contenuto del file markdown
$content = Get-Content -Path $markdownFilePath
# Definisci il pattern di ricerca
$pattern = "https:\/\/dev\.azure\.com\/.*\/_apis\/wit\/attachments\/(.*)\?fileName=([^\s]+)"
# Esegui la sostituzione utilizzando il pattern e il formato desiderato
$content = $content -replace $pattern, 'attachment/$1$2'
# Scrivi il contenuto modificato nel file originale
Set-Content -Path $markdownFilePath -Value $content
}
function Download-ImagesFromMarkdown {
param (
[Parameter(Mandatory = $true)]
[string]$markdownFilePath,
[Parameter(Mandatory = $true)]
[string]$outputFolder
)
if (-not (Test-Path $markdownFilePath)) {
Write-Host "Markdown file not found: $markdownFilePath"
return
}
if (-not (Test-Path $outputFolder)) {
New-Item -ItemType Directory -Path $outputFolder | Out-Null
}
$markdownContent = Get-Content -Path $markdownFilePath
# Regex per trovare i link alle immagini ![alt text](http://url)
$regex = '!\[.*?\]\((http.*?)\)'
foreach ($line in $markdownContent) {
if ($line -match $regex) {
$matchez = [regex]::Matches($line, $regex)
foreach ($match in $matchez) {
$url = $match.Groups[1].Value
# Scarica da azdo l'allegato
$fileName = $url.Substring($url.LastIndexOf("=") + 1)
$attchmentId = $url.Substring($url.LastIndexOf("attachments/") + 12, $url.LastIndexOf("?") - $url.LastIndexOf("attachments/") - 12)
$outputFilePath = Join-Path -Path $outputFolder -ChildPath $attchmentId$fileName
Download-Attachment -attachmentUrl $url -outputFilePath $outputFilePath -base64AuthInfo $base64AuthInfo
}
}
}
Write-Host "Download completed."
}
# Funzione per pulire e ricreare la cartella degli allegati
function Setup-AttachmentFolder {
param (
[string]$folderPath
)
if (Test-Path -Path $folderPath) {
Remove-Item -Path $folderPath -Recurse -Force
}
New-Item -Path $folderPath -ItemType Directory | Out-Null
}
function AskSummary {
param (
[string]$openApiPat,
[string]$jsonContent
)
$prompt = @'
Crea un documento in formato markdown di
release note per i work-item che ti passo alla fine di questo prompt.
Non inserire i nomi di chi ha fatto cosa. Spiega bene perché ti stai rivolgendo agli utenti finali.
Il documento deve contenere un riassunto generale su cosa sono le novità.
Poi deve contenere una sezione dove compare ogni work-item come sottotitolo con la sua descrizione.
Infine fai una sezione finale che incoraggia gli utenti a provare le novità fatte con amore. Ecco i work-item:
'@ + $jsonContent
$body = @{
model = "gpt-4o"
messages = @(
@{
role = "system"
content = "Hello, I'm a bot that can help you summarize work-items from Azure DevOps."
},
@{
role = "user"
content = $prompt
}
)
}
Write-Host "LLM is thinking..." -NoNewline
$response = Invoke-RestMethod -Uri "https://api.openai.com/v1/chat/completions" -Method Post -Headers @{
"Authorization" = "Bearer $openApiPat"
"Content-Type" = "application/json"
} -Body ($body | ConvertTo-Json)
Write-Host " done!" -ForegroundColor Green
return $response
}
function Download-Attachment {
param (
[string]$attachmentUrl,
[string]$outputFilePath,
[string]$base64AuthInfo
)
Invoke-RestMethod -Uri $attachmentUrl -Method Get -Headers @{
Authorization = "Basic $base64AuthInfo"
} -OutFile $outputFilePath
}
# Imposta la cartella degli allegati
Setup-AttachmentFolder -folderPath "attachment"
# Crea la base64 del token per l'autenticazione
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($pat)"))
# Definisci la query per ottenere i work item negli stati specificati
$query = @"
{
"query": "Select [System.Id], [System.Title], [System.State] From WorkItems Where [System.State] In ('Pronto')"
}
"@
# Esegui la richiesta HTTP
$response = Invoke-RestMethod -Uri "https://dev.azure.com/$organization/$project/_apis/wit/wiql?api-version=6.0" -Method Post -Headers @{Authorization = ("Basic {0}" -f $base64AuthInfo) } -Body $query -ContentType "application/json"
# Inizializza una lista per i dettagli dei work item
$workItemsDetails = @()
# Ottieni i dettagli di ogni work item
foreach ($item in $response.workItems | Select-Object) {
$workItemDetail = Invoke-RestMethod -Uri "https://dev.azure.com/$organization/_apis/wit/workitems/$($item.id)?api-version=6.0" -Method Get -Headers @{Authorization = ("Basic {0}" -f $base64AuthInfo) }
# Implement progress bar
$progress = [math]::Round(($($workItemsDetails.Count + 1) / $response.workItems.Count) * 100)
Write-Progress -Activity "Retrieving work items" -Status "Processing work item $($workItemsDetails.Count+1) of $($response.workItems.Count)" -PercentComplete $progress
# Aggiungi i dettagli del work item alla lista
$workItemsDetails += [PSCustomObject]@{
Id = $workItemDetail.id
Title = $workItemDetail.fields.'System.Title'
Description = $workItemDetail.fields.'System.Description'
ReleaseNote = $workItemDetail.fields.'System.Description'
}
}
# Converti i dettagli dei work item in JSON
$workItemsJson = $workItemsDetails | ConvertTo-Json -Depth 10
# Salva il JSON in un file
$outputFilePath = "workItemsDetails.json"
$workItemsJson | Out-File -FilePath $outputFilePath
# Invia JSON a OpenAPI
$response = AskSummary -openApiPat $openApiPat -jsonContent $workItemsJson
# cancella il file releasenote.md
Remove-Item -Path "releasenote.md" -ErrorAction SilentlyContinue
$response.choices[0].message.content | Out-File -FilePath "releasenote.md"
# Download delle immagini
Download-ImagesFromMarkdown -markdownFilePath "releasenote.md" -outputFolder "attachment"
Replace-ImageUrlsInMarkdown -markdownFilePath "releasenote.md" -fixedFolder "attachment"
start "releasenote.md"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment