Handle milestoned and labeled events independently (#31034)

This commit is contained in:
Felix Becker 2022-02-10 20:45:05 -08:00 committed by GitHub
parent f65d092932
commit aa368f7a05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 62 additions and 54 deletions

View File

@ -34,4 +34,9 @@ jobs:
$PSDefaultParameterValues['*GitHub*:Token'] = ConvertTo-SecureString -String $env:GITHUB_TOKEN -AsPlainText -Force
./.github/workflows/update-project-items.ps1 -ProjectNodeId 'MDExOlByb2plY3ROZXh0MzI3Ng==' -TeamLabel 'team/code-insights' -SlackChannel '#code-insights-planning' -SlackWebhookUri $env:SLACK_WEBHOOK_URI
./.github/workflows/update-project-items.ps1 `
-ProjectNodeId 'MDExOlByb2plY3ROZXh0MzI3Ng==' `
-TeamLabel 'team/code-insights' `
-TeamIterationMilestonePattern '^Insights iteration' `
-SlackChannel '#code-insights-planning' `
-SlackWebhookUri $env:SLACK_WEBHOOK_URI

View File

@ -6,10 +6,15 @@ param(
[Parameter(Mandatory)]
[string] $ProjectNodeId,
# The team/* label to filter issues/PRs by. All issues/PRs that don't have this label will be ignored.
# The team/* label to filter issues/PRs by. `labeled` events for other labels than this label will be ignored.
[Parameter(Mandatory)]
[string] $TeamLabel,
# A regular expression pattern to match milestone titles by.
# All `milestoned` events not matching the pattern will be ignored.
[Parameter(Mandatory)]
[regex] $TeamIterationMilestonePattern,
# Previously set up webhook URI from https://sourcegraph.slack.com/apps/A0F7XDUAZ
[Parameter(Mandatory)]
[string] $SlackWebhookUri,
@ -19,79 +24,74 @@ param(
[string] $SlackChannel
)
# Regex for extracting the "Closes #1234" pattern in GitHub PR descriptions
$fixIssuePattern = "(?:close|fixe?|resolve)(?:[sd])? (?:#|(?<owner>[\w_-]+)/(?<repo>[\w_-]+)#|https://github\.com/(?<owner>[\w_-]+)/(?<repo>[\w_-]+)/issues/)(?<number>\d+)"
switch ($github.event_name) {
'issues' {
if (-not ($github.event.issue.labels | Where-Object { $_.name -eq $TeamLabel })) {
Write-Information "Issue does not have $TeamLabel label, exiting."
return
}
Write-Information "Issue was $($github.event.action)"
if ($github.event.action -in 'labeled', 'milestoned') {
# If issue was labeled, make sure to only consider the team label being added (don't send a Slack message for every label added).
if ($github.event.action -eq 'labeled' -and $github.event.label.name -ne $TeamLabel) {
if ($github.event.action -eq 'labeled') {
# If issue was labeled, make sure to only consider the team label being added.
if ($github.event.label.name -ne $TeamLabel) {
Write-Information "Labeled with non-team label ($($github.event.label.name)), exiting."
return
}
# If issue was milestoned, make sure to only consider iteration milestones
if ($github.event.action -eq 'milestoned' -and $github.event.issue.milestone.title -notmatch "iteration") {
Write-Information "Milestoned with non-iteration milestone ($($github.event.issue.milestone.title)), exiting."
# Add issue to the team project board. Idempotent.
[pscustomobject]$github.event.issue | Add-GitHubBetaProjectItem -ProjectNodeId $ProjectNodeId
} elseif ($github.event.action -eq 'milestoned') {
# If issue was milestoned, make sure to only consider team iteration milestones
if ($github.event.issue.milestone.title -notmatch $TeamIterationMilestonePattern) {
Write-Information "Milestoned with non-matching milestone ($($github.event.issue.milestone.title)), exiting. Pattern: $TeamIterationMilestonePattern"
return
}
# If team label was added, add to project board
# If added to an iteration, update status and set "proposed by" to the event actor
# Idempotent, will return the item if already exists in the board (this is fine because we checked for the team label)
# Add issue to the team project board. Idempotent, will return the item if already exists in the board.
$item = [pscustomobject]$github.event.issue | Add-GitHubBetaProjectItem -ProjectNodeId $ProjectNodeId
if ($github.event.issue.milestone) {
$proposer = $github.event.sender.login
Write-Information "Updating issue as 'Proposed for iteration' by @$proposer"
# Update status and set "Proposed by" to the event actor
$item |
Set-GitHubBetaProjectItemField -Name 'Status' -Value 'Proposed for iteration' |
Set-GitHubBetaProjectItemField -Name 'Proposed by' -Value $proposer
$proposer = $github.event.sender.login
Write-Information "Updating issue as 'Proposed for iteration' by @$proposer"
$item |
Set-GitHubBetaProjectItemField -Name 'Status' -Value 'Proposed for iteration' |
Set-GitHubBetaProjectItemField -Name 'Proposed by' -Value $proposer
# Post Slack message
# Post Slack message
$stats = Find-GitHubIssue "org:sourcegraph is:issue milestone:`"$($item.content.milestone.title)`"" |
Get-GitHubBetaProjectItem |
Where-Object { $_.project.id -eq $ProjectNodeId -and $_.Fields['Status'] -ne 'Done' } |
ForEach-Object { $_.Fields['Size 🔵'] ?? 1 } |
Measure-Object -AllStats
$stats = Find-GitHubIssue "org:sourcegraph is:issue milestone:`"$($item.content.milestone.title)`"" |
Get-GitHubBetaProjectItem |
Where-Object { $_.project.id -eq $ProjectNodeId -and $_.Fields['Status'] -ne 'Done' } |
ForEach-Object { $_.Fields['Size 🔵'] ?? 1 } |
Measure-Object -AllStats
$color = if ($item.content.state -eq 'OPEN') { '#1A7F37' } else { '#8250DF' }
$color = if ($item.content.state -eq 'OPEN') { '#1A7F37' } else { '#8250DF' }
$message = "*$proposer* proposed a new issue for iteration <$($item.content.milestone.url)|$($item.content.milestone.title)>.`n" +
"There are now $($stats.Sum) points of open issues in the iteration."
$message = "*$proposer* proposed a new issue for iteration <$($item.content.milestone.url)|$($item.content.milestone.title)>.`n" +
"There are now $($stats.Sum) points of open issues in the iteration."
# Plain text fallback for contexts without formatting capability, e.g. push notifications
$fallback = "*$proposer* proposed a new issue for iteration $($item.content.milestone.title): #$($item.content.number) $($item.content.title). There are now $($stats.Sum) points of open issues in the iteration."
# Plain text fallback for contexts without formatting capability, e.g. push notifications
$fallback = "*$proposer* proposed a new issue for iteration $($item.content.milestone.title): #$($item.content.number) $($item.content.title). There are now $($stats.Sum) points of open issues in the iteration."
New-SlackMessageAttachment `
-Pretext $message `
-Color $color `
-AuthorName $item.content.author.login `
-AuthorIcon $item.content.author.avatarUrl `
-Title "#$($item.content.number) $($item.content.title)" `
-TitleLink $item.content.url `
-Text $item.content.bodyText.Substring(0, [System.Math]::Min(1000, $item.content.bodyText.Length)) `
-Fields @(
@{ title = 'Size'; value = $item.Fields['Size 🔵']; short = $true },
@{ title = 'Importance'; value = $item.Fields['Importance']; short = $true },
@{ title = 'Labels'; value = $item.content.labels | ForEach-Object name | Join-String -Separator ', '; short = $true },
@{ title = 'Assignee'; value = $item.content.assignees | ForEach-Object login | Join-String -Separator ', '; short = $true }
) `
-Fallback $fallback |
New-SlackMessage -Username 'Iteration Bot' -IconEmoji ':robot:' -Channel $SlackChannel |
Send-SlackMessage -Uri $SlackWebhookUri
New-SlackMessageAttachment `
-Pretext $message `
-Color $color `
-AuthorName $item.content.author.login `
-AuthorIcon $item.content.author.avatarUrl `
-Title "#$($item.content.number) $($item.content.title)" `
-TitleLink $item.content.url `
-Text $item.content.bodyText.Substring(0, [System.Math]::Min(1000, $item.content.bodyText.Length)) `
-Fields @(
@{ title = 'Size'; value = $item.Fields['Size 🔵']; short = $true },
@{ title = 'Importance'; value = $item.Fields['Importance']; short = $true },
@{ title = 'Labels'; value = $item.content.labels | ForEach-Object name | Join-String -Separator ', '; short = $true },
@{ title = 'Assignee'; value = $item.content.assignees | ForEach-Object login | Join-String -Separator ', '; short = $true }
) `
-Fallback $fallback |
New-SlackMessage -Username 'Iteration Bot' -IconEmoji ':robot:' -Channel $SlackChannel |
Send-SlackMessage -Uri $SlackWebhookUri
}
} else {
# If issue was closed or reopened, update Status column
$status = if ($github.event.action -eq 'closed') { 'Done' } else { 'In Progress' }
@ -114,6 +114,9 @@ switch ($github.event_name) {
$status = if ($pr.draft) { 'In Progress' } else { 'In Review' }
# Regex for extracting the "Closes #1234" pattern in GitHub PR descriptions
$fixIssuePattern = "(?:close|fixe?|resolve)(?:[sd])? (?:#|(?<owner>[\w_-]+)/(?<repo>[\w_-]+)#|https://github\.com/(?<owner>[\w_-]+)/(?<repo>[\w_-]+)/issues/)(?<number>\d+)"
# Get fixed issues from the PR description
[regex]::Matches($pr.body, $fixIssuePattern, [Text.RegularExpressions.RegexOptions]::IgnoreCase) |
ForEach-Object {