From f9963d600980eb8713fde4f66c0b747d31505c15 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Nov 2025 17:50:26 +0000 Subject: [PATCH 1/5] Initial plan From 8ad4979436d2b03803cfb8533be7ec874e272911 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Nov 2025 17:54:37 +0000 Subject: [PATCH 2/5] Add peer review check GitHub Action workflow Co-authored-by: DonnieBLT <128622481+DonnieBLT@users.noreply.github.com> --- .github/workflows/check-peer-review.yml | 101 ++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 .github/workflows/check-peer-review.yml diff --git a/.github/workflows/check-peer-review.yml b/.github/workflows/check-peer-review.yml new file mode 100644 index 0000000000..39714f7007 --- /dev/null +++ b/.github/workflows/check-peer-review.yml @@ -0,0 +1,101 @@ +name: Check Peer Review + +on: + pull_request: + types: + - opened + - synchronize + - reopened + pull_request_review: + types: + - submitted + - dismissed + +permissions: + pull-requests: write + contents: read + issues: write + +jobs: + check_peer_review: + runs-on: ubuntu-latest + steps: + - name: Check for Peer Review + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR_NUMBER: ${{ github.event.pull_request.number }} + REPO_OWNER: ${{ github.repository_owner }} + REPO_NAME: ${{ github.event.repository.name }} + PR_AUTHOR: ${{ github.event.pull_request.user.login }} + run: | + echo "Checking peer review for PR #$PR_NUMBER in $REPO_OWNER/$REPO_NAME" + echo "PR Author: $PR_AUTHOR" + + # Get all reviews for the PR + REVIEWS_RESPONSE=$(curl -s -X GET \ + -H "Authorization: token $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + "https://api.github.com/repos/$REPO_OWNER/$REPO_NAME/pulls/$PR_NUMBER/reviews") + + # Check if the API request was successful + if [[ "$REVIEWS_RESPONSE" == *"message"*"Not Found"* ]] || [[ "$REVIEWS_RESPONSE" == *"Resource not accessible by integration"* ]]; then + echo "Error: Could not fetch PR reviews. Response: $REVIEWS_RESPONSE" + exit 1 + fi + + # Extract reviewer usernames (excluding bot accounts and specific users) + VALID_REVIEWERS=$(echo "$REVIEWS_RESPONSE" | jq -r '.[] | select(.user.login != "'$PR_AUTHOR'" and .user.login != "DonnieBLT" and .user.login != "coderabbit[bot]" and (.user.login | contains("copilot") | not)) | .user.login' | sort -u) + + echo "Reviews found: $(echo "$REVIEWS_RESPONSE" | jq length)" + echo "Valid reviewers (excluding author, DonnieBLT, coderabbit, and copilot): $VALID_REVIEWERS" + + # Check if there are any valid reviewers + if [ -z "$VALID_REVIEWERS" ]; then + echo "No peer review found from a valid reviewer." + + # Check if we already posted a comment + COMMENTS_RESPONSE=$(curl -s -X GET \ + -H "Authorization: token $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + "https://api.github.com/repos/$REPO_OWNER/$REPO_NAME/issues/$PR_NUMBER/comments") + + # Check if a comment about peer review already exists + EXISTING_COMMENT=$(echo "$COMMENTS_RESPONSE" | jq -r '.[] | select(.body | contains("peer review")) | .id' | head -n 1) + + if [ -z "$EXISTING_COMMENT" ]; then + echo "Posting comment to request peer review..." + + # Create JSON payload for the comment + jq -n \ + --arg body "👋 Hi @${PR_AUTHOR}! + + This pull request needs a peer review before it can be merged. Please request a review from a team member who is not: + - The PR author + - DonnieBLT + - coderabbit + - copilot + + Once a valid peer review is submitted, this check will pass automatically. Thank you!" \ + '{body: $body}' > /tmp/comment.json + + POST_COMMENT_RESPONSE=$(curl -s -X POST \ + -H "Authorization: token $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + "https://api.github.com/repos/$REPO_OWNER/$REPO_NAME/issues/$PR_NUMBER/comments" \ + -d @/tmp/comment.json) + + if [[ "$POST_COMMENT_RESPONSE" == *"id"* ]]; then + echo "Comment posted successfully." + else + echo "Failed to post comment: $POST_COMMENT_RESPONSE" + fi + else + echo "Comment about peer review already exists (ID: $EXISTING_COMMENT)." + fi + + echo "Peer review check failed: No valid peer review found." + exit 1 + else + echo "Peer review check passed: Valid reviewers found: $VALID_REVIEWERS" + exit 0 + fi From d2f3b62a023b1dd69ea508f320b8f44f93f57b35 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Nov 2025 17:56:28 +0000 Subject: [PATCH 3/5] Improve peer review check with better validation and error handling Co-authored-by: DonnieBLT <128622481+DonnieBLT@users.noreply.github.com> --- .github/workflows/check-peer-review.yml | 47 +++++++++++++++++-------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/.github/workflows/check-peer-review.yml b/.github/workflows/check-peer-review.yml index 39714f7007..34d22ce78a 100644 --- a/.github/workflows/check-peer-review.yml +++ b/.github/workflows/check-peer-review.yml @@ -23,12 +23,27 @@ jobs: - name: Check for Peer Review env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PR_NUMBER: ${{ github.event.pull_request.number }} - REPO_OWNER: ${{ github.repository_owner }} - REPO_NAME: ${{ github.event.repository.name }} - PR_AUTHOR: ${{ github.event.pull_request.user.login }} run: | + # Determine PR number based on event type + if [ "${{ github.event_name }}" = "pull_request_review" ]; then + PR_NUMBER="${{ github.event.review.pull_request_url }}" + PR_NUMBER="${PR_NUMBER##*/}" + else + PR_NUMBER="${{ github.event.pull_request.number }}" + fi + + REPO_OWNER="${{ github.repository_owner }}" + REPO_NAME="${{ github.event.repository.name }}" + echo "Checking peer review for PR #$PR_NUMBER in $REPO_OWNER/$REPO_NAME" + + # Get PR details to find the author + PR_RESPONSE=$(curl -s -X GET \ + -H "Authorization: token $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + "https://api.github.com/repos/$REPO_OWNER/$REPO_NAME/pulls/$PR_NUMBER") + + PR_AUTHOR=$(echo "$PR_RESPONSE" | jq -r '.user.login') echo "PR Author: $PR_AUTHOR" # Get all reviews for the PR @@ -43,11 +58,11 @@ jobs: exit 1 fi - # Extract reviewer usernames (excluding bot accounts and specific users) - VALID_REVIEWERS=$(echo "$REVIEWS_RESPONSE" | jq -r '.[] | select(.user.login != "'$PR_AUTHOR'" and .user.login != "DonnieBLT" and .user.login != "coderabbit[bot]" and (.user.login | contains("copilot") | not)) | .user.login' | sort -u) + # Extract reviewer usernames from APPROVED reviews only (excluding bot accounts and specific users) + VALID_REVIEWERS=$(echo "$REVIEWS_RESPONSE" | jq -r '.[] | select(.state == "APPROVED" and .user.login != "'$PR_AUTHOR'" and .user.login != "DonnieBLT" and .user.login != "coderabbit[bot]" and (.user.login | contains("copilot") | not)) | .user.login' | sort -u) echo "Reviews found: $(echo "$REVIEWS_RESPONSE" | jq length)" - echo "Valid reviewers (excluding author, DonnieBLT, coderabbit, and copilot): $VALID_REVIEWERS" + echo "Valid approved reviewers (excluding author, DonnieBLT, coderabbit, and copilot): $VALID_REVIEWERS" # Check if there are any valid reviewers if [ -z "$VALID_REVIEWERS" ]; then @@ -59,15 +74,16 @@ jobs: -H "Accept: application/vnd.github.v3+json" \ "https://api.github.com/repos/$REPO_OWNER/$REPO_NAME/issues/$PR_NUMBER/comments") - # Check if a comment about peer review already exists - EXISTING_COMMENT=$(echo "$COMMENTS_RESPONSE" | jq -r '.[] | select(.body | contains("peer review")) | .id' | head -n 1) + # Check if a comment about peer review already exists (using a unique marker) + EXISTING_COMMENT=$(echo "$COMMENTS_RESPONSE" | jq -r '.[] | select(.body | contains("")) | .id' | head -n 1) if [ -z "$EXISTING_COMMENT" ]; then echo "Posting comment to request peer review..." - # Create JSON payload for the comment + # Create JSON payload for the comment with a unique marker jq -n \ - --arg body "👋 Hi @${PR_AUTHOR}! + --arg body " + 👋 Hi @${PR_AUTHOR}! This pull request needs a peer review before it can be merged. Please request a review from a team member who is not: - The PR author @@ -78,16 +94,19 @@ jobs: Once a valid peer review is submitted, this check will pass automatically. Thank you!" \ '{body: $body}' > /tmp/comment.json - POST_COMMENT_RESPONSE=$(curl -s -X POST \ + POST_COMMENT_RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \ -H "Authorization: token $GITHUB_TOKEN" \ -H "Accept: application/vnd.github.v3+json" \ "https://api.github.com/repos/$REPO_OWNER/$REPO_NAME/issues/$PR_NUMBER/comments" \ -d @/tmp/comment.json) - if [[ "$POST_COMMENT_RESPONSE" == *"id"* ]]; then + HTTP_CODE=$(echo "$POST_COMMENT_RESPONSE" | tail -n 1) + RESPONSE_BODY=$(echo "$POST_COMMENT_RESPONSE" | sed '$d') + + if [ "$HTTP_CODE" -eq 201 ]; then echo "Comment posted successfully." else - echo "Failed to post comment: $POST_COMMENT_RESPONSE" + echo "Failed to post comment. HTTP Code: $HTTP_CODE, Response: $RESPONSE_BODY" fi else echo "Comment about peer review already exists (ID: $EXISTING_COMMENT)." From e61c544e93371cbfd0838840717a2a04af883e87 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Nov 2025 17:58:26 +0000 Subject: [PATCH 4/5] Refactor peer review check for better maintainability and robustness Co-authored-by: DonnieBLT <128622481+DonnieBLT@users.noreply.github.com> --- .github/workflows/check-peer-review.yml | 30 ++++++++++++++++--------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/.github/workflows/check-peer-review.yml b/.github/workflows/check-peer-review.yml index 34d22ce78a..6f70b18715 100644 --- a/.github/workflows/check-peer-review.yml +++ b/.github/workflows/check-peer-review.yml @@ -24,16 +24,13 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - # Determine PR number based on event type - if [ "${{ github.event_name }}" = "pull_request_review" ]; then - PR_NUMBER="${{ github.event.review.pull_request_url }}" - PR_NUMBER="${PR_NUMBER##*/}" - else - PR_NUMBER="${{ github.event.pull_request.number }}" - fi + # Get PR number (available for both pull_request and pull_request_review events) + PR_NUMBER="${{ github.event.pull_request.number }}" - REPO_OWNER="${{ github.repository_owner }}" - REPO_NAME="${{ github.event.repository.name }}" + # Parse repository owner and name + REPO_FULL="${{ github.repository }}" + REPO_OWNER="${REPO_FULL%/*}" + REPO_NAME="${REPO_FULL#*/}" echo "Checking peer review for PR #$PR_NUMBER in $REPO_OWNER/$REPO_NAME" @@ -58,8 +55,19 @@ jobs: exit 1 fi - # Extract reviewer usernames from APPROVED reviews only (excluding bot accounts and specific users) - VALID_REVIEWERS=$(echo "$REVIEWS_RESPONSE" | jq -r '.[] | select(.state == "APPROVED" and .user.login != "'$PR_AUTHOR'" and .user.login != "DonnieBLT" and .user.login != "coderabbit[bot]" and (.user.login | contains("copilot") | not)) | .user.login' | sort -u) + # Define excluded users (users whose reviews don't count as valid peer reviews) + EXCLUDED_USERS=("$PR_AUTHOR" "DonnieBLT" "coderabbit[bot]") + + # Extract reviewer usernames from APPROVED reviews only + # Filter out the PR author, specific excluded users, and any user with "copilot" in their username + VALID_REVIEWERS=$(echo "$REVIEWS_RESPONSE" | jq -r --arg author "$PR_AUTHOR" \ + '.[] | + select(.state == "APPROVED") | + select(.user.login != $author) | + select(.user.login != "DonnieBLT") | + select(.user.login != "coderabbit[bot]") | + select(.user.login | contains("copilot") | not) | + .user.login' | sort -u) echo "Reviews found: $(echo "$REVIEWS_RESPONSE" | jq length)" echo "Valid approved reviewers (excluding author, DonnieBLT, coderabbit, and copilot): $VALID_REVIEWERS" From 524bc8b83e70a1016de0f0bf33c566eb8d15e7e9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 15 Nov 2025 17:50:56 +0000 Subject: [PATCH 5/5] Exempt DonnieBLT, dependabot, and copilot from peer review check Co-authored-by: DonnieBLT <128622481+DonnieBLT@users.noreply.github.com> --- .github/workflows/check-peer-review.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/check-peer-review.yml b/.github/workflows/check-peer-review.yml index 6f70b18715..243d8116c0 100644 --- a/.github/workflows/check-peer-review.yml +++ b/.github/workflows/check-peer-review.yml @@ -19,6 +19,13 @@ permissions: jobs: check_peer_review: runs-on: ubuntu-latest + if: > + github.actor != 'dependabot[bot]' + && github.actor != 'dependabot-preview[bot]' + && github.actor != 'dependabot' + && github.actor != 'DonnieBLT' + && github.actor != 'Copilot' + && github.actor != 'copilot-swe-agent[bot]' steps: - name: Check for Peer Review env: