-
Notifications
You must be signed in to change notification settings - Fork 384
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Workflow that runs each day and creates new issues for failing …
…AVM pipelines (#783) If a AVM pipeline fails, a issue will be created and the failed run is added to the issue. --------- Co-authored-by: Erika Gressi <[email protected]>
- Loading branch information
Showing
2 changed files
with
163 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
name: "avm.platform.manage-workflow-issue" | ||
|
||
on: | ||
schedule: | ||
- cron: "30 5 * * *" # Every day at 5:30 am | ||
|
||
jobs: | ||
manage-issues: | ||
runs-on: ubuntu-latest | ||
permissions: | ||
issues: write | ||
steps: | ||
- name: "Checkout" | ||
uses: actions/checkout@v4 | ||
with: | ||
fetch-depth: 0 | ||
- env: | ||
GH_TOKEN: ${{ github.token }} | ||
name: Manage issues | ||
shell: pwsh | ||
run: | | ||
# Load used functions | ||
. (Join-Path $env:GITHUB_WORKSPACE 'avm' 'utilities' 'pipelines' 'platform' 'Set-AvmGithubIssueForWorkflow.ps1') | ||
$functionInput = @{ | ||
Repo = "${{ github.repository_owner }}/${{ github.event.repository.name }}" | ||
LimitNumberOfRuns = 500 | ||
LimitInDays = 2 | ||
IgnoreWorkflows = @() | ||
} | ||
Write-Verbose "Invoke task with" -Verbose | ||
Write-Verbose ($functionInput | ConvertTo-Json | Out-String) -Verbose | ||
Set-AvmGithubIssueForWorkflow @functionInput -Verbose # -WhatIf |
128 changes: 128 additions & 0 deletions
128
avm/utilities/pipelines/platform/Set-AvmGithubIssueForWorkflow.ps1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
<# | ||
.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-AvmGithubIssueForWorkflow -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-AvmGithubIssueForWorkflow { | ||
[CmdletBinding(SupportsShouldProcess)] | ||
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 'Type: AVM :a: :v: :m:,Type: Bug :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 ($run.workflowName.StartsWith("avm.")) { | ||
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 'Type: AVM :a: :v: :m:,Type: Bug :bug:' --repo $Repo | ||
} | ||
|
||
$issuesCreated++ | ||
} | ||
else { | ||
$issue = ($issues | Where-Object { $_.title -eq $issueName })[0] | ||
|
||
if (-not $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 (-not $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' : '')) | ||
} |