Dependabot Auto-Merge #17
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
| name: Dependabot Auto-Merge | |
| # This workflow runs AFTER CI completes for Dependabot PRs. | |
| # It handles auto-merge AND notifications in sequence. | |
| on: | |
| workflow_run: | |
| workflows: ["CI"] | |
| types: | |
| - completed | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| jobs: | |
| process-dependabot: | |
| name: Process Dependabot PR | |
| runs-on: ubuntu-latest | |
| if: | | |
| github.event.workflow_run.actor.login == 'dependabot[bot]' && | |
| github.event.workflow_run.event == 'pull_request' | |
| steps: | |
| - name: Get PR information | |
| id: pr | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const { data: pullRequests } = await github.rest.pulls.list({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| state: 'open', | |
| head: `${context.repo.owner}:${context.payload.workflow_run.head_branch}` | |
| }); | |
| if (pullRequests.length > 0) { | |
| const pr = pullRequests[0]; | |
| core.setOutput('number', pr.number); | |
| core.setOutput('title', pr.title); | |
| core.setOutput('url', pr.html_url); | |
| core.setOutput('found', 'true'); | |
| // Check if it's a major update by looking at the PR title | |
| const majorPattern = /from \d+\.\d+\.\d+ to (\d+)\./; | |
| const match = pr.title.match(majorPattern); | |
| if (match) { | |
| const fromMajor = pr.title.match(/from (\d+)\./); | |
| const toMajor = match[1]; | |
| if (fromMajor && fromMajor[1] !== toMajor) { | |
| core.setOutput('is_major', 'true'); | |
| } else { | |
| core.setOutput('is_major', 'false'); | |
| } | |
| } else { | |
| core.setOutput('is_major', 'false'); | |
| } | |
| console.log(`Found PR #${pr.number}: ${pr.title}`); | |
| } else { | |
| core.setOutput('found', 'false'); | |
| console.log('No matching PR found'); | |
| } | |
| - name: Notify Slack - CI Failed | |
| if: | | |
| github.event.workflow_run.conclusion == 'failure' && | |
| steps.pr.outputs.found == 'true' | |
| run: | | |
| curl -X POST -H 'Content-type: application/json' --data '{ | |
| "attachments": [{ | |
| "color": "#ff0000", | |
| "blocks": [ | |
| { | |
| "type": "header", | |
| "text": {"type": "plain_text", "text": "🚨 Dependabot Update - CI Failed", "emoji": true} | |
| }, | |
| { | |
| "type": "section", | |
| "fields": [ | |
| {"type": "mrkdwn", "text": "*Repository:*\n${{ github.repository }}"}, | |
| {"type": "mrkdwn", "text": "*PR:*\n<${{ steps.pr.outputs.url }}|#${{ steps.pr.outputs.number }}>"} | |
| ] | |
| }, | |
| { | |
| "type": "section", | |
| "text": {"type": "mrkdwn", "text": "${{ steps.pr.outputs.title }}\n\n<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}|View CI Run> to investigate"} | |
| }, | |
| { | |
| "type": "context", | |
| "elements": [{"type": "mrkdwn", "text": "Manual intervention required"}] | |
| } | |
| ] | |
| }] | |
| }' "$SLACK_WEBHOOK" | |
| env: | |
| SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} | |
| - name: Skip major updates | |
| if: | | |
| github.event.workflow_run.conclusion == 'success' && | |
| steps.pr.outputs.found == 'true' && | |
| steps.pr.outputs.is_major == 'true' | |
| run: | | |
| echo "⚠️ Major version update detected - manual review required" | |
| echo "PR #${{ steps.pr.outputs.number }}: ${{ steps.pr.outputs.title }}" | |
| - name: Notify Slack - Major Update (Manual Review) | |
| if: | | |
| github.event.workflow_run.conclusion == 'success' && | |
| steps.pr.outputs.found == 'true' && | |
| steps.pr.outputs.is_major == 'true' | |
| run: | | |
| curl -X POST -H 'Content-type: application/json' --data '{ | |
| "attachments": [{ | |
| "color": "#ffa500", | |
| "blocks": [ | |
| { | |
| "type": "header", | |
| "text": {"type": "plain_text", "text": "⚠️ Major Update - Manual Review Required", "emoji": true} | |
| }, | |
| { | |
| "type": "section", | |
| "fields": [ | |
| {"type": "mrkdwn", "text": "*Repository:*\n${{ github.repository }}"}, | |
| {"type": "mrkdwn", "text": "*PR:*\n<${{ steps.pr.outputs.url }}|#${{ steps.pr.outputs.number }}>"} | |
| ] | |
| }, | |
| { | |
| "type": "section", | |
| "text": {"type": "mrkdwn", "text": "${{ steps.pr.outputs.title }}\n\nCI passed but this is a *major version update*. Please review changelog for breaking changes."} | |
| } | |
| ] | |
| }] | |
| }' "$SLACK_WEBHOOK" | |
| env: | |
| SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} | |
| - name: Enable auto-merge | |
| id: merge | |
| if: | | |
| github.event.workflow_run.conclusion == 'success' && | |
| steps.pr.outputs.found == 'true' && | |
| steps.pr.outputs.is_major != 'true' | |
| run: | | |
| echo "Enabling auto-merge for PR #${{ steps.pr.outputs.number }}" | |
| if gh pr merge ${{ steps.pr.outputs.number }} --auto --merge --repo ${{ github.repository }}; then | |
| echo "result=success" >> $GITHUB_OUTPUT | |
| else | |
| echo "result=failed" >> $GITHUB_OUTPUT | |
| fi | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Notify Slack - Auto-merge Enabled | |
| if: | | |
| github.event.workflow_run.conclusion == 'success' && | |
| steps.pr.outputs.found == 'true' && | |
| steps.pr.outputs.is_major != 'true' && | |
| steps.merge.outputs.result == 'success' | |
| run: | | |
| curl -X POST -H 'Content-type: application/json' --data '{ | |
| "attachments": [{ | |
| "color": "#36a64f", | |
| "blocks": [ | |
| { | |
| "type": "header", | |
| "text": {"type": "plain_text", "text": "✅ Dependabot Update - Auto-merge Enabled", "emoji": true} | |
| }, | |
| { | |
| "type": "section", | |
| "fields": [ | |
| {"type": "mrkdwn", "text": "*Repository:*\n${{ github.repository }}"}, | |
| {"type": "mrkdwn", "text": "*PR:*\n<${{ steps.pr.outputs.url }}|#${{ steps.pr.outputs.number }}>"} | |
| ] | |
| }, | |
| { | |
| "type": "section", | |
| "text": {"type": "mrkdwn", "text": "${{ steps.pr.outputs.title }}"} | |
| }, | |
| { | |
| "type": "context", | |
| "elements": [{"type": "mrkdwn", "text": "Will merge automatically when all checks pass"}] | |
| } | |
| ] | |
| }] | |
| }' "$SLACK_WEBHOOK" | |
| env: | |
| SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} | |
| - name: Notify Slack - Auto-merge Failed | |
| if: | | |
| github.event.workflow_run.conclusion == 'success' && | |
| steps.pr.outputs.found == 'true' && | |
| steps.pr.outputs.is_major != 'true' && | |
| steps.merge.outputs.result == 'failed' | |
| run: | | |
| curl -X POST -H 'Content-type: application/json' --data '{ | |
| "attachments": [{ | |
| "color": "#ff0000", | |
| "blocks": [ | |
| { | |
| "type": "header", | |
| "text": {"type": "plain_text", "text": "🚨 Auto-merge Failed", "emoji": true} | |
| }, | |
| { | |
| "type": "section", | |
| "fields": [ | |
| {"type": "mrkdwn", "text": "*Repository:*\n${{ github.repository }}"}, | |
| {"type": "mrkdwn", "text": "*PR:*\n<${{ steps.pr.outputs.url }}|#${{ steps.pr.outputs.number }}>"} | |
| ] | |
| }, | |
| { | |
| "type": "section", | |
| "text": {"type": "mrkdwn", "text": "${{ steps.pr.outputs.title }}\n\nCould not enable auto-merge. Manual intervention required."} | |
| } | |
| ] | |
| }] | |
| }' "$SLACK_WEBHOOK" | |
| env: | |
| SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} | |
| notify-merged: | |
| name: Notify Merged | |
| runs-on: ubuntu-latest | |
| if: | | |
| github.event.workflow_run.conclusion == 'success' && | |
| github.event.workflow_run.event == 'push' && | |
| contains(github.event.workflow_run.head_commit.message, 'dependabot') | |
| steps: | |
| - name: Send Slack notification (Merged) | |
| run: | | |
| curl -X POST -H 'Content-type: application/json' --data '{ | |
| "attachments": [{ | |
| "color": "#2eb886", | |
| "blocks": [ | |
| { | |
| "type": "header", | |
| "text": {"type": "plain_text", "text": "🎉 Dependencies Updated Successfully", "emoji": true} | |
| }, | |
| { | |
| "type": "section", | |
| "fields": [ | |
| {"type": "mrkdwn", "text": "*Repository:*\n${{ github.repository }}"}, | |
| {"type": "mrkdwn", "text": "*Commit:*\n<${{ github.server_url }}/${{ github.repository }}/commit/${{ github.event.workflow_run.head_sha }}|View Commit>"} | |
| ] | |
| }, | |
| { | |
| "type": "context", | |
| "elements": [{"type": "mrkdwn", "text": "Merged to main"}] | |
| } | |
| ] | |
| }] | |
| }' "$SLACK_WEBHOOK" | |
| env: | |
| SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} |