mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-26 00:43:20 +00:00
369cfa02da
Also post a comment in case base branch is wrong This guides newcomers in how to smoothly handle the potentially scary situation of having thousands of commits listed in a PR. While CI shows the same, people might not even look at CI if the PR looks botched.
88 lines
2.6 KiB
Bash
Executable File
88 lines
2.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# Get the code owners of the files changed by a PR,
|
|
# 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 (( "$#" < 5 )); then
|
|
log "Usage: $0 GIT_REPO BASE_REF HEAD_REF OWNERS_FILE PR_AUTHOR"
|
|
exit 1
|
|
fi
|
|
|
|
gitRepo=$1
|
|
baseRef=$2
|
|
headRef=$3
|
|
ownersFile=$4
|
|
prAuthor=$5
|
|
|
|
tmp=$(mktemp -d)
|
|
trap 'rm -rf "$tmp"' exit
|
|
|
|
git -C "$gitRepo" diff --name-only --merge-base "$baseRef" "$headRef" > "$tmp/touched-files"
|
|
readarray -t touchedFiles < "$tmp/touched-files"
|
|
log "This PR touches ${#touchedFiles[@]} files"
|
|
|
|
# Get the owners file from the base, because we don't want to allow PRs to
|
|
# remove code owners to avoid pinging them
|
|
git -C "$gitRepo" show "$baseRef":"$ownersFile" > "$tmp"/codeowners
|
|
|
|
# Associative arrays with the team/user as the key for easy deduplication
|
|
declare -A teams users
|
|
|
|
for file in "${touchedFiles[@]}"; do
|
|
result=$(codeowners --file "$tmp"/codeowners "$file")
|
|
|
|
read -r file owners <<< "$result"
|
|
if [[ "$owners" == "(unowned)" ]]; then
|
|
log "File $file is unowned"
|
|
continue
|
|
fi
|
|
log "File $file is owned by $owners"
|
|
|
|
# Split up multiple owners, separated by arbitrary amounts of spaces
|
|
IFS=" " read -r -a entries <<< "$owners"
|
|
|
|
for entry in "${entries[@]}"; do
|
|
# GitHub technically also supports Emails as code owners,
|
|
# but we can't easily support that, so let's not
|
|
if [[ ! "$entry" =~ @(.*) ]]; then
|
|
warn -e "\e[33mCodeowner \"$entry\" for file $file is not valid: Must start with \"@\"\e[0m" >&2
|
|
# Don't fail, because the PR for which this script runs can't fix it,
|
|
# it has to be fixed in the base branch
|
|
continue
|
|
fi
|
|
# The first regex match is everything after the @
|
|
entry=${BASH_REMATCH[1]}
|
|
if [[ "$entry" =~ .*/(.*) ]]; then
|
|
# Teams look like $org/$team, where we only need $team for the API
|
|
# call to request reviews from teams
|
|
teams[${BASH_REMATCH[1]}]=
|
|
else
|
|
# Everything else is a user
|
|
users[$entry]=
|
|
fi
|
|
done
|
|
|
|
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
|
|
|
|
# Turn it into a JSON for the GitHub API call to request PR reviewers
|
|
jq -n \
|
|
--arg users "${!users[*]}" \
|
|
--arg teams "${!teams[*]}" \
|
|
'{
|
|
reviewers: $users | split(" "),
|
|
team_reviewers: $teams | split(" ")
|
|
}'
|