Skip to content

Commit

Permalink
[repo] Release request issue template & automation (open-telemetry#2080)
Browse files Browse the repository at this point in the history
  • Loading branch information
CodeBlanch committed Sep 20, 2024
1 parent 88de33c commit c55961c
Show file tree
Hide file tree
Showing 4 changed files with 297 additions and 1 deletion.
81 changes: 81 additions & 0 deletions .github/ISSUE_TEMPLATE/release_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
name: Release request
title: "[release request] "
description: Request a release for a component
labels: ["release"]
body:
- type: markdown
attributes:
value: |
Fill out this form to request a release of one of the components in this repository.
- type: dropdown
id: component
attributes:
label: Component
description: Which component does this release request concern?
multiple: false
options:
- OpenTelemetry.Exporter.Geneva
- OpenTelemetry.Exporter.InfluxDB
- OpenTelemetry.Exporter.Instana
- OpenTelemetry.Exporter.OneCollector
- OpenTelemetry.Exporter.Stackdriver
- OpenTelemetry.Extensions
- OpenTelemetry.Extensions.AWS
- OpenTelemetry.Extensions.Enrichment
- OpenTelemetry.Instrumentation.AspNet
- OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule
- OpenTelemetry.Instrumentation.AspNetCore
- OpenTelemetry.Instrumentation.AWS
- OpenTelemetry.Instrumentation.AWSLambda
- OpenTelemetry.Instrumentation.Cassandra
- OpenTelemetry.Instrumentation.ConfluentKafka
- OpenTelemetry.Instrumentation.ElasticsearchClient
- OpenTelemetry.Instrumentation.EntityFrameworkCore
- OpenTelemetry.Instrumentation.EventCounters
- OpenTelemetry.Instrumentation.GrpcCore
- OpenTelemetry.Instrumentation.GrpcNetClient
- OpenTelemetry.Instrumentation.Hangfire
- OpenTelemetry.Instrumentation.Http
- OpenTelemetry.Instrumentation.MassTransit
- OpenTelemetry.Instrumentation.MySqlData
- OpenTelemetry.Instrumentation.Owin
- OpenTelemetry.Instrumentation.Process
- OpenTelemetry.Instrumentation.Quartz
- OpenTelemetry.Instrumentation.Runtime
- OpenTelemetry.Instrumentation.SqlClient
- OpenTelemetry.Instrumentation.StackExchangeRedis
- OpenTelemetry.Instrumentation.Wcf
- OpenTelemetry.PersistentStorage.Abstractions
- OpenTelemetry.PersistentStorage.FileSystem
- OpenTelemetry.Resources.AWS
- OpenTelemetry.Resources.Azure
- OpenTelemetry.Resources.Container
- OpenTelemetry.Resources.Gcp
- OpenTelemetry.Resources.Host
- OpenTelemetry.Resources.OperatingSystem
- OpenTelemetry.Resources.Process
- OpenTelemetry.Resources.ProcessRuntime
- OpenTelemetry.Sampler.AWS
- OpenTelemetry.SemanticConventions
validations:
required: true

- type: input
attributes:
label: Version
description: |
What is the requested version for the release?
Version must specify [Major].[Minor].[Patch] and may also include prerelease information -[alpha|beta|rc].[Increment].
Examples:
* 1.9.0
* 1.10.0-rc.1
* 1.12.0-beta.2
* 0.2.0-alpha.3
validations:
required: true

- type: textarea
attributes:
label: Additional context
description: Any additional information you think may be relevant to this release request.
55 changes: 55 additions & 0 deletions .github/workflows/prepare-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,20 @@ on:
type: string
description: 'Release version'
required: true
releaseIssue:
type: string
description: 'Release request issue'
required: false

pull_request:
types:
- closed

issues:
types:
- opened
- edited

issue_comment:
types:
- created
Expand Down Expand Up @@ -95,6 +104,7 @@ jobs:
-component '${{ inputs.component }}' `
-version '${{ inputs.version }}' `
-requestedByUserName '${{ github.event.sender.login }}' `
-releaseIssue '${{ inputs.releaseIssue }}' `
-targetBranch '${{ github.ref_name }}' `
-gitUserName '${{ needs.automation.outputs.username }}' `
-gitUserEmail '${{ needs.automation.outputs.email }}'
Expand Down Expand Up @@ -209,3 +219,48 @@ jobs:
-commentUserName '${{ github.event.comment.user.login }}' `
-gitUserName '${{ needs.automation.outputs.username }}' `
-gitUserEmail '${{ needs.automation.outputs.email }}'
process-release-request-issue:
runs-on: ubuntu-latest

needs: automation

if: |
startsWith(github.event.issue.title, '[release request] ')
&& github.event.issue.pull_request == null
&& needs.automation.outputs.enabled
&& (
(github.event_name == 'issues')
||
(github.event_name == 'issue_comment'
&& github.event.issue.state == 'open'
&& contains(github.event.comment.body, '/PrepareRelease')
&& github.event.comment.user.login != needs.automation.outputs.username)
)
env:
GH_TOKEN: ${{ secrets[needs.automation.outputs.token-secret-name] }}

steps:
- name: check out code
uses: actions/checkout@v4
with:
token: ${{ secrets[needs.automation.outputs.token-secret-name] }}

- name: Process release request issue being opened or commented
shell: pwsh
run: |
Import-Module .\build\scripts\prepare-release.psm1
TagCodeOwnersOnOrRunWorkflowForRequestReleaseIssue `
-gitRepository '${{ github.repository }}' `
-targetBranch '${{ github.event.repository.default_branch }}' `
-triggeringEventName '${{ github.event_name }}' `
-approvingGroups '@${{ github.repository_owner }}/dotnet-approvers @${{ github.repository_owner }}/dotnet-maintainers' `
-requestedByUserName '${{ github.event.comment.user.login || github.event.sender.login }}' `
-issueNumber '${{ github.event.issue.number }}' `
-issueBody $env:ISSUE_BODY `
-gitUserName '${{ needs.automation.outputs.username }}' `
-gitUserEmail '${{ needs.automation.outputs.email }}'
env:
ISSUE_BODY: ${{ github.event.issue.body }}
161 changes: 160 additions & 1 deletion build/scripts/prepare-release.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ function CreatePullRequestToUpdateChangelogsAndPublicApis {
[Parameter(Mandatory=$true)][string]$component,
[Parameter(Mandatory=$true)][string]$version,
[Parameter(Mandatory=$true)][string]$requestedByUserName,
[Parameter()][string]$releaseIssue,
[Parameter()][string]$targetBranch="main",
[Parameter()][string]$gitUserName,
[Parameter()][string]$gitUserEmail
Expand Down Expand Up @@ -42,10 +43,19 @@ function CreatePullRequestToUpdateChangelogsAndPublicApis {
throw 'git switch failure'
}

if ([string]::IsNullOrEmpty($releaseIssue) -eq $false)
{
$issueText =
@"
Release request: #$releaseIssue
"@
}

$body =
@"
Note: This PR was opened automatically by the [prepare release workflow](https://github.com/$gitRepository/actions/workflows/prepare-release.yml).
$issueText
Requested by: @$requestedByUserName
## Changes
Expand Down Expand Up @@ -304,3 +314,152 @@ Released $(Get-Date -UFormat '%Y-%b-%d')
}

Export-ModuleMember -Function UpdateChangelogReleaseDatesAndPostNoticeOnPullRequest

function TagCodeOwnersOnOrRunWorkflowForRequestReleaseIssue {
param(
[Parameter(Mandatory=$true)][string]$gitRepository,
[Parameter(Mandatory=$true)][string]$triggeringEventName,
[Parameter(Mandatory=$true)][string]$approvingGroups,
[Parameter(Mandatory=$true)][string]$requestedByUserName,
[Parameter(Mandatory=$true)][string]$issueNumber,
[Parameter(Mandatory=$true)][string]$issueBody,
[Parameter()][string]$targetBranch="main",
[Parameter()][string]$gitUserName,
[Parameter()][string]$gitUserEmail
)

$match = [regex]::Match($issueBody, '^[#]+ Component\s*(OpenTelemetry\.(?:.|\w+)+)$', [Text.RegularExpressions.RegexOptions]::Multiline)
if ($match.Success -eq $false)
{
Write-Host 'Component could not be parsed from body'
Return
}

$component = $match.Groups[1].Value.Trim()

$match = [regex]::Match($issueBody, '^[#]+ Version\s*(.*)$', [Text.RegularExpressions.RegexOptions]::Multiline)
if ($match.Success -eq $false)
{
Write-Host 'Version could not be parsed from body'
Return
}

$version = $match.Groups[1].Value.Trim()

$match = [regex]::Match($version, '^(\d+\.\d+\.\d+)(?:-((?:alpha)|(?:beta)|(?:rc))\.(\d+))?$')
if ($match.Success -eq $false)
{
gh issue comment $issueNumber `
--body "The version specified on the release request is invalid. Please create a new release request with a valid version or edit the description and set a valid version."
Return
}

$projectPath = "src/$component/$component.csproj"

if ((Test-Path -Path $projectPath) -eq $false)
{
gh issue comment $issueNumber `
--body "I couldn't find the project file for the requested component. Please create a new release request and select a valid component or edit the description and set a valid component."
Return
}

$projectContent = Get-Content -Path $projectPath

$match = [regex]::Match($projectContent, '<MinVerTagPrefix>(.*)<\/MinVerTagPrefix>')
if ($match.Success -eq $false)
{
gh issue comment $issueNumber `
--body "I couldn't find ``MinVerTagPrefix`` in the project file for the requested component. Please create a new release request and select a valid component or edit the description and set a valid component."
Return
}

$minVerTagPrefix = $match.Groups[1].Value

$projectDirs = Get-ChildItem -Path src/**/*.csproj | Select-String "<MinVerTagPrefix>$minVerTagPrefix</MinVerTagPrefix>" -List | Select Path | Split-Path -Parent

$componentOwnersContent = Get-Content '.github/component_owners.yml' -Raw

$componentOwners = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase)

foreach ($projectDir in $projectDirs)
{
$projectName = [System.IO.Path]::GetFileName($projectDir)

$match = [regex]::Match($componentOwnersContent, "src\/$projectName\/:([\w\W\s]*?)src")
if ($match.Success -eq $true)
{
$matches = [regex]::Matches($match.Groups[1].Value, "-\s*(.*)")
foreach ($match in $matches)
{
$owner = $match.Groups[1].Value
$_ = $componentOwners.Add($owner.Trim())
}
}
}

$requestedByUserPermission = gh api "repos/$gitRepository/collaborators/$requestedByUserName/permission" | ConvertFrom-Json

$kickOffWorkflow = $false
$kickOffWorkflowReason = ''

if ($requestedByUserPermission.permission -eq 'admin' -or $requestedByUserPermission.permission -eq 'write')
{
$kickOffWorkflow = $true
$kickOffWorkflowReason = "@$requestedByUserName has collaborator or greater permission"
}
elseif ($componentOwners.Contains($requestedByUserName) -eq $true)
{
$kickOffWorkflow = $true
$kickOffWorkflowReason = "@$requestedByUserName is a component owner"
}

if ($kickOffWorkflow -eq $true)
{
CreatePullRequestToUpdateChangelogsAndPublicApis `
-gitRepository $gitRepository `
-component $component `
-version $version `
-requestedByUserName $requestedByUserName `
-releaseIssue $issueNumber `
-targetBranch $targetBranch `
-gitUserName $gitUserName `
-gitUserEmail $gitUserEmail

gh issue close $issueNumber `
--comment "I executed the prepare release script for ``$component`` version ``$version``` because $kickOffWorkflowReason."

return
}

if ($triggeringEventName -eq 'issues')
{
# Executed when issues are created or edited
$componentOwnerApprovers = ''
if ($componentOwners.Count -gt 0)
{
foreach ($componentOwner in $componentOwners)
{
$componentOwnerApprovers += "@$componentOwner "
}
}

$body =
@"
$componentOwnerApprovers$approvingGroups
Post a comment with "/PrepareRelease" in the body if you would like me to execute the prepare release script for the component and version listed in the description.
"@

gh issue comment $issueNumber --body $body
}
else {
# Executed when issues are commented with the /PrepareRelease command
if ($kickOffWorkflow -eq $false)
{
gh issue comment $issueNumber `
--body "I'm sorry @$requestedByUserName but you don't have permission to execute the prepare release script. Only maintainers, approvers, and/or owners of the component may use the `"/PrepareRelease`" command."
}
}
}

Export-ModuleMember -Function TagCodeOwnersOnOrRunWorkflowForRequestReleaseIssue
1 change: 1 addition & 0 deletions opentelemetry-dotnet-contrib.sln
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ISSUE_TEMPLATE", "ISSUE_TEM
ProjectSection(SolutionItems) = preProject
.github\ISSUE_TEMPLATE\bug_report.yml = .github\ISSUE_TEMPLATE\bug_report.yml
.github\ISSUE_TEMPLATE\feature_request.yml = .github\ISSUE_TEMPLATE\feature_request.yml
.github\ISSUE_TEMPLATE\release_request.yml = .github\ISSUE_TEMPLATE\release_request.yml
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.ConfluentKafka", "src\OpenTelemetry.Instrumentation.ConfluentKafka\OpenTelemetry.Instrumentation.ConfluentKafka.csproj", "{96341E23-990E-4144-A7E3-9EF0DAFF3232}"
Expand Down

0 comments on commit c55961c

Please sign in to comment.