Skip to content

Commit

Permalink
ci/request-reviews: Request reviews for individual team members
Browse files Browse the repository at this point in the history
This makes this codeowner mechanism behave differently than the native
one, but there's no other way to avoid rerequesting reviews from teams
when a member already reviewed the PR.

(cherry picked from commit 1ff83b2)
  • Loading branch information
infinisil committed Oct 14, 2024
1 parent 16b54e1 commit 59990c7
Showing 1 changed file with 30 additions and 8 deletions.
38 changes: 30 additions & 8 deletions ci/request-reviews/get-reviewers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ log "This PR touches ${#touchedFiles[@]} files"
# 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
# Associative array with the user as the key for easy de-duplication
declare -A users=()

for file in "${touchedFiles[@]}"; do
result=$(codeowners --file "$tmp"/codeowners "$file")
Expand All @@ -61,10 +61,34 @@ for file in "${touchedFiles[@]}"; do
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]}]=

if [[ "$entry" =~ (.*)/(.*) ]]; then
# Teams look like $org/$team
org=${BASH_REMATCH[1]}
team=${BASH_REMATCH[2]}

# Instead of requesting a review from the team itself,
# we request reviews from the individual users.
# This is because once somebody from a team reviewed the PR,
# the API doesn't expose that the team was already requested for a review,
# so we wouldn't be able to avoid rerequesting reviews
# without saving some some extra state somewhere

# We could also consider implementing a more advanced heuristic
# in the future that e.g. only pings one team member,
# but escalates to somebody else if that member doesn't respond in time.
gh api \
--cache=1h \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/orgs/$org/teams/$team/members" \
--jq '.[].login' > "$tmp/team-members"
readarray -t members < "$tmp/team-members"
log "Team $entry has these members: ${members[*]}"

for user in "${members[@]}"; do
users[$user]=
done
else
# Everything else is a user
users[$entry]=
Expand Down Expand Up @@ -96,8 +120,6 @@ done < "$tmp/already-reviewed-by"
# 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(" ")
}'

0 comments on commit 59990c7

Please sign in to comment.