utilities/pipelines/manageIssueForFailingPipelines/Set-IssueForWorkflow.ps1 (98 lines of code) (raw):

<# .SYNOPSIS Check for failing pipelines and create issues for those, that are failing. .DESCRIPTION If a pipeline fails, a new issue will be created, with a link to the failed pipeline. If the issue is already existing, a comment will be added, if a new run failed (with the link for the new failed run). If a pipeline run succeeds and an issue is open for the failed run, it will be closed (and a link to the successful run is added to the issue). .PARAMETER Repo Mandatory. The name of the respository to scan. Needs to have the structure "<owner>/<repositioryName>" .PARAMETER LimitNumberOfRuns Optional. Number of recent runs to scan for failed runs. Default is 100. .PARAMETER LimitInDays Optional. Only runs in the past selected days will be analyzed. Default is 2. .PARAMETER IgnoreWorkflows Optional. List of workflow names that should be ignored (even if they fail, no ticket will be created). Default is an empty array. .EXAMPLE Set-IssueForWorkflow -Repo 'owner/repo01' -LimitNumberOfRuns 100 -LimitInDays 2 -IgnoreWorkflows @('Pipeline 01') Check the last 100 workflow runs in the repository 'owner/repo01' that happened in the last 2 days. If the workflow name is 'Pipeline 01', then ignore the workflow run. .NOTES The function requires GitHub CLI to be installed. #> function Set-IssueForWorkflow { [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Low')] param ( [Parameter(Mandatory = $true)] [string] $Repo, [Parameter(Mandatory = $false)] [int] $LimitNumberOfRuns = 100, [Parameter(Mandatory = $false)] [int] $LimitInDays = 2, [Parameter(Mandatory = $false)] [String[]] $IgnoreWorkflows = @() ) $issues = gh issue list --state open --label 'automation,bug' --json 'title,url,body,comments' --repo $Repo | ConvertFrom-Json -Depth 100 $runs = gh run list --json 'url,workflowName,headBranch,startedAt' --limit $LimitNumberOfRuns --repo $Repo | ConvertFrom-Json -Depth 100 $workflowRuns = @{} $issuesCreated = 0 $issuesCommented = 0 $issuesClosed = 0 foreach ($run in $runs) { $runStartTime = [Datetime]::ParseExact($run.startedAt, 'MM/dd/yyyy HH:mm:ss', $null) if (($run.headBranch -eq 'main') -and ($runStartTime -gt (Get-Date).AddDays(-$LimitInDays)) -and ($IgnoreWorkflows -notcontains $run.workflowName)) { $runId = $run.url.Split('/') | Select-Object -Last 1 $runDetails = gh run view $runId --json 'conclusion,number' --repo $Repo | ConvertFrom-Json -Depth 100 if (-not $workflowRuns.ContainsKey($run.workflowName) -or $runDetails.number -gt $workflowRuns[$run.workflowName].number) { $workflowRun = New-Object PSObject -Property @{ workflowName = $run.workflowName number = $runDetails.number url = $run.url conclusion = $runDetails.conclusion } if (-not $workflowRuns.ContainsKey($run.workflowName)) { $workflowRuns.Add($run.workflowName, $workflowRun) } else { $workflowRuns[$run.workflowName] = $workflowRun } } } } foreach ($workflowRun in $workflowRuns.values) { if ($workflowRun.conclusion -eq 'failure') { $issueName = "[Failed pipeline] $($workflowRun.workflowName)" $failedrun = "failed run: $($workflowRun.url)" if ($issues.title -notcontains $issueName) { if ($PSCmdlet.ShouldProcess("Issue [$issueName]", 'Create')) { gh issue create --title "$issueName" --body "$failedrun" --label 'automation,bug' --repo $Repo } $issuesCreated++ } else { $issue = ($issues | Where-Object { $_.title -eq $issueName })[0] if (!$issue.body.Contains($failedrun)) { if ($issue.comments.length -eq 0) { if ($PSCmdlet.ShouldProcess("Issue [$issueName]", 'Add comment')) { gh issue comment $issue.url --body $failedrun --repo $Repo } $issuesCommented++ } else { if (!$issue.comments.body.Contains($failedrun)) { if ($PSCmdlet.ShouldProcess("Issue [$issueName]", 'Close')) { gh issue comment $issue.url --body $failedrun --repo $Repo } $issuesCommented++ } } } } } else { $issueName = "[Failed pipeline] $($workflowRun.workflowName)" if ($issues.title -contains $issueName) { $issue = ($issues | Where-Object { $_.title -eq $issueName })[0] $successfulrun = "successful run: $($workflowRun.url)" gh issue close $issue.url --comment $successfulrun --repo $Repo $issuesClosed++ } } } Write-Verbose ('[{0}] issue(s){1} created' -f $issuesCreated, $($WhatIfPreference ? ' would have been' : '')) Write-Verbose ('[{0}] issue(s){1} commented' -f $issuesCommented, $($WhatIfPreference ? ' would have been' : '')) Write-Verbose ('[{0}] issue(s){1} closed' -f $issuesClosed, $($WhatIfPreference ? ' would have been' : '')) }