summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/actions/add-maintainers-as-reviewers/Dockerfile6
-rwxr-xr-x.github/actions/add-maintainers-as-reviewers/entrypoint.py85
2 files changed, 91 insertions, 0 deletions
diff --git a/.github/actions/add-maintainers-as-reviewers/Dockerfile b/.github/actions/add-maintainers-as-reviewers/Dockerfile
new file mode 100644
index 0000000000..9370cfed83
--- /dev/null
+++ b/.github/actions/add-maintainers-as-reviewers/Dockerfile
@@ -0,0 +1,6 @@
+FROM python:3.7-alpine
+
+RUN pip install pygithub
+
+ADD entrypoint.py /entrypoint.py
+ENTRYPOINT ["/entrypoint.py"]
diff --git a/.github/actions/add-maintainers-as-reviewers/entrypoint.py b/.github/actions/add-maintainers-as-reviewers/entrypoint.py
new file mode 100755
index 0000000000..53f7318f82
--- /dev/null
+++ b/.github/actions/add-maintainers-as-reviewers/entrypoint.py
@@ -0,0 +1,85 @@
+#!/usr/bin/env python
+#
+# Copyright 2013-2019 Lawrence Livermore National Security, LLC and other
+# Spack Project Developers. See the top-level COPYRIGHT file for details.
+#
+# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+
+"""Maintainer review action.
+
+This action checks which packages have changed in a PR, and adds their
+maintainers to the pull request for review.
+"""
+
+import json
+import os
+import re
+import subprocess
+
+from github import Github
+
+
+def spack(*args):
+ """Run the spack executable with arguments, and return the output split.
+
+ This does just enough to run `spack pkg` and `spack maintainers`, the
+ two commands used by this action.
+ """
+ github_workspace = os.environ['GITHUB_WORKSPACE']
+ spack = os.path.join(github_workspace, 'bin', 'spack')
+ output = subprocess.check_output([spack] + list(args))
+ split = re.split(r'\s*', output.decode('utf-8').strip())
+ return [s for s in split if s]
+
+
+def main():
+ # get these first so that we'll fail early
+ token = os.environ['GITHUB_TOKEN']
+ event_path = os.environ['GITHUB_EVENT_PATH']
+
+ with open(event_path) as file:
+ data = json.load(file)
+
+ # make sure it's a pull_request event
+ assert 'pull_request' in data
+
+ # only request reviews on open, edit, or reopen
+ action = data['action']
+ if action not in ('opened', 'edited', 'reopened'):
+ return
+
+ # get data from the event payload
+ pr_data = data['pull_request']
+ base_branch_name = pr_data['base']['ref']
+ full_repo_name = pr_data['base']['repo']['full_name']
+ pr_number = pr_data['number']
+ requested_reviewers = pr_data['requested_reviewers']
+ author = pr_data['user']['login']
+
+ # get a list of packages that this PR modified
+ changed_pkgs = spack(
+ 'pkg', 'changed', '--type', 'ac', '%s...' % base_branch_name)
+
+ # get maintainers for all modified packages
+ maintainers = set()
+ for pkg in changed_pkgs:
+ pkg_maintainers = set(spack('maintainers', pkg))
+ maintainers |= pkg_maintainers
+
+ # remove any maintainers who are already on the PR, and the author,
+ # as you can't review your own PR)
+ maintainers -= set(requested_reviewers)
+ maintainers -= set([author])
+
+ if not maintainers:
+ return
+
+ # request reviews from each maintainer
+ gh = Github(token)
+ repo = gh.get_repo(full_repo_name)
+ pr = repo.get_pull(pr_number)
+ pr.create_review_request(list(maintainers))
+
+
+if __name__ == "__main__":
+ main()