1#!/usr/bin/env bash
2
3# Request reviewers for a PR, reading line-separated usernames on stdin,
4# filtering for valid reviewers before using the API endpoint to request reviews:
5# https://docs.github.com/en/rest/pulls/review-requests?apiVersion=2022-11-28#request-reviewers-for-a-pull-request
6
7set -euo pipefail
8
9tmp=$(mktemp -d)
10trap 'rm -rf "$tmp"' exit
11
12log() {
13 echo "$@" >&2
14}
15
16effect() {
17 if [[ -n "${DRY_MODE:-}" ]]; then
18 log "Skipping in dry mode:" "${@@Q}"
19 else
20 "$@"
21 fi
22}
23
24if (( "$#" < 3 )); then
25 log "Usage: $0 BASE_REPO PR_NUMBER PR_AUTHOR"
26 exit 1
27fi
28
29baseRepo=$1
30prNumber=$2
31prAuthor=$3
32
33tmp=$(mktemp -d)
34trap 'rm -rf "$tmp"' exit
35
36declare -A users=()
37while read -r handle && [[ -n "$handle" ]]; do
38 users[${handle,,}]=
39done
40
41# Cannot request a review from the author
42if [[ -v users[${prAuthor,,}] ]]; then
43 log "One or more files are owned by the PR author, ignoring"
44 unset 'users[${prAuthor,,}]'
45fi
46
47gh api \
48 -H "Accept: application/vnd.github+json" \
49 -H "X-GitHub-Api-Version: 2022-11-28" \
50 "/repos/$baseRepo/pulls/$prNumber/reviews" \
51 --jq '.[].user.login' > "$tmp/already-reviewed-by"
52
53# And we don't want to rerequest reviews from people who already reviewed
54while read -r user; do
55 if [[ -v users[${user,,}] ]]; then
56 log "User $user is a potential reviewer, but has already left a review, ignoring"
57 unset 'users[${user,,}]'
58 fi
59done < "$tmp/already-reviewed-by"
60
61for user in "${!users[@]}"; do
62 if ! gh api \
63 -H "Accept: application/vnd.github+json" \
64 -H "X-GitHub-Api-Version: 2022-11-28" \
65 "/repos/$baseRepo/collaborators/$user" >&2; then
66 log "User $user is not a repository collaborator, probably missed the automated invite to the maintainers team (see <https://github.com/NixOS/nixpkgs/issues/234293>), ignoring"
67 unset 'users[$user]'
68 fi
69done
70
71if [[ "${#users[@]}" -gt 10 ]]; then
72 log "Too many reviewers (${!users[*]}), skipping review requests"
73 exit 0
74fi
75
76for user in "${!users[@]}"; do
77 log "Requesting review from: $user"
78
79 if ! response=$(jq -n --arg user "$user" '{ reviewers: [ $user ] }' | \
80 effect gh api \
81 --method POST \
82 -H "Accept: application/vnd.github+json" \
83 -H "X-GitHub-Api-Version: 2022-11-28" \
84 "/repos/$baseRepo/pulls/$prNumber/requested_reviewers" \
85 --input -); then
86 log "Failed to request review from $user: $response"
87 fi
88done