Skip to content

Commit

Permalink
[repo] Auto label pull requests (#5681)
Browse files Browse the repository at this point in the history
  • Loading branch information
CodeBlanch authored Jun 10, 2024
1 parent fd18bb1 commit a763c0d
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 32 deletions.
42 changes: 35 additions & 7 deletions .github/workflows/add-labels.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,53 @@
name: 'Add labels for area found in bug issue descriptions'
name: 'Add labels to issues and pull requests'
on:
issues:
types: [opened]
types: [ opened ]

pull_request:
branches: [ 'main*' ]

permissions:
issues: write
pull-requests: write

jobs:
add-labels:
if: ${{ !github.event.issue.pull_request }}
add-labels-on-issues:
if: github.event_name == 'issues' && !github.event.issue.pull_request

runs-on: ubuntu-latest

steps:
- name: check out code
uses: actions/checkout@v4

- name: Add labels for areas found in bug issue descriptions
- name: Add labels for package found in bug issue descriptions
shell: pwsh
run: |
.\build\scripts\add-labels.ps1 -issueNumber $env:ISSUE_NUMBER -issueBody $env:ISSUE_BODY
Import-Module .\build\scripts\add-labels.psm1
AddLabelsOnIssuesForPackageFoundInBody `
-issueNumber ${{ github.event.issue.number }} `
-issueBody $env:ISSUE_BODY
env:
GH_TOKEN: ${{ github.token }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
ISSUE_BODY: ${{ github.event.issue.body }}

add-labels-on-pull-requests:
if: github.event_name == 'pull_request'

runs-on: ubuntu-latest

steps:
- name: check out code
uses: actions/checkout@v4

- name: Add labels for files changed on pull requests
shell: pwsh
run: |
Import-Module .\build\scripts\add-labels.psm1
AddLabelsOnPullRequestsBasedOnFilesChanged `
-pullRequestNumber ${{ github.event.pull_request.number }} `
-labelPackagePrefix 'pkg:'
env:
GH_TOKEN: ${{ github.token }}
2 changes: 1 addition & 1 deletion .github/workflows/post-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
&& github.event.issue.locked == true
&& github.event.comment.user.login != needs.automation.outputs.username
&& contains(github.event.comment.body, '/PushPackages')
&& startsWith(github.event.issue.title, '[repo] Prepare release ')
&& startsWith(github.event.issue.title, '[release] Prepare release ')
&& github.event.issue.pull_request.merged_at
&& needs.automation.outputs.enabled
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/prepare-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ jobs:
&& github.event.action == 'closed'
&& github.event.pull_request.user.login == needs.automation.outputs.username
&& github.event.pull_request.merged == true
&& startsWith(github.event.pull_request.title, '[repo] Prepare release ')
&& startsWith(github.event.pull_request.title, '[release] Prepare release ')
&& needs.automation.outputs.enabled
env:
Expand Down Expand Up @@ -100,7 +100,7 @@ jobs:
&& github.event.issue.locked == true
&& github.event.comment.user.login != needs.automation.outputs.username
&& contains(github.event.comment.body, '/CreateReleaseTag')
&& startsWith(github.event.issue.title, '[repo] Prepare release ')
&& startsWith(github.event.issue.title, '[release] Prepare release ')
&& github.event.issue.pull_request.merged_at
&& needs.automation.outputs.enabled
Expand Down
2 changes: 1 addition & 1 deletion OpenTelemetry.sln
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TagWriter", "TagWriter", "{
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{44982E0D-C8C6-42DC-9F8F-714981F27CE6}"
ProjectSection(SolutionItems) = preProject
build\scripts\add-labels.ps1 = build\scripts\add-labels.ps1
build\scripts\add-labels.psm1 = build\scripts\add-labels.psm1
build\scripts\finalize-publicapi.ps1 = build\scripts\finalize-publicapi.ps1
build\scripts\post-release.psm1 = build\scripts\post-release.psm1
build\scripts\prepare-release.psm1 = build\scripts\prepare-release.psm1
Expand Down
12 changes: 0 additions & 12 deletions build/scripts/add-labels.ps1

This file was deleted.

148 changes: 148 additions & 0 deletions build/scripts/add-labels.psm1
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
function AddLabelsOnIssuesForPackageFoundInBody {
param(
[Parameter(Mandatory=$true)][int]$issueNumber,
[Parameter(Mandatory=$true)][string]$issueBody
)

$match = [regex]::Match($issueBody, '^[#]+ Package\s*(OpenTelemetry(?:\.\w+)*)')
if ($match.Success -eq $false)
{
Return
}

gh issue edit $issueNumber --add-label $("pkg:" + $match.Groups[1].Value)
}

Export-ModuleMember -Function AddLabelsOnIssuesForPackageFoundInBody

function AddLabelsOnPullRequestsBasedOnFilesChanged {
param(
[Parameter(Mandatory=$true)][int]$pullRequestNumber,
[Parameter(Mandatory=$true)][string]$labelPackagePrefix # 'pkg:' on main repo, 'comp:' on contrib repo
)

# Note: This function is intended to work on main repo and on contrib. Please
# keep them in sync.

$repoLabels = gh label list --json name,id | ConvertFrom-Json

$filesChangedOnPullRequest = gh pr diff $pullRequestNumber --name-only

$labelsOnPullRequest = (gh pr view $pullRequestNumber --json labels | ConvertFrom-Json).labels

$visitedProjects = New-Object System.Collections.Generic.HashSet[string]
$labelsToAdd = New-Object System.Collections.Generic.HashSet[string]
$labelsToRemove = New-Object System.Collections.Generic.HashSet[string]

# Note: perf label may be added but it is kind of a guess so we don't remove
# it automatically in order to also allow manual inclusion after reviewing files
$managedLabels = 'infra', 'documentation', 'dependencies'
$rootInfraFiles = 'global.json', 'NuGet.config', 'codeowners'
$documentationFiles = 'readme.md', 'contributing.md', 'releasing.md', 'versioning.md'

foreach ($fileChanged in $filesChangedOnPullRequest)
{
$fileChanged = $fileChanged.ToLower()
$fullFileName = [System.IO.Path]::GetFileName($fileChanged)
$fileName = [System.IO.Path]::GetFileNameWithoutExtension($fileChanged)
$fileExtension = [System.IO.Path]::GetExtension($fileChanged)

if ($fileChanged.StartsWith('src/') -or $fileChanged.StartsWith('test/'))
{
$match = [regex]::Match($fileChanged, '^(?:(?:src)|(?:test))\/(.*?)\/.+$')
if ($match.Success -eq $false)
{
continue
}
$rawProjectName = $match.Groups[1].Value
if ($rawProjectName.Contains(".benchmarks") -or $rawProjectName.Contains(".stress"))
{
$added = $labelsToAdd.Add("perf")
}

$projectName = $rawProjectName.Replace(".tests", "").Replace(".benchmarks", "").Replace(".stress", "")
if ($visitedProjects.Contains($projectName))
{
continue
}

$added = $visitedProjects.Add($projectName);

foreach ($repoLabel in $repoLabels)
{
if ($repoLabel.name.StartsWith($labelPackagePrefix))
{
$package = $repoLabel.name.Substring($labelPackagePrefix.Length).ToLower()
if ($package.StartsWith('opentelemetry') -eq $false)
{
# Note: On contrib labels don't have "OpenTelemetry." prefix
$package = 'opentelemetry.' + $package
}
if ($package -eq $projectName)
{
$added = $labelsToAdd.Add($repoLabel.name)
break
}
}
}
}

if ($documentationFiles.Contains($fullFileName) -or
$fileChanged.StartsWith('docs/') -or
$fileChanged.StartsWith('examples/'))
{
$added = $labelsToAdd.Add("documentation")
}

if ($fileChanged.StartsWith('build/') -or
$fileChanged.StartsWith('.github/') -or
$rootInfraFiles.Contains($fullFileName) -or
$fileExtension -eq ".props" -or
$fileExtension -eq ".targets" -or
$fileChanged.StartsWith('test\openTelemetry.aotcompatibility'))
{
$added = $labelsToAdd.Add("infra")
}

if ($fileChanged.StartsWith('test\benchmarks'))
{
$added = $labelsToAdd.Add("perf")
}

if ($fullFileName -eq 'directory.packages.props')
{
$added = $labelsToAdd.Add("dependencies")
}
}

foreach ($labelOnPullRequest in $labelsOnPullRequest)
{
if ($labelsToAdd.Contains($labelOnPullRequest.name))
{
$removed = $labelsToAdd.Remove($labelOnPullRequest.name)
}
elseif ($labelOnPullRequest.name.StartsWith($labelPackagePrefix) -or
$managedLabels.Contains($labelOnPullRequest.name))
{
$added = $labelsToRemove.Add($labelOnPullRequest.name)
}
}

if ($labelsToAdd.Count -gt 0)
{
foreach ($label in $labelsToAdd)
{
gh pr edit $pullRequestNumber --add-label $label
}
}

if ($labelsToRemove.Count -gt 0)
{
foreach ($label in $labelsToRemove)
{
gh pr edit $pullRequestNumber --remove-label $label
}
}
}

Export-ModuleMember -Function AddLabelsOnPullRequestsBasedOnFilesChanged
10 changes: 5 additions & 5 deletions build/scripts/post-release.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ function TryPostPackagesReadyNoticeOnPrepareReleasePullRequest {

foreach ($pr in $prListResponse)
{
if ($pr.author.login -ne $botUserName -or $pr.title -ne "[repo] Prepare release $tag")
if ($pr.author.login -ne $botUserName -or $pr.title -ne "[release] Prepare release $tag")
{
continue
}
Expand Down Expand Up @@ -169,7 +169,7 @@ function PushPackagesPublishReleaseUnlockAndPostNoticeOnPrepareReleasePullReques
throw 'PR author was unexpected'
}

$match = [regex]::Match($prViewResponse.title, '^\[repo\] Prepare release (.*)$')
$match = [regex]::Match($prViewResponse.title, '^\[release\] Prepare release (.*)$')
if ($match.Success -eq $false)
{
throw 'Could not parse tag from PR title'
Expand Down Expand Up @@ -302,11 +302,11 @@ Merge once packages are available on NuGet and the build passes.
"@

gh pr create `
--title "[repo] Core stable release $packageVersion updates" `
--title "[release] Core stable release $packageVersion updates" `
--body $body `
--base $targetBranch `
--head $branch `
--label infra
--label release
}

Export-ModuleMember -Function CreateStableVersionUpdatePullRequest
Expand Down Expand Up @@ -355,7 +355,7 @@ function TryPostReleasePublishedNoticeOnPrepareReleasePullRequest {

foreach ($pr in $prListResponse)
{
if ($pr.author.login -ne $botUserName -or $pr.title -ne "[repo] Prepare release $tag")
if ($pr.author.login -ne $botUserName -or $pr.title -ne "[release] Prepare release $tag")
{
continue
}
Expand Down
8 changes: 4 additions & 4 deletions build/scripts/prepare-release.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,11 @@ Note: This PR was opened automatically by the [prepare release workflow](https:/
}

gh pr create `
--title "[repo] Prepare release $tag" `
--title "[release] Prepare release $tag" `
--body $body `
--base $targetBranch `
--head $branch `
--label infra
--label release
}

Export-ModuleMember -Function CreatePullRequestToUpdateChangelogsAndPublicApis
Expand All @@ -82,7 +82,7 @@ function LockPullRequestAndPostNoticeToCreateReleaseTag {
throw 'PR author was unexpected'
}

$match = [regex]::Match($prViewResponse.title, '^\[repo\] Prepare release (.*)$')
$match = [regex]::Match($prViewResponse.title, '^\[release\] Prepare release (.*)$')
if ($match.Success -eq $false)
{
throw 'Could not parse tag from PR title'
Expand Down Expand Up @@ -126,7 +126,7 @@ function CreateReleaseTagAndPostNoticeOnPullRequest {
throw 'PR author was unexpected'
}

$match = [regex]::Match($prViewResponse.title, '^\[repo\] Prepare release (.*)$')
$match = [regex]::Match($prViewResponse.title, '^\[release\] Prepare release (.*)$')
if ($match.Success -eq $false)
{
throw 'Could not parse tag from PR title'
Expand Down

0 comments on commit a763c0d

Please sign in to comment.