| ## @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() |