Skip to content

Instantly share code, notes, and snippets.

@mauteri
Created September 4, 2025 19:31
Show Gist options
  • Select an option

  • Save mauteri/fdde61273d5056b911474160f57a6b09 to your computer and use it in GitHub Desktop.

Select an option

Save mauteri/fdde61273d5056b911474160f57a6b09 to your computer and use it in GitHub Desktop.
List approved PRs by reviewer in a GitHub org (CSV export).
#!/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