Last active
June 10, 2025 17:33
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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