Add prch.sh
This commit is contained in:
parent
a1b6363c73
commit
9339fec374
1 changed files with 219 additions and 0 deletions
219
prch.sh
Normal file
219
prch.sh
Normal file
|
|
@ -0,0 +1,219 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Pretty display for GitHub PR checks using gum
|
||||||
|
# Usage: ./gh-pr-checks-pretty.sh <PR_NUMBER> [--watch]
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
WATCH_MODE=false
|
||||||
|
PR_NUMBER=""
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
--watch|-w)
|
||||||
|
WATCH_MODE=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
PR_NUMBER=$1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Check if PR number is provided
|
||||||
|
if [ -z "$PR_NUMBER" ]; then
|
||||||
|
echo "Usage: $0 <PR_NUMBER> [--watch]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if gum is installed
|
||||||
|
if ! command -v gum &> /dev/null; then
|
||||||
|
echo "Error: gum is not installed. Install it from https://github.com/charmbracelet/gum"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if gh is installed
|
||||||
|
if ! command -v gh &> /dev/null; then
|
||||||
|
echo "Error: gh (GitHub CLI) is not installed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Function to display checks
|
||||||
|
display_checks() {
|
||||||
|
# Get PR details including reviews, comments, and state
|
||||||
|
PR_INFO=$(gh pr view "$PR_NUMBER" --json number,title,url,state,isDraft,reviews,comments)
|
||||||
|
PR_TITLE=$(echo "$PR_INFO" | jq -r '.title')
|
||||||
|
PR_URL=$(echo "$PR_INFO" | jq -r '.url')
|
||||||
|
PR_STATE=$(echo "$PR_INFO" | jq -r '.state')
|
||||||
|
PR_DRAFT=$(echo "$PR_INFO" | jq -r '.isDraft')
|
||||||
|
|
||||||
|
# Count comments
|
||||||
|
COMMENT_COUNT=$(echo "$PR_INFO" | jq '.comments | length')
|
||||||
|
|
||||||
|
# Get approval status
|
||||||
|
APPROVED_COUNT=$(echo "$PR_INFO" | jq '[.reviews[] | select(.state == "APPROVED")] | length')
|
||||||
|
CHANGES_REQUESTED=$(echo "$PR_INFO" | jq '[.reviews[] | select(.state == "CHANGES_REQUESTED")] | length')
|
||||||
|
|
||||||
|
# Determine PR status string
|
||||||
|
if [ "$PR_DRAFT" = "true" ]; then
|
||||||
|
PR_STATUS="Draft"
|
||||||
|
STATUS_COLOR="8" # Gray
|
||||||
|
elif [ "$PR_STATE" = "MERGED" ]; then
|
||||||
|
PR_STATUS="Merged"
|
||||||
|
STATUS_COLOR="13" # Purple
|
||||||
|
elif [ "$PR_STATE" = "CLOSED" ]; then
|
||||||
|
PR_STATUS="Closed"
|
||||||
|
STATUS_COLOR="9" # Red
|
||||||
|
else
|
||||||
|
PR_STATUS="Open"
|
||||||
|
STATUS_COLOR="10" # Green
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Determine approval string
|
||||||
|
if [ "$CHANGES_REQUESTED" -gt 0 ]; then
|
||||||
|
APPROVAL_STATUS="Changes requested"
|
||||||
|
APPROVAL_COLOR="9" # Red
|
||||||
|
elif [ "$APPROVED_COUNT" -gt 0 ]; then
|
||||||
|
APPROVAL_STATUS="✓ Approved ($APPROVED_COUNT)"
|
||||||
|
APPROVAL_COLOR="10" # Green
|
||||||
|
else
|
||||||
|
APPROVAL_STATUS="No reviews"
|
||||||
|
APPROVAL_COLOR="8" # Gray
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get checks with full details
|
||||||
|
CHECKS_JSON=$(gh pr checks "$PR_NUMBER" --json bucket,name,link,completedAt,description,state)
|
||||||
|
|
||||||
|
# Count all checks
|
||||||
|
TOTAL_ALL=$(echo "$CHECKS_JSON" | jq '. | length')
|
||||||
|
SUCCESSFUL_ALL=$(echo "$CHECKS_JSON" | jq '[.[] | select(.state == "SUCCESS")] | length')
|
||||||
|
FAILING_ALL=$(echo "$CHECKS_JSON" | jq '[.[] | select(.state == "FAILURE")] | length')
|
||||||
|
PENDING_ALL=$(echo "$CHECKS_JSON" | jq '[.[] | select(.state == "PENDING" or .state == "IN_PROGRESS")] | length')
|
||||||
|
|
||||||
|
# Filter checks: only include Terraform results, failures, or ongoing checks
|
||||||
|
FILTERED_JSON=$(echo "$CHECKS_JSON" | jq '[.[] | select(
|
||||||
|
(.description | contains("Run not triggered") | not) and
|
||||||
|
(
|
||||||
|
(.description | contains("Terraform plan:")) or
|
||||||
|
(.state == "FAILURE") or
|
||||||
|
(.state == "PENDING") or
|
||||||
|
(.state == "IN_PROGRESS")
|
||||||
|
)
|
||||||
|
)]')
|
||||||
|
|
||||||
|
# Count filtered checks
|
||||||
|
TOTAL=$(echo "$FILTERED_JSON" | jq '. | length')
|
||||||
|
HIDDEN=$((SUCCESSFUL_ALL - TOTAL))
|
||||||
|
|
||||||
|
# Clear screen in watch mode
|
||||||
|
if [ "$WATCH_MODE" = true ]; then
|
||||||
|
clear
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Display header
|
||||||
|
gum style \
|
||||||
|
--border double \
|
||||||
|
--border-foreground 212 \
|
||||||
|
--padding "1 2" \
|
||||||
|
--margin "1 0" \
|
||||||
|
--align center \
|
||||||
|
"#$PR_NUMBER | $PR_TITLE" "$PR_URL"
|
||||||
|
|
||||||
|
# Display PR status, approval, and comments
|
||||||
|
echo ""
|
||||||
|
gum style --foreground "$STATUS_COLOR" --bold "Status: $PR_STATUS" | tr '\n' ' '
|
||||||
|
echo -n " | "
|
||||||
|
gum style --foreground "$APPROVAL_COLOR" "Reviews: $APPROVAL_STATUS" | tr '\n' ' '
|
||||||
|
echo -n " | "
|
||||||
|
gum style --foreground 12 "Comments: $COMMENT_COUNT"
|
||||||
|
|
||||||
|
# Display summary statistics
|
||||||
|
echo ""
|
||||||
|
if [ "$TOTAL" -eq 0 ]; then
|
||||||
|
gum style --foreground 8 "Total: $TOTAL_ALL | Success: $SUCCESSFUL_ALL | Failed: $FAILING_ALL | Pending: $PENDING_ALL"
|
||||||
|
echo ""
|
||||||
|
gum style \
|
||||||
|
--foreground 10 \
|
||||||
|
--bold \
|
||||||
|
"✓ All checks passed"
|
||||||
|
|
||||||
|
if [ "$WATCH_MODE" = false ]; then
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
gum style --foreground 8 "Total: $TOTAL_ALL | Success: $SUCCESSFUL_ALL ($HIDDEN hidden) | Failed: $FAILING_ALL | Pending: $PENDING_ALL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Prepare table data
|
||||||
|
TABLE_DATA=$(echo "$FILTERED_JSON" | jq -r '
|
||||||
|
[" STATUS", "NAME", "DESCRIPTION", "URL"],
|
||||||
|
[" ──────", "────", "───────────", "───"],
|
||||||
|
(.[] | [
|
||||||
|
" " + (if .state == "SUCCESS" then "✓"
|
||||||
|
elif .state == "FAILURE" then "✗"
|
||||||
|
elif .state == "PENDING" or .state == "IN_PROGRESS" then "⏳"
|
||||||
|
else "○" end),
|
||||||
|
# Shorten name - extract workspace from Terraform Cloud checks
|
||||||
|
(if .name | startswith("Terraform Cloud/") then
|
||||||
|
"TF - " + (.name | split("/") | last)
|
||||||
|
else
|
||||||
|
.name
|
||||||
|
end),
|
||||||
|
# Format description - compact Terraform plan output
|
||||||
|
(if .description and (.description | contains("Terraform plan:")) then
|
||||||
|
(.description |
|
||||||
|
gsub("Terraform plan: "; "") |
|
||||||
|
gsub(" to add"; "") |
|
||||||
|
gsub(" to change"; "") |
|
||||||
|
gsub(" to destroy\\."; "") |
|
||||||
|
gsub(", "; " ") |
|
||||||
|
split(" ") |
|
||||||
|
"🟢+" + .[0] + " 🛠~" + .[1] + " 🗑-" + .[2])
|
||||||
|
else
|
||||||
|
(.description // "No description" |
|
||||||
|
if (. | length) > 50 then .[0:47] + "..." else . end)
|
||||||
|
end),
|
||||||
|
# Full URL
|
||||||
|
(.link // "")
|
||||||
|
]) | @tsv
|
||||||
|
' | column -t -s $'\t')
|
||||||
|
|
||||||
|
# Display table with gum
|
||||||
|
echo "$TABLE_DATA" | gum format
|
||||||
|
|
||||||
|
# Show timestamp in watch mode
|
||||||
|
if [ "$WATCH_MODE" = true ]; then
|
||||||
|
echo ""
|
||||||
|
gum style --foreground 8 --italic "Last updated: $(date '+%Y-%m-%d %H:%M:%S')"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run in watch mode or single run
|
||||||
|
if [ "$WATCH_MODE" = true ]; then
|
||||||
|
# Trap Ctrl+C to exit gracefully
|
||||||
|
trap 'echo ""; echo "Watch mode stopped."; exit 0' INT
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
display_checks
|
||||||
|
|
||||||
|
# Check if all checks are complete
|
||||||
|
CHECKS_JSON=$(gh pr checks "$PR_NUMBER" --json state)
|
||||||
|
PENDING_COUNT=$(echo "$CHECKS_JSON" | jq '[.[] | select(.state == "PENDING" or .state == "IN_PROGRESS")] | length')
|
||||||
|
|
||||||
|
if [ "$PENDING_COUNT" -eq 0 ]; then
|
||||||
|
echo ""
|
||||||
|
gum style --foreground 10 --bold "All checks complete!"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
sleep 10
|
||||||
|
done
|
||||||
|
else
|
||||||
|
display_checks
|
||||||
|
fi
|
||||||
Loading…
Reference in a new issue