mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
155 lines
5.9 KiB
YAML
155 lines
5.9 KiB
YAML
name: Auto Merge Approved PRs
|
|
|
|
on:
|
|
schedule:
|
|
- cron: '0 */2 * * *' # Every 2 hours
|
|
workflow_dispatch: # Allow manual triggering
|
|
|
|
permissions:
|
|
contents: write
|
|
pull-requests: write
|
|
actions: read
|
|
|
|
jobs:
|
|
auto-merge-prs:
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
token: ${{ secrets.PAT_TOKEN }}
|
|
|
|
- name: Configure git
|
|
run: |
|
|
git config --global user.email "action@github.com"
|
|
git config --global user.name "GitHub Action"
|
|
|
|
- name: Check for running workflows
|
|
id: check_workflows
|
|
run: |
|
|
# Get all running workflows except this one
|
|
running_workflows=$(gh run list --status in_progress --json workflowName,name --repo "$GITHUB_REPOSITORY" --jq '.[].name' | grep -v "Auto Merge Approved PRs" | wc -l)
|
|
echo "running_workflows=$running_workflows" >> $GITHUB_OUTPUT
|
|
|
|
if [ "$running_workflows" -gt 0 ]; then
|
|
echo "Found $running_workflows running workflows. Exiting to avoid conflicts."
|
|
echo "should_continue=false" >> $GITHUB_OUTPUT
|
|
else
|
|
echo "No other workflows running. Proceeding with auto-merge."
|
|
echo "should_continue=true" >> $GITHUB_OUTPUT
|
|
fi
|
|
env:
|
|
GH_TOKEN: ${{ secrets.PAT_TOKEN }}
|
|
|
|
- name: Find and merge approved PRs
|
|
if: steps.check_workflows.outputs.should_continue == 'true'
|
|
run: |
|
|
authorized_user="carlospolop"
|
|
max_merges=2
|
|
|
|
echo "Authorized user: $authorized_user"
|
|
echo "Looking for PRs with exact comment 'merge' from $authorized_user..."
|
|
|
|
# Get all open PRs
|
|
prs=$(gh pr list --state open --json number,title,url --repo "$GITHUB_REPOSITORY")
|
|
|
|
if [ "$prs" = "[]" ]; then
|
|
echo "No open PRs found."
|
|
exit 0
|
|
fi
|
|
|
|
# Create a temp file to track merge count
|
|
echo "0" > /tmp/merged_count
|
|
|
|
# Process each PR
|
|
echo "$prs" | jq -r '.[] | @base64' | while IFS= read -r pr_data; do
|
|
current_count=$(cat /tmp/merged_count)
|
|
if [ "$current_count" -ge "$max_merges" ]; then
|
|
echo "Reached maximum merge limit ($max_merges). Stopping."
|
|
break
|
|
fi
|
|
|
|
pr_info=$(echo "$pr_data" | base64 --decode)
|
|
pr_number=$(echo "$pr_info" | jq -r '.number')
|
|
pr_title=$(echo "$pr_info" | jq -r '.title')
|
|
pr_url=$(echo "$pr_info" | jq -r '.url')
|
|
|
|
echo "Checking PR #$pr_number: $pr_title"
|
|
|
|
# Get all comments for this PR
|
|
comments=$(gh pr view "$pr_number" --json comments --jq '.comments[]' --repo "$GITHUB_REPOSITORY")
|
|
|
|
# Print all comment authors for debugging
|
|
echo "Comments in PR #$pr_number:"
|
|
echo "$comments" | jq -r '" - Author: " + .author.login + " | Comment: " + (.body | split("\n")[0] | .[0:100])'
|
|
|
|
# Check if any comment from carlospolop contains exactly "merge"
|
|
has_merge_comment=false
|
|
echo "$comments" | jq -r '.author.login + "|" + .body' | while IFS='|' read -r comment_author comment_body; do
|
|
if [ "$comment_author" = "$authorized_user" ]; then
|
|
if echo "$comment_body" | grep -iExq "merge"; then
|
|
echo "Found exact 'merge' comment from $authorized_user in PR #$pr_number"
|
|
echo "true" > /tmp/has_merge_comment_$pr_number
|
|
break
|
|
fi
|
|
fi
|
|
done
|
|
|
|
if [ -f "/tmp/has_merge_comment_$pr_number" ]; then
|
|
has_merge_comment=true
|
|
fi
|
|
|
|
if [ "$has_merge_comment" = true ]; then
|
|
echo "Attempting to merge PR #$pr_number..."
|
|
|
|
# Get PR details including head branch
|
|
pr_details=$(gh pr view "$pr_number" --json headRefName,baseRefName --repo "$GITHUB_REPOSITORY")
|
|
head_branch=$(echo "$pr_details" | jq -r '.headRefName')
|
|
base_branch=$(echo "$pr_details" | jq -r '.baseRefName')
|
|
|
|
# --- Polling for non-UNKNOWN mergeable status ---
|
|
max_retries=10
|
|
retry=0
|
|
while true; do
|
|
pr_mergeable=$(gh pr view "$pr_number" --json mergeable --jq '.mergeable' --repo "$GITHUB_REPOSITORY")
|
|
if [ "$pr_mergeable" != "UNKNOWN" ]; then
|
|
break
|
|
fi
|
|
if [ $retry -ge $max_retries ]; then
|
|
echo "Timeout: mergeable status is still UNKNOWN after $max_retries retries"
|
|
break
|
|
fi
|
|
echo "mergeable status UNKNOWN, retrying in 2s..."
|
|
sleep 2
|
|
retry=$((retry + 1))
|
|
done
|
|
|
|
if [ "$pr_mergeable" = "MERGEABLE" ]; then
|
|
if gh pr merge "$pr_number" --merge --delete-branch --repo "$GITHUB_REPOSITORY"; then
|
|
echo "Successfully merged PR #$pr_number: $pr_title"
|
|
current_count=$(cat /tmp/merged_count)
|
|
echo $((current_count + 1)) > /tmp/merged_count
|
|
else
|
|
echo "Failed to merge PR #$pr_number: $pr_title"
|
|
fi
|
|
elif [ "$pr_mergeable" = "CONFLICTED" ] || [ "$pr_mergeable" = "CONFLICTING" ]; then
|
|
echo "PR #$pr_number has conflicts. Skipping auto-merge so it can be resolved manually."
|
|
else
|
|
echo "PR #$pr_number is not mergeable (status: $pr_mergeable)"
|
|
fi
|
|
else
|
|
echo "No exact 'merge' comment found from $authorized_user in PR #$pr_number"
|
|
fi
|
|
|
|
rm -f "/tmp/has_merge_comment_$pr_number"
|
|
done
|
|
|
|
final_count=$(cat /tmp/merged_count)
|
|
echo "Auto-merge process completed. Merged $final_count PRs."
|
|
rm -f /tmp/merged_count
|
|
|
|
env:
|
|
GH_TOKEN: ${{ secrets.PAT_TOKEN }}
|