Created
September 4, 2025 19:31
-
-
Save mauteri/fdde61273d5056b911474160f57a6b09 to your computer and use it in GitHub Desktop.
List approved PRs by reviewer in a GitHub org (CSV export).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| set -euo pipefail | |
| # GitHub API script to find PRs approved by a specific reviewer | |
| # Usage: bash github_approved_prs.sh REVIEWER [DAYS_AGO] | |
| # | |
| # Requirements: | |
| # - jq (JSON parser) | |
| # - curl | |
| # | |
| # TOKEN and ORG can be set as environment variables, e.g.: | |
| # export TOKEN=ghp_yourtoken | |
| # export ORG=my-org | |
| # Or edit the defaults below. | |
| # Default values (only used if env vars not set) | |
| TOKEN="${TOKEN:-GITHUB_TOKEN_HERE}" | |
| ORG="${ORG:-ORGANIZATION_HERE}" | |
| # Safety checks | |
| if [[ "$TOKEN" == "GITHUB_TOKEN_HERE" || -z "${TOKEN}" ]]; then | |
| echo "Error: TOKEN not set. Run: export TOKEN=ghp_yourtoken" | |
| exit 1 | |
| fi | |
| if [[ "$ORG" == "ORGANIZATION_HERE" || -z "${ORG}" ]]; then | |
| echo "Error: ORG not set. Run: export ORG=my-org" | |
| exit 1 | |
| fi | |
| # Check if reviewer was provided | |
| if [ $# -eq 0 ]; then | |
| echo "Error: Reviewer username required" | |
| echo "Usage: $0 REVIEWER [DAYS_AGO]" | |
| exit 1 | |
| fi | |
| REVIEWER="$1" | |
| DAYS_AGO=${2:-30} # Default 30 if not provided | |
| OUTPUT_FILE="approved_prs.csv" | |
| # Create CSV header | |
| echo "PR URL,Title,Repository,Created Date,Merged Date" > "$OUTPUT_FILE" | |
| # Calculate date from X days ago (macOS vs Linux) | |
| SINCE_DATE=$(date -v-"${DAYS_AGO}"d +%Y-%m-%d 2>/dev/null || date --date="${DAYS_AGO} days ago" +%Y-%m-%d) | |
| # Query for PRs | |
| query="org:$ORG type:pr reviewed-by:$REVIEWER review:approved updated:>=$SINCE_DATE" | |
| encoded_query=$(printf '%s' "$query" | jq -sRr @uri) | |
| echo "Searching for PRs approved by $REVIEWER in $ORG since $SINCE_DATE..." | |
| page=1 | |
| total_prs=0 | |
| while true; do | |
| response=$(curl -s -H "Authorization: token $TOKEN" \ | |
| -H "Accept: application/vnd.github.v3+json" \ | |
| "https://api.github.com/search/issues?q=$encoded_query&per_page=100&page=$page") | |
| pr_count=$(echo "$response" | jq '.items | length') | |
| total_count=$(echo "$response" | jq '.total_count') | |
| if [ "$pr_count" -eq 0 ]; then | |
| break | |
| fi | |
| for i in $(seq 0 $(($pr_count - 1))); do | |
| pr_url=$(echo "$response" | jq -r ".items[$i].html_url") | |
| pr_title=$(echo "$response" | jq -r ".items[$i].title" | tr -d '\n' | sed 's/,/\\,/g') | |
| repo=$(echo "$pr_url" | sed 's|https://github.com/||' | cut -d/ -f1-2) | |
| created_date=$(echo "$response" | jq -r ".items[$i].created_at") | |
| pr_number=$(echo "$pr_url" | sed 's|.*/||') | |
| pr_details=$(curl -s -H "Authorization: token $TOKEN" \ | |
| -H "Accept: application/vnd.github.v3+json" \ | |
| "https://api.github.com/repos/$repo/pulls/$pr_number") | |
| merged_date=$(echo "$pr_details" | jq -r '.merged_at // "Not merged"') | |
| echo "$pr_url,$pr_title,$repo,$created_date,$merged_date" >> "$OUTPUT_FILE" | |
| total_prs=$((total_prs + 1)) | |
| echo " Found PR: $pr_title ($pr_url)" | |
| done | |
| if [ "$total_prs" -ge "$total_count" ]; then | |
| break | |
| fi | |
| page=$((page + 1)) | |
| done | |
| echo "Complete! Found $total_prs PRs approved by $REVIEWER." | |
| echo "Results saved to $OUTPUT_FILE" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment