From 51ada84cd57c5ef6c75a72aeb002226cf9180b21 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Fri, 2 Aug 2024 15:35:08 -0400 Subject: [PATCH] .github/request-reviews.yml: Move workflow Py code to file To make the Python code used within the action more mantainable over time, it is moved to a standalone script in .github/scripts. No functional changes are made to the workflow itself. Signed-off-by: Michael Kubacki --- .github/scripts/RequestPrReviewers.py | 98 +++++++++++++++++++++++++++ .github/workflows/request-reviews.yml | 64 +---------------- 2 files changed, 99 insertions(+), 63 deletions(-) create mode 100644 .github/scripts/RequestPrReviewers.py diff --git a/.github/scripts/RequestPrReviewers.py b/.github/scripts/RequestPrReviewers.py new file mode 100644 index 0000000000..fdff657617 --- /dev/null +++ b/.github/scripts/RequestPrReviewers.py @@ -0,0 +1,98 @@ +## @file +# Used in a CI workflow to request reviewers for a pull request. +# +# Refer to the following link for a list of pre-defined GitHub workflow +# environment variables: +# https://docs.github.com/actions/reference/environment-variables +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +import git +import GitHub +import os +import sys + + +"""Request Pull Request Reviewers Helpers""" + + +def request_pr_reviewers(): + """Request pull request reviewers for a GitHub PR. + + This function is intended to be used in a GitHub Actions workflow to + request reviewers for a pull request triggered by a GitHub event. The + function makes assumptions about GitHub workflow environment variables and + the pull request context in which it is run. + + The function will exit with a non-zero status indicating an error if a + critical error occurs during execution so the workflow fails. + + The following environment variables are expected to be set before calling + this function. The recommend GitHub context values are show for reference: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ORG_NAME: ${{ github.repository_owner }} + PR_NUMBER: ${{ github.event.number}} + REPO_NAME: ${{ github.event.pull_request.base.repo.name }} + TARGET_BRANCH: ${{ github.event.pull_request.base.ref }} + WORKSPACE_PATH: ${{ github.workspace }} + """ + WORKSPACE_PATH = os.environ["WORKSPACE_PATH"] + GET_MAINTAINER_LOCAL_PATH = os.path.join( + WORKSPACE_PATH, os.environ["GET_MAINTAINER_REL_PATH"] + ) + + # Step 1: Get the GitHub created PR commit SHA (contains all changes in a single commit) + pr_commit_sha = GitHub.get_pr_sha( + os.environ["GH_TOKEN"], + os.environ["ORG_NAME"], + os.environ["REPO_NAME"], + int(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}" + ) + + # Step 2: Fetch only the PR commit to get the files changed in the PR + git.Repo(WORKSPACE_PATH).remotes.origin.fetch(pr_commit_sha, depth=1) + + # Step 3: Get the list of reviewers for the PR + 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 New Reviewers Found!::No reviewers found for this PR.") + sys.exit(0) + + print( + f"::notice title=Preliminary Reviewer List::Total reviewer candidates for " + f"PR {os.environ['PR_NUMBER']}: {', '.join(reviewers)}" + ) + + # Step 4: Add the reviewers to the PR + # Note the final requested reviewer list in the workflow run for reference + new_reviewers = GitHub.add_reviewers_to_pr( + os.environ["GH_TOKEN"], + os.environ["ORG_NAME"], + os.environ["REPO_NAME"], + int(os.environ["PR_NUMBER"]), + reviewers, + ) + if new_reviewers: + print( + f"::notice title=New Reviewers Added::New reviewers requested for PR " + f"{os.environ['PR_NUMBER']}: {', '.join(new_reviewers)}" + ) + else: + print( + "::notice title=No New Reviewers Added::No reviewers were found that " + "should be newly requested." + ) + + +if __name__ == '__main__': + request_pr_reviewers() diff --git a/.github/workflows/request-reviews.yml b/.github/workflows/request-reviews.yml index 15de2cb0e5..13330561f2 100644 --- a/.github/workflows/request-reviews.yml +++ b/.github/workflows/request-reviews.yml @@ -56,7 +56,6 @@ jobs: run: pip install -r .github/scripts/requirements.txt --upgrade - name: Add Reviewers to Pull Request - shell: python env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} ORG_NAME: ${{ github.repository_owner }} @@ -64,65 +63,4 @@ jobs: REPO_NAME: ${{ github.event.pull_request.base.repo.name }} TARGET_BRANCH: ${{ github.event.pull_request.base.ref }} WORKSPACE_PATH: ${{ github.workspace }} - run: | - import git - import os - import sys - - sys.path.append(os.path.join(os.environ["WORKSPACE_PATH"], ".github")) - 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"] - ) - - # Step 1: Get the GitHub created PR commit SHA (contains all changes in a single commit) - pr_commit_sha = GitHub.get_pr_sha( - os.environ["GH_TOKEN"], - os.environ["ORG_NAME"], - os.environ["REPO_NAME"], - int(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}" - ) - - # Step 2: Fetch only the PR commit to get the files changed in the PR - git.Repo(WORKSPACE_PATH).remotes.origin.fetch(pr_commit_sha, depth=1) - - # Step 3: Get the list of reviewers for the PR - 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 New Reviewers Found!::No reviewers found for this PR.") - sys.exit(0) - - print( - f"::notice title=Preliminary Reviewer List::Total reviewer candidates for " - f"PR {os.environ['PR_NUMBER']}: {', '.join(reviewers)}" - ) - - # Step 4: Add the reviewers to the PR - # Note the final requested reviewer list in the workflow run for reference - new_reviewers = GitHub.add_reviewers_to_pr( - os.environ["GH_TOKEN"], - os.environ["ORG_NAME"], - os.environ["REPO_NAME"], - int(os.environ["PR_NUMBER"]), - reviewers, - ) - if new_reviewers: - print( - f"::notice title=New Reviewers Added::New reviewers requested for PR " - f"{os.environ['PR_NUMBER']}: {', '.join(new_reviewers)}" - ) - else: - print( - "::notice title=No New Reviewers Added::No reviewers were found that " - "should be newly requested." - ) + run: python .github/scripts/RequestPrReviewers.py