Skip to content

Instantly share code, notes, and snippets.

@akaszynski
Last active June 10, 2025 17:33
Show Gist options
  • Select an option

  • Save akaszynski/bec151cbe4812291bfbab2458dddc9f6 to your computer and use it in GitHub Desktop.

Select an option

Save akaszynski/bec151cbe4812291bfbab2458dddc9f6 to your computer and use it in GitHub Desktop.
Check if a PR is ready to merge using GH CLI and merge it if all checks pass.
# Monitors the current GitHub pull request and automatically merges it when ready.
#
# Conditions:
# - Runs up to 30 minutes, checking every 30 seconds (max 60 attempts).
# - Exits if any status checks fail.
# - Merges when the PR is open, mergeable, and has a clean merge state.
# - Uses squash merge and deletes the source branch.
#
# Output:
# - Logs status checks, elapsed time, merge success, or timeout.
automerge() {
echo "Starting auto-merge watcher (max 30 minutes)..."
pr=$(gh pr view --json number -q .number)
start_time=$(date +%s)
tput civis
trap 'tput cnorm; exit' INT TERM
for ((i=0; i<60; i++)); do
clear
elapsed=$(( $(date +%s) - start_time ))
minutes=$(( elapsed / 60 ))
seconds=$(( elapsed % 60 ))
printf "Check %02d/60 [%02d:%02d elapsed]: monitoring PR #%s\n\n" $((i+1)) $minutes $seconds "$pr"
raw=$(gh pr view --json statusCheckRollup -q \
'.statusCheckRollup[] | select(.name != null) | "\(.name)|\(.status)|\(.conclusion)"')
pending=0
failed=0
passed=0
printf "%-45s | %-9s\n" "Check" "Status"
printf -- "----------------------------------------------+-----------\n"
while IFS='|' read -r name status conclusion; do
color=""
reset=$(tput sgr0)
if [[ "$status" != "COMPLETED" ]]; then
((pending++))
color=$(tput setaf 3)
conclusion="PENDING"
elif [[ "$conclusion" == "FAILURE" ]]; then
((failed++))
color=$(tput setaf 1)
else
((passed++))
color=$(tput setaf 2)
fi
printf "%-45s | %s%-9s%s\n" "$name" "$color" "$conclusion" "$reset"
done <<< "$raw"
echo
if (( failed > 0 )); then
echo "$failed check(s) failed. Exiting."
tput cnorm
return 1
elif (( pending > 0 )); then
echo "$pending check(s) pending. Waiting 30 seconds..."
sleep 30
continue
else
echo "All checks passed."
fi
merge_ready=$(gh pr view --json mergeable,mergeStateStatus,state -q \
'select(.state=="OPEN" and .mergeable=="MERGEABLE" and .mergeStateStatus=="CLEAN")')
if [[ -n "$merge_ready" ]]; then
echo "PR #$pr is ready. Merging..."
gh pr merge --delete-branch --squash "$pr"
echo "Merge complete after $minutes minutes and $seconds seconds."
tput cnorm
return
fi
echo "Not ready. Sleeping 30s..."
sleep 30
done
echo "Timeout reached. PR not ready after 30 minutes."
tput cnorm
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment