ci/request-reviews: share code to request reviewers from gh api

This makes it easier to add ofborg's request-1-by-1 logic, where failed
requests are OK for edge cases.

Changed files
+94 -90
.github
workflows
ci
+1 -8
.github/workflows/eval.yml
···
# There appears to be no API to request reviews based on GitHub IDs
jq -r 'keys[]' comparison/maintainers.json \
| while read -r id; do gh api /user/"$id" --jq .login; done \
-
| GH_TOKEN=${{ steps.app-token.outputs.token }} result/bin/process-reviewers.sh "$REPOSITORY" "$NUMBER" "$AUTHOR" \
-
> reviewers.json
-
-
# Request reviewers from maintainers of changed output paths
-
GH_TOKEN=${{ steps.app-token.outputs.token }} gh api \
-
--method POST \
-
/repos/"$REPOSITORY"/pulls/"$NUMBER"/requested_reviewers \
-
--input reviewers.json
+
| GH_TOKEN=${{ steps.app-token.outputs.token }} result/bin/request-reviewers.sh "$REPOSITORY" "$NUMBER" "$AUTHOR"
env:
GH_TOKEN: ${{ github.token }}
+1 -1
ci/request-reviews/default.nix
···
root = ./.;
fileset = lib.fileset.unions [
./get-code-owners.sh
-
./process-reviewers.sh
+
./request-reviewers.sh
./request-code-owner-reviews.sh
./verify-base-branch.sh
./dev-branches.txt
-65
ci/request-reviews/process-reviewers.sh
···
-
#!/usr/bin/env bash
-
-
# Process reviewers for a PR, reading line-separated usernames on stdin,
-
# returning a JSON suitable to be consumed by the API endpoint to request reviews:
-
# https://docs.github.com/en/rest/pulls/review-requests?apiVersion=2022-11-28#request-reviewers-for-a-pull-request
-
-
set -euo pipefail
-
-
log() {
-
echo "$@" >&2
-
}
-
-
if (( "$#" < 3 )); then
-
log "Usage: $0 BASE_REPO PR_NUMBER PR_AUTHOR"
-
exit 1
-
fi
-
-
baseRepo=$1
-
prNumber=$2
-
prAuthor=$3
-
-
tmp=$(mktemp -d)
-
trap 'rm -rf "$tmp"' exit
-
-
declare -A users=()
-
while read -r handle && [[ -n "$handle" ]]; do
-
users[${handle,,}]=
-
done
-
-
# Cannot request a review from the author
-
if [[ -v users[${prAuthor,,}] ]]; then
-
log "One or more files are owned by the PR author, ignoring"
-
unset 'users[${prAuthor,,}]'
-
fi
-
-
gh api \
-
-H "Accept: application/vnd.github+json" \
-
-H "X-GitHub-Api-Version: 2022-11-28" \
-
"/repos/$baseRepo/pulls/$prNumber/reviews" \
-
--jq '.[].user.login' > "$tmp/already-reviewed-by"
-
-
# And we don't want to rerequest reviews from people who already reviewed
-
while read -r user; do
-
if [[ -v users[${user,,}] ]]; then
-
log "User $user is a potential reviewer, but has already left a review, ignoring"
-
unset 'users[${user,,}]'
-
fi
-
done < "$tmp/already-reviewed-by"
-
-
for user in "${!users[@]}"; do
-
if ! gh api \
-
-H "Accept: application/vnd.github+json" \
-
-H "X-GitHub-Api-Version: 2022-11-28" \
-
"/repos/$baseRepo/collaborators/$user" >&2; then
-
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"
-
unset 'users[$user]'
-
fi
-
done
-
-
# Turn it into a JSON for the GitHub API call to request PR reviewers
-
jq -n \
-
--arg users "${!users[*]}" \
-
'{
-
reviewers: $users | split(" "),
-
}'
+2 -16
ci/request-reviews/request-code-owner-reviews.sh
···
exit 1
fi
-
log "Getting code owners to request reviews from"
+
log "Requesting reviews from code owners"
"$SCRIPT_DIR"/get-code-owners.sh "$tmp/nixpkgs.git" "$ownersFile" "$baseBranch" "$headRef" | \
-
"$SCRIPT_DIR"/process-reviewers.sh "$baseRepo" "$prNumber" "$prAuthor" > "$tmp/reviewers.json"
-
-
log "Requesting reviews from: $(<"$tmp/reviewers.json")"
-
-
if ! response=$(effect gh api \
-
--method POST \
-
-H "Accept: application/vnd.github+json" \
-
-H "X-GitHub-Api-Version: 2022-11-28" \
-
"/repos/$baseRepo/pulls/$prNumber/requested_reviewers" \
-
--input "$tmp/reviewers.json"); then
-
log "Failed to request reviews: $response"
-
exit 1
-
fi
-
-
log "Successfully requested reviews"
+
"$SCRIPT_DIR"/request-reviewers.sh "$baseRepo" "$prNumber" "$prAuthor"
+90
ci/request-reviews/request-reviewers.sh
···
+
#!/usr/bin/env bash
+
+
# Request reviewers for a PR, reading line-separated usernames on stdin,
+
# filtering for valid reviewers before using the API endpoint to request reviews:
+
# https://docs.github.com/en/rest/pulls/review-requests?apiVersion=2022-11-28#request-reviewers-for-a-pull-request
+
+
set -euo pipefail
+
+
tmp=$(mktemp -d)
+
trap 'rm -rf "$tmp"' exit
+
+
log() {
+
echo "$@" >&2
+
}
+
+
effect() {
+
if [[ -n "${DRY_MODE:-}" ]]; then
+
log "Skipping in dry mode:" "${@@Q}"
+
else
+
"$@"
+
fi
+
}
+
+
if (( "$#" < 3 )); then
+
log "Usage: $0 BASE_REPO PR_NUMBER PR_AUTHOR"
+
exit 1
+
fi
+
+
baseRepo=$1
+
prNumber=$2
+
prAuthor=$3
+
+
tmp=$(mktemp -d)
+
trap 'rm -rf "$tmp"' exit
+
+
declare -A users=()
+
while read -r handle && [[ -n "$handle" ]]; do
+
users[${handle,,}]=
+
done
+
+
# Cannot request a review from the author
+
if [[ -v users[${prAuthor,,}] ]]; then
+
log "One or more files are owned by the PR author, ignoring"
+
unset 'users[${prAuthor,,}]'
+
fi
+
+
gh api \
+
-H "Accept: application/vnd.github+json" \
+
-H "X-GitHub-Api-Version: 2022-11-28" \
+
"/repos/$baseRepo/pulls/$prNumber/reviews" \
+
--jq '.[].user.login' > "$tmp/already-reviewed-by"
+
+
# And we don't want to rerequest reviews from people who already reviewed
+
while read -r user; do
+
if [[ -v users[${user,,}] ]]; then
+
log "User $user is a potential reviewer, but has already left a review, ignoring"
+
unset 'users[${user,,}]'
+
fi
+
done < "$tmp/already-reviewed-by"
+
+
for user in "${!users[@]}"; do
+
if ! gh api \
+
-H "Accept: application/vnd.github+json" \
+
-H "X-GitHub-Api-Version: 2022-11-28" \
+
"/repos/$baseRepo/collaborators/$user" >&2; then
+
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"
+
unset 'users[$user]'
+
fi
+
done
+
+
# Turn it into a JSON for the GitHub API call to request PR reviewers
+
jq -n \
+
--arg users "${!users[*]}" \
+
'{
+
reviewers: $users | split(" "),
+
}' > "$tmp/reviewers.json"
+
+
log "Requesting reviews from: $(<"$reviewersFile")"
+
+
if ! response=$(effect gh api \
+
--method POST \
+
-H "Accept: application/vnd.github+json" \
+
-H "X-GitHub-Api-Version: 2022-11-28" \
+
"/repos/$baseRepo/pulls/$prNumber/requested_reviewers" \
+
--input "$tmp/reviewers.json"); then
+
log "Failed to request reviews: $response"
+
exit 1
+
fi
+
+
log "Successfully requested reviews"