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