Skip to content

Instantly share code, notes, and snippets.

@ezynda3
Last active August 19, 2025 04:35
Show Gist options
  • Save ezynda3/f47c92049256d2633d20cded915e3416 to your computer and use it in GitHub Desktop.
Save ezynda3/f47c92049256d2633d20cded915e3416 to your computer and use it in GitHub Desktop.
Fetch all comments from pr and user
#!/bin/bash
# Script to fetch and display PR comments from GitHub
# Automatically detects repository from current git directory
# Usage: ./fetch_pr_comments.sh <PR_NUMBER> [USERNAME]
# Color codes for better output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
BOLD='\033[1m'
# Function to display usage
show_usage() {
echo "Usage: $0 <PR_NUMBER> [USERNAME]"
echo ""
echo "This script must be run from within a git repository with a GitHub origin remote."
echo ""
echo "Arguments:"
echo " PR_NUMBER - Required. The pull request number"
echo " USERNAME - Optional. Filter comments by specific user"
echo ""
echo "Examples:"
echo " $0 123 # Show all comments from PR #123"
echo " $0 123 Bob # Show only comments from user Bob in PR #123"
exit 1
}
# Function to check if required commands are available
check_dependencies() {
if ! command -v git &> /dev/null; then
echo -e "${RED}Error: git is not installed${NC}"
exit 1
fi
if ! command -v gh &> /dev/null; then
echo -e "${RED}Error: GitHub CLI (gh) is not installed${NC}"
echo "Please install it from: https://cli.github.com/"
exit 1
fi
if ! command -v jq &> /dev/null; then
echo -e "${RED}Error: jq is not installed${NC}"
echo "Please install it using your package manager"
exit 1
fi
# Check if gh is authenticated
if ! gh auth status &> /dev/null; then
echo -e "${RED}Error: GitHub CLI is not authenticated${NC}"
echo "Please run: gh auth login"
exit 1
fi
}
# Function to extract repo info from git remote
get_repo_info() {
# Check if we're in a git repository
if ! git rev-parse --git-dir > /dev/null 2>&1; then
echo -e "${RED}Error: Not in a git repository${NC}"
echo "Please run this script from within a git repository"
exit 1
fi
# Get the origin remote URL
REMOTE_URL=$(git config --get remote.origin.url 2>/dev/null)
if [ -z "$REMOTE_URL" ]; then
echo -e "${RED}Error: No 'origin' remote found${NC}"
echo "Please ensure your repository has an origin remote set"
exit 1
fi
# Parse the URL to extract owner and repo name
# Handle both HTTPS and SSH URLs
if [[ "$REMOTE_URL" =~ ^https://github.com/([^/]+)/([^/]+)(\.git)?$ ]]; then
# HTTPS format: https://github.com/owner/repo.git
REPO_OWNER="${BASH_REMATCH[1]}"
REPO_NAME="${BASH_REMATCH[2]}"
elif [[ "$REMOTE_URL" =~ ^[email protected]:([^/]+)/([^/]+)(\.git)?$ ]]; then
# SSH format: [email protected]:owner/repo.git
REPO_OWNER="${BASH_REMATCH[1]}"
REPO_NAME="${BASH_REMATCH[2]}"
elif [[ "$REMOTE_URL" =~ ^ssh://[email protected]/([^/]+)/([^/]+)(\.git)?$ ]]; then
# SSH alternative format: ssh://[email protected]/owner/repo.git
REPO_OWNER="${BASH_REMATCH[1]}"
REPO_NAME="${BASH_REMATCH[2]}"
else
echo -e "${RED}Error: Unable to parse GitHub repository from remote URL${NC}"
echo "Remote URL: $REMOTE_URL"
echo "Expected format: https://github.com/owner/repo.git or [email protected]:owner/repo.git"
exit 1
fi
# Remove .git extension if present
REPO_NAME="${REPO_NAME%.git}"
echo -e "${GREEN}Repository detected: ${BOLD}${REPO_OWNER}/${REPO_NAME}${NC}"
}
# Function to display a single comment with formatting
display_comment() {
local comment="$1"
# Extract fields from JSON
local id=$(echo "$comment" | jq -r '.id')
local author=$(echo "$comment" | jq -r '.user.login')
local created=$(echo "$comment" | jq -r '.created_at')
local updated=$(echo "$comment" | jq -r '.updated_at')
local file=$(echo "$comment" | jq -r '.path')
local line=$(echo "$comment" | jq -r '.line // .original_line // "N/A"')
local position=$(echo "$comment" | jq -r '.position // "outdated"')
local body=$(echo "$comment" | jq -r '.body')
# Determine status
local status
if [ "$position" = "outdated" ]; then
status="${RED}Outdated${NC}"
else
status="Active"
fi
# Display formatted comment
echo -e "${YELLOW}═══════════════════════════════════════════════════${NC}"
echo -e "${GREEN}Comment ID:${NC} $id"
echo -e "${GREEN}Author:${NC} $author"
echo -e "${GREEN}Created:${NC} $created"
echo -e "${GREEN}Updated:${NC} $updated"
echo -e "${GREEN}File:${NC} ${BLUE}$file${NC}"
echo -e "${GREEN}Line:${NC} $line"
echo -e "${GREEN}Status:${NC} $status"
echo -e "${GREEN}Comment:${NC}"
echo "$body"
echo ""
}
# Check if at least one argument is provided
if [ $# -lt 1 ]; then
show_usage
fi
# Parse arguments
PR_NUMBER=$1
USERNAME=$2
# Validate PR number is a positive integer
if ! [[ "$PR_NUMBER" =~ ^[0-9]+$ ]]; then
echo -e "${RED}Error: PR number must be a positive integer${NC}"
exit 1
fi
# Check dependencies
check_dependencies
# Get repository information from git
get_repo_info
# Build the API endpoint
API_ENDPOINT="repos/${REPO_OWNER}/${REPO_NAME}/pulls/${PR_NUMBER}/comments"
# Display what we're doing
if [ -n "$USERNAME" ]; then
echo -e "${CYAN}Fetching comments from ${BOLD}${REPO_OWNER}/${REPO_NAME}${NC} PR #${PR_NUMBER} by user: ${BOLD}${USERNAME}${NC}\n"
else
echo -e "${CYAN}Fetching all comments from ${BOLD}${REPO_OWNER}/${REPO_NAME}${NC} PR #${PR_NUMBER}${NC}\n"
fi
echo -e "${YELLOW}Fetching comments...${NC}\n"
# Fetch all comments
ALL_COMMENTS=$(gh api "$API_ENDPOINT" --paginate 2>/dev/null)
# Check if the API call was successful
if [ $? -ne 0 ] || [ -z "$ALL_COMMENTS" ] || [ "$ALL_COMMENTS" = "[]" ]; then
# Try to get more specific error information
ERROR_MSG=$(gh api "$API_ENDPOINT" 2>&1)
if [[ "$ERROR_MSG" == *"404"* ]] || [[ "$ERROR_MSG" == *"Not Found"* ]]; then
echo -e "${RED}Error: PR #${PR_NUMBER} not found in ${REPO_OWNER}/${REPO_NAME}${NC}"
elif [[ "$ERROR_MSG" == *"401"* ]] || [[ "$ERROR_MSG" == *"403"* ]]; then
echo -e "${RED}Error: Access denied to ${REPO_OWNER}/${REPO_NAME}${NC}"
echo "Please check your GitHub permissions"
else
echo -e "${YELLOW}No comments found in PR #${PR_NUMBER}${NC}"
fi
exit 1
fi
# Filter comments by username if provided
if [ -n "$USERNAME" ]; then
FILTERED_COMMENTS=$(echo "$ALL_COMMENTS" | jq -c ".[] | select(.user.login == \"$USERNAME\")")
else
FILTERED_COMMENTS=$(echo "$ALL_COMMENTS" | jq -c ".[]")
fi
# Check if any comments match the filter
if [ -z "$FILTERED_COMMENTS" ]; then
if [ -n "$USERNAME" ]; then
echo -e "${YELLOW}No comments found from user '${USERNAME}' in PR #${PR_NUMBER}${NC}"
else
echo -e "${YELLOW}No comments found in PR #${PR_NUMBER}${NC}"
fi
exit 0
fi
# Display each comment
while IFS= read -r comment; do
display_comment "$comment"
done <<< "$FILTERED_COMMENTS"
# Display summary
echo -e "${YELLOW}═══════════════════════════════════════════════════${NC}"
if [ -n "$USERNAME" ]; then
COMMENT_COUNT=$(echo "$ALL_COMMENTS" | jq "[.[] | select(.user.login == \"$USERNAME\")] | length")
echo -e "${GREEN}Total comments by ${USERNAME}: ${BOLD}${COMMENT_COUNT}${NC}"
else
COMMENT_COUNT=$(echo "$ALL_COMMENTS" | jq ". | length")
echo -e "${GREEN}Total comments: ${BOLD}${COMMENT_COUNT}${NC}"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment