Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
bfef797
Add function to create a comment on a jira ticket
julianbopp Sep 3, 2025
7080b63
Add a function to flag & comment a jira ticket
julianbopp Sep 3, 2025
e4e3c8b
Flag jira issue if it changed but is deactivated
julianbopp Sep 9, 2025
f69f014
Add function to get jira key from ticket name
julianbopp Sep 9, 2025
6a20e4f
Validate branch changes are restricted to package
julianbopp Sep 10, 2025
9c93952
Fix jql syntax error (~ instead of =)
julianbopp Sep 10, 2025
599ca05
Issue warning when multiple tickets are found
julianbopp Sep 10, 2025
2ac6729
Merge branch 'jira-flag-comment' into check-correct-changes
julianbopp Sep 10, 2025
33d77b0
Merge branch 'jira-flag-comment' into handle-deactivated-packages
julianbopp Sep 11, 2025
f7f98cf
Use function to get jira key
julianbopp Sep 11, 2025
0a6e327
Add Find-PackageInWishlist function
julianbopp Oct 21, 2025
264e302
Merge branch 'check-wishlist-function' into integration
julianbopp Oct 21, 2025
8228a8e
Merge branch 'handle-deactivated-packages' into integration
julianbopp Oct 21, 2025
65cd6f9
Merge branch 'check-correct-changes' into integration
julianbopp Oct 21, 2025
8630532
Remove test function call in JiraObserver
julianbopp Oct 22, 2025
d345546
Replace search wishlist with dedicated function
julianbopp Oct 22, 2025
d10f4a4
Replace search wishlist with dedicated function
julianbopp Oct 22, 2025
3f5cf47
Replace search wishlist with dedicated function
julianbopp Oct 22, 2025
9c3d7b9
Replace search wishlist with dedicated function
julianbopp Oct 22, 2025
d781f38
Use correct FileName in .Notes
julianbopp Oct 22, 2025
e1ae706
Use correct FielName in .Notes
julianbopp Oct 22, 2025
5229dbc
Remove logging from Find-PackageInWishlist
julianbopp Oct 22, 2025
23ab67b
Remove response content in log of succesful case
julianbopp Oct 22, 2025
b9faf10
Do not delete jira state files while deleting logs
julianbopp Oct 23, 2025
3b39e62
Push repackaged to test/prod only after closing PR
julianbopp Oct 29, 2025
0ea2e25
Fix check for allowed changes
julianbopp Oct 29, 2025
e1db42d
Add Search-JiraComment.ps1
julianbopp Nov 4, 2025
c5e813d
Only flag and comment if comment is new
julianbopp Nov 4, 2025
21f0b3c
Make "deactivated in wishlist" a warning
julianbopp Nov 10, 2025
e08ecb6
Make cosmetic log changes
julianbopp Nov 10, 2025
667457c
Make "other files were changed" a warning
julianbopp Nov 10, 2025
a496c63
make 'invalid files' message a warning (part 2)
julianbopp Nov 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions WASP/Private/Find-PackageInWishlist.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
function Find-PackageInWishlist {
<#
.SYNOPSIS
Takes a package name and searches for it in the wishlist. Returns true if found, false otherwise.
.DESCRIPTION
Find a package in the wishlist by its name.
.NOTES
FileName: Find-PackageInWishlist.ps1
Author: Julian Bopp
Contact: its-wcs-ma@unibas.ch
Created: 2025-10-16
Version: 1.0.0
#>
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)][string] $packageName
)

begin {
$config = Read-ConfigFile

$GitRepo = $config.Application.PackagesWishlist
$GitFile = $GitRepo.Substring($GitRepo.LastIndexOf("/") + 1, $GitRepo.Length - $GitRepo.LastIndexOf("/") - 1)
$GitFolderName = $GitFile.Replace(".git", "")
$PackagesWishlistPath = Join-Path -Path $config.Application.BaseDirectory -ChildPath $GitFolderName
$wishlistPath = Join-Path -Path $PackagesWishlistPath -ChildPath "wishlist.txt"
$wishlistContent = Get-Content -Path $wishlistPath | Where-Object { $_ -notlike "#*" }
}

process {
$foundInWishlist = $false
foreach ($line in $wishlistContent) {
$line = $line -replace "@.*", ""
if ($line -eq $packageName) {
$foundInWishlist = $true
}
}
if (!$foundInWishlist) {
return $false
} else {
return $true
}
}

end {
}
}
93 changes: 93 additions & 0 deletions WASP/Private/Flag-JiraTicket.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
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

if ($comment) {

# Check if the comment already exists
$existingComment = Search-JiraComment -issueKey $issueKey -searchString $flagComment

if ($existingComment) {
Write-Log -Message "Comment already exists on Jira ticket $issueKey. Skipping adding comment and flag." -Severity 2
return
}
New-JiraComment -issueKey $issueKey -comment $flagComment
}

Write-Log -Message "Flagging jira ticket $issueKey" -Severity 1
$response = Invoke-WebRequest -Uri $url -Method Put -Headers $header -Body $body

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 {
}
}
61 changes: 61 additions & 0 deletions WASP/Private/Get-JiraIssueKeyFromName.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
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 }

# 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
}

end { }
}
16 changes: 15 additions & 1 deletion WASP/Private/Invoke-JiraObserver.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,14 @@ function Invoke-JiraObserver {
$GitBranchDEV = $Config.Application.GitBranchDEV
$GitBranchTEST = $Config.Application.GitBranchTEST
$GitBranchPROD = $Config.Application.GitBranchPROD

$GitRepo = $config.Application.PackagesWishlist
$GitFile = $GitRepo.Substring($GitRepo.LastIndexOf("/") + 1, $GitRepo.Length - $GitRepo.LastIndexOf("/") - 1)
}

process {
$nameAndVersionSeparator = '@'

# Die neueste Jira State file wird eingelesen als Hashtable
Write-Log -Message "Reading latest Jira state file" -Severity 0
$jiraStateFileContent, $JiraStateFile = Read-JiraStateFile
Expand Down Expand Up @@ -132,6 +137,16 @@ function Invoke-JiraObserver {
$UpdateJiraStateFile = $true
# jedes Issue, welches vom Stand im neusten JiraState-File abweicht wird einzeln durchgegangen
foreach($key in $IssuesCompareState.keys) {
$packageName, $packageVersion, $re = $key.split($nameAndVersionSeparator)
$foundInWishlist = Find-PackageInWishlist -PackageName $packageName
if (!$foundInWishlist) {
# Paket nicht in der Wishlist, Ticket wird auf Jira geflagged und kommentiert.
Write-Log "Skip handling of $key - deactivated in wishlist." -Severity 2
$IssueKey = Get-JiraIssueKeyFromName -issueName "$packageName$nameAndVersionSeparator$packageVersion"
Flag-JiraTicket -issueKey $IssueKey -comment "Package $packageName is deactivated in the wishlist."
continue
}

# Ermittlung des Dev-Branches anhand des Paket Namens (mit Eventualität des Repackaging branches)
$DevBranchPrefix = "$GitBranchDEV$key"
$DevBranch = Get-DevBranch -RemoteBranches $RemoteBranches -DevBranchPrefix $DevBranchPrefix
Expand Down Expand Up @@ -196,4 +211,3 @@ function Invoke-JiraObserver {
}
}
}

58 changes: 58 additions & 0 deletions WASP/Private/New-JiraComment.ps1
Original file line number Diff line number Diff line change
@@ -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." -Severity 0
} else {
Write-Log -Message "Failed to comment jira ticket! StatusCode: $($response.StatusCode): $($response.StatusDescription)" -Severity 3
}
}

end {
}
}
66 changes: 66 additions & 0 deletions WASP/Private/Search-JiraComment.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
function Search-JiraComment {
<#
.SYNOPSIS
Searches for a specific comment in a Jira Ticket
.DESCRIPTION
Retrieves all comments from the specified Jira ticket and searches for a comment containing the given search string.
.NOTES
FileName: Search-JiraComment.ps1
Author: Julian Bopp
Contact: its-wcs-ma@unibas.ch
Created: 2025-11-04
Version: 1.0.0
#>
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)][string] $issueKey,
[Parameter(Mandatory = $true)][string] $searchString
)

begin {
$config = Read-ConfigFile
$jiraBaseUrl = $config.Application.JiraBaseUrl
$jiraUser = $config.Application.JiraUser
$jiraPassword = $config.Application.JiraPassword

$base64AuthInfo = [Convert]::ToBase64String(
[Text.Encoding]::ASCII.GetBytes("${jiraUser}:${jiraPassword}")
)
$headers = @{
"Authorization" = "Basic $base64AuthInfo"
"Content-Type" = "application/json"
}

$url = "$jiraBaseUrl/rest/api/2/issue/$issueKey/comment"
}

process {
Write-Log -Message "Searching Jira ticket $issueKey for comment containing '$searchString'" -Severity 1

try {
$response = Invoke-WebRequest -Uri $url -Method Get -Headers $headers -UseBasicParsing
$comments = ($response.Content | ConvertFrom-Json).comments

if (-not $comments) {
Write-Log -Message "No comments found for Jira ticket $issueKey" -Severity 2
return $null
}

$matched = $comments | Where-Object { $_.body -match [Regex]::Escape($searchString) }

if ($matched) {
Write-Log -Message "Found $($matched.Count) matching comment(s) in $issueKey" -Severity 0
return $matched | Select-Object id, author, created, body
} else {
Write-Log -Message "No comment matching '$searchString' in $issueKey" -Severity 2
return $null
}
}
catch {
Write-Log -Message "Failed to retrieve comments for Jira ticket $(issueKey): $($_.Exception.Message)" -Severity 3
return $null
}
}

end { }
}
11 changes: 3 additions & 8 deletions WASP/Private/Search-NewPackages.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,16 @@ function Search-NewPackages {
$Manual
)
begin {
$config = Read-ConfigFile

$GitRepo = $config.Application.PackagesWishlist
$GitFile = $GitRepo.Substring($GitRepo.LastIndexOf("/") + 1, $GitRepo.Length - $GitRepo.LastIndexOf("/") - 1)
$GitFolderName = $GitFile.Replace(".git", "")
$PackagesWishlistPath = Join-Path -Path $config.Application.BaseDirectory -ChildPath $GitFolderName
$wishlistPath = Join-Path -Path $PackagesWishlistPath -ChildPath "wishlist.txt"
}

process {
$wishlistContent = Get-Content -Path $wishlistPath | Select-String -Pattern "#" -NotMatch | ForEach-Object {$_ -replace "@.*", ""}

foreach ($package in $Packages) {
# Check if the package is in (not deactivated) wishlist. Only scan for packages that are relevant
if (!(($package.Name) -in $wishlistContent)) {
$packageName = $package.Name
$foundInWishlist = Find-PackageInWishlist -PackageName $packageName
if (!($foundInWishlist)) {
continue
} else {
if ($Manual) {
Expand Down
Loading