From bfef7974a68bf9fcaa09467964c10378cd173a22 Mon Sep 17 00:00:00 2001 From: julianbopp Date: Wed, 3 Sep 2025 20:36:11 +0200 Subject: [PATCH 1/6] Add function to create a comment on a jira ticket --- WASP/Private/New-JiraComment.ps1 | 58 ++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 WASP/Private/New-JiraComment.ps1 diff --git a/WASP/Private/New-JiraComment.ps1 b/WASP/Private/New-JiraComment.ps1 new file mode 100644 index 0000000..37c0219 --- /dev/null +++ b/WASP/Private/New-JiraComment.ps1 @@ -0,0 +1,58 @@ +function New-JiraComment { + <# + .SYNOPSIS + Adds a comment to a Jira Ticket + .DESCRIPTION + Adds a comment to a Jira Ticket + .NOTES + FileName: New-JiraComment.ps1 + Author: Julian Bopp + Contact: its-wcs-ma@unibas.ch + Created: 2025-08-21 + Version: 1.0.0 + #> + [CmdletBinding()] + param ( + [Parameter(Mandatory = $true)][string] $issueKey, + [Parameter(Mandatory = $true)][string] $comment + ) + + begin { + $config = Read-ConfigFile + $jiraBaseUrl = $config.Application.JiraBaseUrl + $jiraUser = $config.Application.JiraUser + $jiraPassword = $config.Application.JiraPassword + $projectKey = $config.Application.ProjectKey + $issueType = $config.Application.IssueType # Story + } + + process { + $url = "$($jiraBaseUrl)/rest/api/2/issue/$issueKey/comment" + + $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("${jiraUser}:${jiraPassword}"))) + + $header = @{ + "Authorization" = "Basic $base64AuthInfo" + "Content-Type" = "application/json" + } + + # Create the JSON payload for the new comment + $body = @{ + body = $comment + } | ConvertTo-Json -Depth 3 + + Write-Log -Message "Commenting jira ticket $issueKey with comment: $comment" -Severity 1 + + $response = Invoke-WebRequest -Uri $url -Method Post -Headers $header -Body $body + + if ($response.StatusCode -eq 201) { + Write-Log -Message "StatusCode: $($response.StatusCode)" -Severity 0 + Write-Log -Message "Jira ticket successfully commented: $($response.Content)" -Severity 0 + } else { + Write-Log -Message "Failed to comment jira ticket! StatusCode: $($response.StatusCode): $($response.StatusDescription)" -Severity 3 + } + } + + end { + } +} \ No newline at end of file From 7080b6362614e5511aac3589e643def5e4489807 Mon Sep 17 00:00:00 2001 From: julianbopp Date: Wed, 3 Sep 2025 20:37:02 +0200 Subject: [PATCH 2/6] Add a function to flag & comment a jira ticket --- WASP/Private/Flag-JiraTicket.ps1 | 85 ++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 WASP/Private/Flag-JiraTicket.ps1 diff --git a/WASP/Private/Flag-JiraTicket.ps1 b/WASP/Private/Flag-JiraTicket.ps1 new file mode 100644 index 0000000..54a271e --- /dev/null +++ b/WASP/Private/Flag-JiraTicket.ps1 @@ -0,0 +1,85 @@ +function Flag-JiraTicket { + <# + .SYNOPSIS + Flags a Jira Ticket + .DESCRIPTION + Flags or unflags and optionally comments a Jira Ticket with the given parameters + .NOTES + FileName: Flag-JiraTicket.ps1 + Author: Julian Bopp + Contact: its-wcs-ma@unibas.ch + Created: 2025-08-21 + Version: 1.0.0 + #> + [CmdletBinding()] + param ( + [Parameter(Mandatory = $true)][string] $issueKey, + [Parameter(Mandatory = $false)][string] $comment, + [Parameter(Mandatory = $false)][bool] $unflag + ) + + begin { + $config = Read-ConfigFile + $jiraBaseUrl = $config.Application.JiraBaseUrl + $jiraUser = $config.Application.JiraUser + $jiraPassword = $config.Application.JiraPassword + $projectKey = $config.Application.ProjectKey + $issueType = $config.Application.IssueType + } + + process { + $url = "$($jiraBaseUrl)/rest/api/2/issue/$issueKey" + + $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("${jiraUser}:${jiraPassword}"))) + + $header = @{ + "Authorization" = "Basic $base64AuthInfo" + "Content-Type" = "application/json" + } + + # Create comment if provided + if ($comment) { + $flagComment = "(flag) " + $comment + if ($unflag) { + $flagComment = "(flagoff) " + $comment + } + } + # Create the JSON payload + $value = "Impediment" + + if ($unflag) { + $value = $null + } + + $body = @{ + fields = @{ + # This field is used for the flagging + customfield_10000 = @( + @{ value = $value } + ) + + } + } | ConvertTo-Json -Depth 3 + + Write-Log -Message "Flagging jira ticket $issueKey" -Severity 1 + $response = Invoke-WebRequest -Uri $url -Method Put -Headers $header -Body $body + + if ($comment) { + New-JiraComment -issueKey $issueKey -comment $flagComment + } + + if ($response.StatusCode -eq 204) { + Write-Log -Message "StatusCode: $($response.StatusCode)" -Severity 0 + if ($unflag) { + Write-Log -Message "Jira ticket successfully unflagged" -Severity -0 + } else { + Write-Log -Message "Jira ticket successfully flagged" -Severity -0 + } + } else { + Write-Log -Message "Failed to flag/unflag jira ticket! StatusCode: $($response.StatusCode): $($response.StatusDescription)" -Severity 3 + } + } + + end { + } +} From f69f01458f426cbe964b2f54a7f96df6202d3399 Mon Sep 17 00:00:00 2001 From: julianbopp Date: Tue, 9 Sep 2025 16:42:09 +0200 Subject: [PATCH 3/6] Add function to get jira key from ticket name --- WASP/Private/Get-JiraIssueKeyFromName.ps1 | 56 +++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 WASP/Private/Get-JiraIssueKeyFromName.ps1 diff --git a/WASP/Private/Get-JiraIssueKeyFromName.ps1 b/WASP/Private/Get-JiraIssueKeyFromName.ps1 new file mode 100644 index 0000000..3c97904 --- /dev/null +++ b/WASP/Private/Get-JiraIssueKeyFromName.ps1 @@ -0,0 +1,56 @@ +function Get-JiraIssueKeyFromName { + <# + .SYNOPSIS + Retrieves a Jira issue key from an issue name (summary). + .DESCRIPTION + Uses Jira REST API search to find an issue by its summary/title + and returns the issue key (e.g., PROJ-123). + .NOTES + FileName: Get-JiraIssueKeyFromName.ps1 + Author: Julian Bopp + Contact: its-wcs-ma@unibas.ch + Created: 2025-09-09 + Version: 1.0.0 + #> + [CmdletBinding()] + param ( + [Parameter(Mandatory = $true)][string] $issueName + ) + + begin { + $config = Read-ConfigFile + $jiraBaseUrl = $config.Application.JiraBaseUrl + $jiraUser = $config.Application.JiraUser + $jiraPassword = $config.Application.JiraPassword + $projectKey = $config.Application.ProjectKey + } + + process { + $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("${jiraUser}:${jiraPassword}"))) + + $header = @{ + "Authorization" = "Basic $base64AuthInfo" + "Content-Type" = "application/json" + } + + # JQL to search by issue summary + $jql = "project = $projectKey AND summary = `"$issueName`"" + $searchUrl = "$jiraBaseUrl/rest/api/2/search?jql=$([System.Web.HttpUtility]::UrlEncode($jql))" + + Write-Log -Message "Searching for Jira issue with summary: $issueName" -Severity 1 + $response = Invoke-RestMethod -Uri $searchUrl -Method Get -Headers $header + + if ($response.issues.Count -eq 0) { + Write-Log -Message "No Jira issue found with summary: $issueName" -Severity 2 + return $null + } + + # Return all matching issue keys + $issueKeys = $response.issues | ForEach-Object { $_.key } + + Write-Log -Message "Found Jira issues: $($issueKeys -join ', ')" -Severity 0 + return $issueKeys + } + + end { } +} From 9f7f01336116c98dafd8beee5e9ba3f5a2e572ba Mon Sep 17 00:00:00 2001 From: julianbopp Date: Tue, 9 Sep 2025 16:47:55 +0200 Subject: [PATCH 4/6] No new branch for package not in wishlist --- WASP/Private/New-RemoteBranch.ps1 | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/WASP/Private/New-RemoteBranch.ps1 b/WASP/Private/New-RemoteBranch.ps1 index 0707cd1..eaa94b7 100644 --- a/WASP/Private/New-RemoteBranch.ps1 +++ b/WASP/Private/New-RemoteBranch.ps1 @@ -30,9 +30,36 @@ function New-RemoteBranch { begin { $Config = Read-ConfigFile $RemoteBranches = Get-RemoteBranches -Repo $Repository -User $User + + $GitRepo = $config.Application.PackagesWishlist + $GitFile = $GitRepo.Substring($GitRepo.LastIndexOf("/") + 1, $GitRepo.Length - $GitRepo.LastIndexOf("/") - 1) + $WishlistFolderName = $GitFile.Replace(".git", "") + $PackagesWishlistPath = Join-Path -Path $config.Application.BaseDirectory -ChildPath $WishlistFolderName + $wishlistPath = Join-Path -Path $PackagesWishlistPath -ChildPath "wishlist.txt" } process { + + $wishlist = Get-Content -Path $wishlistPath | Where-Object { $_ -notlike "#*" } + $nameAndVersionSeparator = '@' + + $packageName = $packageName -replace "$nameAndVersionSeparator.*", "" + $packageName = $packageName -replace "dev/", "" + $foundInWishlist = $false + foreach ($line in $wishlist) { + $line = $line -replace "@.*", "" + if ($line -eq $packageName) { + $foundInWishlist = $true + } + } + + if (-not $foundInWishlist) { + $IssueKey = Get-JiraIssueKeyFromName -issueName $packageName + Write-Log "Package $packageName not found in wishlist. Will not create branch." -Severity 2 + Flag-JiraTicket -issueKey $IssueKey -comment "Package $packageName not found in wishlist. Will not create branch." + return + } + if ($RemoteBranches.Contains($BranchName)) { Write-Log "Branch $branchName already exist. Nothing to do" return From 9c939527161450527dc90d01c3d668c1dccdf609 Mon Sep 17 00:00:00 2001 From: julianbopp Date: Wed, 10 Sep 2025 16:43:11 +0200 Subject: [PATCH 5/6] Fix jql syntax error (~ instead of =) --- WASP/Private/Get-JiraIssueKeyFromName.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WASP/Private/Get-JiraIssueKeyFromName.ps1 b/WASP/Private/Get-JiraIssueKeyFromName.ps1 index 3c97904..3cd216a 100644 --- a/WASP/Private/Get-JiraIssueKeyFromName.ps1 +++ b/WASP/Private/Get-JiraIssueKeyFromName.ps1 @@ -34,7 +34,7 @@ function Get-JiraIssueKeyFromName { } # JQL to search by issue summary - $jql = "project = $projectKey AND summary = `"$issueName`"" + $jql = "project = $projectKey AND summary ~ `"$issueName`"" $searchUrl = "$jiraBaseUrl/rest/api/2/search?jql=$([System.Web.HttpUtility]::UrlEncode($jql))" Write-Log -Message "Searching for Jira issue with summary: $issueName" -Severity 1 From 599ca056f517874801f636a953cb7e35f0dfe04b Mon Sep 17 00:00:00 2001 From: julianbopp Date: Wed, 10 Sep 2025 16:43:56 +0200 Subject: [PATCH 6/6] Issue warning when multiple tickets are found --- WASP/Private/Get-JiraIssueKeyFromName.ps1 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/WASP/Private/Get-JiraIssueKeyFromName.ps1 b/WASP/Private/Get-JiraIssueKeyFromName.ps1 index 3cd216a..08f1786 100644 --- a/WASP/Private/Get-JiraIssueKeyFromName.ps1 +++ b/WASP/Private/Get-JiraIssueKeyFromName.ps1 @@ -48,6 +48,11 @@ function Get-JiraIssueKeyFromName { # Return all matching issue keys $issueKeys = $response.issues | ForEach-Object { $_.key } + # if multiple issues found, log a warning + if ($issueKeys.Count -gt 1) { + Write-Log -Message "Multiple Jira issues found with summary: $issueName. Returning all matching keys." -Severity 2 + } + Write-Log -Message "Found Jira issues: $($issueKeys -join ', ')" -Severity 0 return $issueKeys }