diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml new file mode 100644 index 0000000000000..4e24aeac8e8f9 --- /dev/null +++ b/.github/workflows/dependabot-auto-merge.yml @@ -0,0 +1,95 @@ +name: Dependabot Auto-Merge + +on: + pull_request: + types: [opened, reopened, synchronize, ready_for_review] + pull_request_target: + types: [opened, reopened, synchronize, ready_for_review] + workflow_run: + workflows: [CI] + types: [completed] + branches: [main] + +permissions: + contents: write + pull-requests: write + checks: write + statuses: read + +jobs: + auto-merge: + if: github.event_name == 'pull_request_target' || (github.event.workflow_run && github.event.workflow_run.conclusion == 'success') + runs-on: blacksmith-16vcpu-ubuntu-2404 + timeout-minutes: 30 + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Get PR number + id: pr-number + run: | + if [ "${{ github.event_name }}" = "workflow_run" ]; then + # Find the PR that triggered the workflow run + PR_NUMBER=$(gh run view "${{ github.event.workflow_run.id }}" --json pullRequests --jq '.[0].number') + echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT + else + echo "pr_number=${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT + fi + + - name: Check if PR is from Dependabot + id: is-dependabot + run: | + PR_JSON=$(gh pr view "${{ steps.pr-number.outputs.pr_number }}" --json author,mergeable,mergeStateStatus,reviewDecision,labels) + + # Check if author is Dependabot + AUTHOR=$(echo "$PR_JSON" | jq -r '.author.login') + if [ "$AUTHOR" != "dependabot[bot]" ]; then + echo "not-dependabot" >> $GITHUB_OUTPUT + exit 0 + fi + + # Check if mergeable + MERGEABLE=$(echo "$PR_JSON" | jq -r '.mergeable') + if [ "$MERGEABLE" != "true" ]; then + echo "not-mergeable" >> $GITHUB_OUTPUT + exit 0 + fi + + # Check merge state status + MERGE_STATE=$(echo "$PR_JSON" | jq -r '.mergeStateStatus') + if [ "$MERGE_STATE" != "CLEAN" ]; then + echo "not-clean" >> $GITHUB_OUTPUT + exit 0 + fi + + # Check if all checks passed - get head SHA + HEAD_SHA=$(echo "$PR_JSON" | jq -r '.headRefOid') + + # Get check runs for the head SHA + CHECKS=$(gh api repos/${{ github.repository }}/commits/$HEAD_SHA/check-runs 2>/dev/null || echo '{"check_runs":[]}') + CHECK_COUNT=$(echo "$CHECKS" | jq '[.check_runs[] | select(.conclusion == "success")] | length') + TOTAL_CHECKS=$(echo "$CHECKS" | jq '.check_runs | length') + + if [ "$CHECK_COUNT" -eq 0 ] && [ "$TOTAL_CHECKS" -gt 0 ]; then + echo "checks-not-passed" >> $GITHUB_OUTPUT + exit 0 + fi + + # Also check status (for non-Check Suite workflows) + STATUS=$(gh api repos/${{ github.repository }}/commits/$HEAD_SHA/status --jq '.state') + if [ "$STATUS" != "success" ]; then + echo "status-not-success" >> $GITHUB_OUTPUT + exit 0 + fi + + echo "ready-to-merge" >> $GITHUB_OUTPUT + + - name: Enable auto-merge + if: steps.is-dependabot.outputs.ready-to-merge == 'ready-to-merge' + run: | + gh pr merge "${{ steps.pr-number.outputs.pr_number }}" --admin --auto + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file