Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

workflows/eval: fix maintainer requests #370456

Merged
merged 4 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions .github/workflows/eval.yml
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ jobs:
tag:
name: Tag
runs-on: ubuntu-latest
needs: process
needs: [ attrs, process ]
if: needs.process.outputs.baseRunId
permissions:
pull-requests: write
Expand All @@ -239,6 +239,21 @@ jobs:
name: comparison
path: comparison

- name: Install Nix
uses: cachix/install-nix-action@08dcb3a5e62fa31e2da3d490afc4176ef55ecd72 # v30

# Important: This workflow job runs with extra permissions,
# so we need to make sure to not run untrusted code from PRs
- name: Check out Nixpkgs at the base commit
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ needs.attrs.outputs.baseSha }}
path: base
sparse-checkout: ci

- name: Build the requestReviews derivation
run: nix-build base/ci -A requestReviews

- name: Tagging pull request
run: |
# Get all currently set rebuild labels
Expand Down Expand Up @@ -271,20 +286,21 @@ jobs:
# maintainers.json contains GitHub IDs. Look up handles to request reviews from.
# 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"; done \
| jq -s '{ reviewers: map(.login) }' \
| 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/${{ github.repository }}/pulls/${{ github.event.number }}/requested_reviewers \
/repos/"$REPOSITORY"/pulls/"$NUMBER"/requested_reviewers \
doronbehar marked this conversation as resolved.
Show resolved Hide resolved
--input reviewers.json

env:
GH_TOKEN: ${{ github.token }}
REPOSITORY: ${{ github.repository }}
NUMBER: ${{ github.event.number }}
AUTHOR: ${{ github.event.pull_request.user.login }}

- name: Add eval summary to commit statuses
if: ${{ github.event_name == 'pull_request_target' }}
Expand Down
1 change: 1 addition & 0 deletions ci/request-reviews/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ stdenvNoCC.mkDerivation {
root = ./.;
fileset = lib.fileset.unions [
./get-reviewers.sh
./process-reviewers.sh
./request-reviews.sh
./verify-base-branch.sh
./dev-branches.txt
Expand Down
42 changes: 6 additions & 36 deletions ci/request-reviews/get-reviewers.sh
Original file line number Diff line number Diff line change
@@ -1,27 +1,22 @@
#!/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
# Get the code owners of the files changed by a PR, returning one username per line

set -euo pipefail

log() {
echo "$@" >&2
}

if (( "$#" < 7 )); then
log "Usage: $0 GIT_REPO OWNERS_FILE BASE_REPO BASE_REF HEAD_REF PR_NUMBER PR_AUTHOR"
if (( "$#" < 4 )); then
log "Usage: $0 GIT_REPO OWNERS_FILE BASE_REF HEAD_REF"
exit 1
fi

gitRepo=$1
ownersFile=$2
baseRepo=$3
baseRef=$4
headRef=$5
prNumber=$6
prAuthor=$7
baseRef=$3
headRef=$4

tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' exit
Expand Down Expand Up @@ -98,29 +93,4 @@ for file in "${touchedFiles[@]}"; do

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 code owner but has already left a review, ignoring"
unset 'users[${user,,}]'
fi
done < "$tmp/already-reviewed-by"

# Turn it into a JSON for the GitHub API call to request PR reviewers
jq -n \
--arg users "${!users[*]}" \
'{
reviewers: $users | split(" "),
}'
printf "%s\n" "${!users[@]}"
65 changes: 65 additions & 0 deletions ci/request-reviews/process-reviewers.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/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"
wolfgangwalther marked this conversation as resolved.
Show resolved Hide resolved

# 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 code owner 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"
JohnRTitor marked this conversation as resolved.
Show resolved Hide resolved
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(" "),
}'
3 changes: 2 additions & 1 deletion ci/request-reviews/request-reviews.sh
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ if ! "$SCRIPT_DIR"/verify-base-branch.sh "$tmp/nixpkgs.git" "$headRef" "$baseRep
fi

log "Getting code owners to request reviews from"
"$SCRIPT_DIR"/get-reviewers.sh "$tmp/nixpkgs.git" "$ownersFile" "$baseRepo" "$baseBranch" "$headRef" "$prNumber" "$prAuthor" > "$tmp/reviewers.json"
"$SCRIPT_DIR"/get-reviewers.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")"

Expand Down
Loading