1+ name : π€ Dependabot Auto-merge
2+
3+ on :
4+ pull_request_target :
5+ types : [opened, synchronize, reopened, ready_for_review]
6+
7+ permissions :
8+ contents : write
9+ pull-requests : write
10+
11+ jobs :
12+ # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
13+ # π€ DEPENDABOT PR HANDLING
14+ # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
15+ dependabot-auto-merge :
16+ name : π€ Dependabot Auto-merge
17+ runs-on : ubuntu-latest
18+ if : github.actor == 'dependabot[bot]'
19+ timeout-minutes : 10
20+
21+ steps :
22+ - name : π₯ Checkout PR
23+ uses : actions/checkout@v4
24+ with :
25+ token : ${{ secrets.GITHUB_TOKEN }}
26+
27+ - name : π Analyze Dependabot PR
28+ id : analyze
29+ run : |
30+ echo "π€ Analyzing Dependabot PR..."
31+
32+ # Get PR details
33+ PR_TITLE="${{ github.event.pull_request.title }}"
34+ PR_BODY="${{ github.event.pull_request.body }}"
35+
36+ echo "π PR Title: $PR_TITLE"
37+ echo "pr_title=$PR_TITLE" >> $GITHUB_OUTPUT
38+
39+ # Determine update type
40+ if echo "$PR_TITLE" | grep -q "Bump.*from.*to"; then
41+ echo "π Standard dependency update detected"
42+ echo "update_type=dependency" >> $GITHUB_OUTPUT
43+ elif echo "$PR_TITLE" | grep -qi "security"; then
44+ echo "π Security update detected"
45+ echo "update_type=security" >> $GITHUB_OUTPUT
46+ else
47+ echo "β Unknown update type"
48+ echo "update_type=unknown" >> $GITHUB_OUTPUT
49+ fi
50+
51+ - name : π Check if CI passed
52+ uses : actions/github-script@v7
53+ id : ci-check
54+ with :
55+ script : |
56+ const { data: checks } = await github.rest.checks.listForRef({
57+ owner: context.repo.owner,
58+ repo: context.repo.repo,
59+ ref: context.payload.pull_request.head.sha,
60+ });
61+
62+ // Look for main CI workflow
63+ const ciChecks = checks.check_runs.filter(check =>
64+ check.name.includes('Quality Gate') ||
65+ check.name.includes('Code Quality')
66+ );
67+
68+ const allPassed = ciChecks.every(check => check.status === 'completed' && check.conclusion === 'success');
69+ const anyFailed = ciChecks.some(check => check.conclusion === 'failure');
70+
71+ if (anyFailed) {
72+ console.log('β Some CI checks failed');
73+ core.setOutput('ci_status', 'failed');
74+ } else if (allPassed && ciChecks.length > 0) {
75+ console.log('β
All CI checks passed');
76+ core.setOutput('ci_status', 'passed');
77+ } else {
78+ console.log('β³ CI checks still running or not found');
79+ core.setOutput('ci_status', 'pending');
80+ }
81+
82+ - name : π― Auto-merge Decision
83+ id : decision
84+ run : |
85+ CI_STATUS="${{ steps.ci-check.outputs.ci_status }}"
86+ UPDATE_TYPE="${{ steps.analyze.outputs.update_type }}"
87+
88+ echo "π― Making auto-merge decision..."
89+ echo " CI Status: $CI_STATUS"
90+ echo " Update Type: $UPDATE_TYPE"
91+
92+ SHOULD_MERGE="false"
93+
94+ # Auto-merge conditions
95+ if [[ "$CI_STATUS" == "passed" ]]; then
96+ if [[ "$UPDATE_TYPE" == "security" ]]; then
97+ echo "π Security update with passing CI - auto-merging"
98+ SHOULD_MERGE="true"
99+ elif [[ "$UPDATE_TYPE" == "dependency" ]]; then
100+ # Check if it's a patch/minor update (safer)
101+ if echo "${{ steps.analyze.outputs.pr_title }}" | grep -E "(patch|minor)" > /dev/null; then
102+ echo "π Patch/minor update with passing CI - auto-merging"
103+ SHOULD_MERGE="true"
104+ else
105+ echo "β οΈ Major update - requires manual review"
106+ SHOULD_MERGE="false"
107+ fi
108+ fi
109+ else
110+ echo "β CI not passed - skipping auto-merge"
111+ SHOULD_MERGE="false"
112+ fi
113+
114+ echo "should_merge=$SHOULD_MERGE" >> $GITHUB_OUTPUT
115+ echo "π― Decision: Auto-merge = $SHOULD_MERGE"
116+
117+ - name : β
Auto-merge Dependabot PR
118+ if : steps.decision.outputs.should_merge == 'true'
119+ uses : actions/github-script@v7
120+ with :
121+ script : |
122+ console.log('β
Auto-merging Dependabot PR...');
123+
124+ await github.rest.pulls.merge({
125+ owner: context.repo.owner,
126+ repo: context.repo.repo,
127+ pull_number: context.payload.pull_request.number,
128+ commit_title: `π€ ${context.payload.pull_request.title}`,
129+ commit_message: `Auto-merged by Dependabot workflow\n\n${context.payload.pull_request.body}`,
130+ merge_method: 'squash'
131+ });
132+
133+ console.log('π Dependabot PR auto-merged successfully!');
134+
135+ - name : π¬ Add Review Comment
136+ if : steps.decision.outputs.should_merge == 'false'
137+ uses : actions/github-script@v7
138+ with :
139+ script : |
140+ const ciStatus = '${{ steps.ci-check.outputs.ci_status }}';
141+ const updateType = '${{ steps.analyze.outputs.update_type }}';
142+
143+ let message = '## π€ Dependabot Auto-merge Analysis\n\n';
144+
145+ if (ciStatus === 'failed') {
146+ message += 'β **CI checks failed** - This PR requires manual review and fixes.\n\n';
147+ } else if (ciStatus === 'pending') {
148+ message += 'β³ **CI checks still running** - Auto-merge will be reconsidered once checks complete.\n\n';
149+ } else if (updateType === 'dependency' && !`${{ steps.analyze.outputs.pr_title }}`.match(/(patch|minor)/)) {
150+ message += 'β οΈ **Major version update detected** - This requires manual review for potential breaking changes.\n\n';
151+ } else {
152+ message += 'βΉοΈ **Manual review required** - This PR did not meet auto-merge criteria.\n\n';
153+ }
154+
155+ message += '### π Auto-merge Criteria\n';
156+ message += '- β
Security updates with passing CI\n';
157+ message += '- β
Patch/minor dependency updates with passing CI\n';
158+ message += '- β Major version updates (require manual review)\n';
159+ message += '- β Any PR with failing CI checks\n\n';
160+ message += '**Note:** Production deployment is automatically skipped for all Dependabot commits for security.';
161+
162+ await github.rest.issues.createComment({
163+ owner: context.repo.owner,
164+ repo: context.repo.repo,
165+ issue_number: context.payload.pull_request.number,
166+ body: message
167+ });
168+
169+ # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
170+ # π SUMMARY REPORTING
171+ # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
172+ summary :
173+ name : π Dependabot Summary
174+ runs-on : ubuntu-latest
175+ needs : [dependabot-auto-merge]
176+ if : always() && github.actor == 'dependabot[bot]'
177+
178+ steps :
179+ - name : π Generate Summary
180+ run : |
181+ echo "## π€ Dependabot PR Summary" >> $GITHUB_STEP_SUMMARY
182+ echo "" >> $GITHUB_STEP_SUMMARY
183+ echo "**PR:** ${{ github.event.pull_request.title }}" >> $GITHUB_STEP_SUMMARY
184+ echo "**Author:** ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
185+ echo "**Status:** ${{ needs.dependabot-auto-merge.result }}" >> $GITHUB_STEP_SUMMARY
186+ echo "" >> $GITHUB_STEP_SUMMARY
187+
188+ if [[ "${{ needs.dependabot-auto-merge.result }}" == "success" ]]; then
189+ echo "β
**Dependabot PR processed successfully**" >> $GITHUB_STEP_SUMMARY
190+ echo "" >> $GITHUB_STEP_SUMMARY
191+ echo "### π‘οΈ Security Note" >> $GITHUB_STEP_SUMMARY
192+ echo "Production deployment is **automatically skipped** for Dependabot commits." >> $GITHUB_STEP_SUMMARY
193+ echo "Use the Manual Deployment workflow if you need to deploy after testing." >> $GITHUB_STEP_SUMMARY
194+ else
195+ echo "β οΈ **Dependabot PR requires attention**" >> $GITHUB_STEP_SUMMARY
196+ fi
0 commit comments