.github/request-reviews.yml: Switch to pull_request_target
This change simply moves the trigger to `pull_request_target`. The rest of this message contains verbose details related to that. `pull_request_target` is used instead of `pull_request` since the default GitHub token cannot pick up write permissions with the `pull_request` type on PRs from public forks. Write permission is needed to add reviewrs. This was previously tested on an edk2 fork where PRs were not from other public forks into the fork being used for testing but directly on the fork itself. Because `pull_request_target` runs the pull request in the context of the base branch (not the PR branch) some logic needs slightly modified. The main change is that the GitHub context will no longer give the PR branch HEAD as the PR commit SHA (i.e. `github.event.pull_request.head.sha`). The SHA will be the base branch (`master`) SHA as that is what is checked out for the workflow run. SO, the actual PR SHA is now fetched separately. Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
This commit is contained in:
committed by
mergify[bot]
parent
7868d509dd
commit
0343e75233
82
.github/scripts/GitHub.py
vendored
82
.github/scripts/GitHub.py
vendored
@@ -39,37 +39,47 @@ def leave_pr_comment(
|
||||
response.raise_for_status()
|
||||
|
||||
|
||||
def get_reviewers_for_current_branch(
|
||||
workspace_path: str, maintainer_file_path: str, target_branch: str = "master"
|
||||
def get_reviewers_for_range(
|
||||
workspace_path: str,
|
||||
maintainer_file_path: str,
|
||||
range_start: str = "master",
|
||||
range_end: str = "HEAD",
|
||||
) -> List[str]:
|
||||
"""Get the reviewers for the current branch.
|
||||
|
||||
To get the reviewers for a single commit, set `range_start` and
|
||||
`range_end` to the commit SHA.
|
||||
|
||||
Args:
|
||||
workspace_path (str): The workspace path.
|
||||
maintainer_file_path (str): The maintainer file path.
|
||||
target_branch (str, optional): The name of the target branch that the
|
||||
current HEAD will merge to. Defaults to "master".
|
||||
range_start (str, optional): The range start ref. Defaults to "master".
|
||||
range_end (str, optional): The range end ref. Defaults to "HEAD".
|
||||
|
||||
Returns:
|
||||
List[str]: A list of GitHub usernames.
|
||||
"""
|
||||
|
||||
commit_stream_buffer = StringIO()
|
||||
cmd_ret = RunCmd(
|
||||
"git",
|
||||
f"log --format=format:%H {target_branch}..HEAD",
|
||||
workingdir=workspace_path,
|
||||
outstream=commit_stream_buffer,
|
||||
logging_level=logging.INFO,
|
||||
)
|
||||
if cmd_ret != 0:
|
||||
print(
|
||||
f"::error title=Commit Lookup Error!::Error getting branch commits: [{cmd_ret}]: {commit_stream_buffer.getvalue()}"
|
||||
if range_start == range_end:
|
||||
commits = [range_start]
|
||||
else:
|
||||
commit_stream_buffer = StringIO()
|
||||
cmd_ret = RunCmd(
|
||||
"git",
|
||||
f"log --format=format:%H {range_start}..{range_end}",
|
||||
workingdir=workspace_path,
|
||||
outstream=commit_stream_buffer,
|
||||
logging_level=logging.INFO,
|
||||
)
|
||||
return []
|
||||
if cmd_ret != 0:
|
||||
print(
|
||||
f"::error title=Commit Lookup Error!::Error getting branch commits: [{cmd_ret}]: {commit_stream_buffer.getvalue()}"
|
||||
)
|
||||
return []
|
||||
commits = commit_stream_buffer.getvalue().splitlines()
|
||||
|
||||
raw_reviewers = []
|
||||
for commit_sha in commit_stream_buffer.getvalue().splitlines():
|
||||
for commit_sha in commits:
|
||||
reviewer_stream_buffer = StringIO()
|
||||
cmd_ret = RunPythonScript(
|
||||
maintainer_file_path,
|
||||
@@ -104,6 +114,44 @@ def get_reviewers_for_current_branch(
|
||||
return reviewers
|
||||
|
||||
|
||||
def get_pr_sha(token: str, owner: str, repo: str, pr_number: str) -> str:
|
||||
"""Returns the commit SHA of given PR branch.
|
||||
|
||||
This returns the SHA of the merge commit that GitHub creates from a
|
||||
PR branch. This commit contains all of the files in the PR branch in
|
||||
a single commit.
|
||||
|
||||
Args:
|
||||
token (str): The GitHub token to use for authentication.
|
||||
owner (str): The GitHub owner (organization) name.
|
||||
repo (str): The GitHub repository name (e.g. 'edk2').
|
||||
pr_number (str): The pull request number.
|
||||
|
||||
Returns:
|
||||
str: The commit SHA of the PR branch. An empty string is returned
|
||||
if the request fails.
|
||||
"""
|
||||
url = f"https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {token}",
|
||||
"Accept": "application/vnd.github.v3+json",
|
||||
}
|
||||
response = requests.get(url, headers=headers)
|
||||
try:
|
||||
response.raise_for_status()
|
||||
except requests.exceptions.HTTPError:
|
||||
print(
|
||||
f"::error title=HTTP Error!::Error getting PR Commit Info: {response.reason}"
|
||||
)
|
||||
return ""
|
||||
|
||||
commit_sha = response.json()["merge_commit_sha"]
|
||||
|
||||
print(f"::debug title=PR {pr_number} Commit SHA::{commit_sha}")
|
||||
|
||||
return commit_sha
|
||||
|
||||
|
||||
def download_gh_file(github_url: str, local_path: str, token=None):
|
||||
"""Downloads a file from GitHub.
|
||||
|
||||
|
||||
27
.github/workflows/request-reviews.yml
vendored
27
.github/workflows/request-reviews.yml
vendored
@@ -11,7 +11,7 @@
|
||||
name: Add Pull Request Reviewers
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
pull_request_target:
|
||||
branches:
|
||||
- master
|
||||
types: [opened, ready_for_review, reopened, synchronize]
|
||||
@@ -55,15 +55,38 @@ jobs:
|
||||
TARGET_BRANCH: ${{ github.event.pull_request.base.ref }}
|
||||
WORKSPACE_PATH: ${{ github.workspace }}
|
||||
run: |
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
sys.path.append(os.path.join(os.environ['WORKSPACE_PATH'], ".github"))
|
||||
from edk2toollib.utility_functions import RunCmd
|
||||
from io import StringIO
|
||||
from scripts import GitHub
|
||||
|
||||
WORKSPACE_PATH = os.environ['WORKSPACE_PATH']
|
||||
GET_MAINTAINER_LOCAL_PATH = os.path.join(WORKSPACE_PATH, os.environ['GET_MAINTAINER_REL_PATH'])
|
||||
|
||||
reviewers = GitHub.get_reviewers_for_current_branch(WORKSPACE_PATH, GET_MAINTAINER_LOCAL_PATH, f"origin/{os.environ['TARGET_BRANCH']}")
|
||||
pr_commit_sha = GitHub.get_pr_sha(os.environ['GH_TOKEN'], os.environ['ORG_NAME'], os.environ['REPO_NAME'], os.environ['PR_NUMBER'])
|
||||
if not pr_commit_sha:
|
||||
sys.exit(1)
|
||||
|
||||
print(f"::notice title=PR Commit SHA::Looking at files in consolidated PR commit: {pr_commit_sha}")
|
||||
|
||||
out_stream_buffer = StringIO()
|
||||
cmd_ret = RunCmd(
|
||||
"git",
|
||||
f"fetch origin {pr_commit_sha}",
|
||||
workingdir=WORKSPACE_PATH,
|
||||
outstream=out_stream_buffer,
|
||||
logging_level=logging.INFO,
|
||||
)
|
||||
if cmd_ret != 0:
|
||||
print(
|
||||
f"::error title=Commit Fetch Error!::Error fetching PR commit: [{cmd_ret}]: {out_stream_buffer.getvalue()}"
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
reviewers = GitHub.get_reviewers_for_range(WORKSPACE_PATH, GET_MAINTAINER_LOCAL_PATH, pr_commit_sha, pr_commit_sha)
|
||||
if not reviewers:
|
||||
print("::notice title=No Reviewers Found!::No reviewers found for this PR.")
|
||||
sys.exit(1)
|
||||
|
||||
Reference in New Issue
Block a user