Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 80 additions & 18 deletions .github/workflows/dependabot-auto-merge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,50 @@ permissions:
jobs:
auto-merge:
runs-on: ubuntu-latest
if: github.actor == 'dependabot[bot]' && github.event.pull_request.mergeable_state == 'clean' && !github.event.pull_request.draft
# Only run for Dependabot PRs that are not drafts
# Check PR author identity to handle reopened PRs
if: github.event.pull_request.user.login == 'dependabot[bot]' && !github.event.pull_request.draft

steps:
- name: Wait for CI checks to complete
- name: Check if PR is from a fork
id: check-fork
run: |
echo "PR head repo: ${{ github.event.pull_request.head.repo.full_name }}"
echo "Base repo: ${{ github.repository }}"

# Check if PR is from the same repository (not a fork)
if [[ "${{ github.event.pull_request.head.repo.full_name }}" == "${{ github.repository }}" ]]; then
echo "PR is from the same repository - safe to proceed"
echo "is_fork=false" >> $GITHUB_OUTPUT
else
echo "PR is from a fork - skipping for security"
echo "is_fork=true" >> $GITHUB_OUTPUT
fi

- name: Check if PR is mergeable via API
id: check-mergeable
if: steps.check-fork.outputs.is_fork == 'false'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PR_NUM=${{ github.event.pull_request.number }}
echo "Checking PR #$PR_NUM mergeable state via API..."

# Query API for fresh mergeable state (normalize to lowercase for comparison)
PR_STATE=$(gh pr view "$PR_NUM" --json mergeStateStatus -q '.mergeStateStatus' | tr '[:upper:]' '[:lower:]')
echo "Current mergeable state from API: $PR_STATE"

# Check if PR is in a mergeable state
if [[ "$PR_STATE" == "clean" || "$PR_STATE" == "unstable" || "$PR_STATE" == "has_hooks" ]]; then
echo "PR is in mergeable state: $PR_STATE"
echo "mergeable=true" >> $GITHUB_OUTPUT
else
echo "PR is not in mergeable state yet: $PR_STATE"
echo "mergeable=false" >> $GITHUB_OUTPUT
fi

- name: Wait for required checks if not mergeable
if: steps.check-fork.outputs.is_fork == 'false' && steps.check-mergeable.outputs.mergeable == 'false'
uses: fountainhead/action-wait-for-check@v1.2.0
id: wait-for-ci
with:
Expand All @@ -25,30 +65,52 @@ jobs:
timeoutSeconds: 600
intervalSeconds: 10

- name: Re-check mergeable state after waiting
if: steps.check-fork.outputs.is_fork == 'false' && steps.check-mergeable.outputs.mergeable == 'false'
id: recheck-mergeable
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "Re-checking mergeable state via API..."
PR_NUM=${{ github.event.pull_request.number }}
# Use gh pr view to get fresh mergeable state (normalize to lowercase)
PR_STATE=$(gh pr view "$PR_NUM" --json mergeStateStatus -q '.mergeStateStatus' | tr '[:upper:]' '[:lower:]')
echo "Current mergeable state from API: $PR_STATE"

if [[ "$PR_STATE" == "clean" || "$PR_STATE" == "unstable" || "$PR_STATE" == "has_hooks" ]]; then
echo "mergeable=true" >> $GITHUB_OUTPUT
else
echo "mergeable=false" >> $GITHUB_OUTPUT
fi

- name: Auto-merge Dependabot PR
if: steps.wait-for-ci.outputs.conclusion == 'success'
if: steps.check-fork.outputs.is_fork == 'false' && (steps.check-mergeable.outputs.mergeable == 'true' || steps.recheck-mergeable.outputs.mergeable == 'true')
run: |
set -e
echo "CI checks passed. Auto-merging Dependabot PR #${{ github.event.pull_request.number }}"
PR_NUM=${{ github.event.pull_request.number }}
echo "Processing Dependabot PR #$PR_NUM"

# Approve the PR first
if ! gh pr review ${{ github.event.pull_request.number }} --approve --body "✅ CI checks passed! Auto-merging this Dependabot PR."; then
echo "Failed to approve PR. Exiting."
exit 1
# Check current review status
REVIEW_DECISION=$(gh pr view $PR_NUM --json reviewDecision -q '.reviewDecision')
echo "Current review decision: $REVIEW_DECISION"

# Approve the PR only if not already approved
if [[ "$REVIEW_DECISION" != "APPROVED" ]]; then
gh pr review $PR_NUM --approve --body "✅ CI checks passed! Auto-merging this Dependabot PR."
else
echo "PR already approved"
fi

# Enable auto-merge
if ! gh pr merge --auto --merge ${{ github.event.pull_request.number }}; then
echo "Failed to enable auto-merge. Checking if already enabled..."
# Check if auto-merge is already enabled
if gh pr view ${{ github.event.pull_request.number }} --json autoMergeRequest --jq '.autoMergeRequest' | grep -q "null"; then
echo "Auto-merge failed and is not enabled. Manual intervention required."
exit 1
else
echo "Auto-merge is already enabled."
fi
gh pr merge --auto --merge $PR_NUM

# Verify auto-merge was enabled
AUTO_MERGE=$(gh pr view $PR_NUM --json autoMergeRequest -q '.autoMergeRequest')
if [[ "$AUTO_MERGE" == "null" || -z "$AUTO_MERGE" ]]; then
echo "ERROR: Auto-merge was not enabled properly"
exit 1
fi

echo "Auto-merge successfully enabled for PR #${{ github.event.pull_request.number }}"
echo "Auto-merge processing complete for PR #$PR_NUM"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Loading
Loading