1+ name : auto-merge dependabot updates
2+
3+ on :
4+ pull_request_target :
5+ branches : [ main ]
6+ types :
7+ - opened
8+ - synchronize
9+ - reopened
10+ - ready_for_review
11+
12+ permissions :
13+ pull-requests : write
14+ contents : write
15+
16+ jobs :
17+ dependabot-merge :
18+ runs-on : ubuntu-latest
19+ if : ${{ github.actor == 'dependabot[bot]' }}
20+
21+ steps :
22+ - name : Dependabot metadata
23+ id : metadata
24+ uses :
dependabot/[email protected] 25+ with :
26+ github-token : " ${{ secrets.DEPENDABOT_PAT }}" # Using PAT for enhanced features, alert-lookup, and compat-lookup
27+ alert-lookup : true # Enable security alert information
28+ compat-lookup : true # Enable compatibility score checking
29+
30+ - name : Check security and compatibility
31+ id : security_check
32+ run : |
33+ DEPS_JSON='${{ steps.metadata.outputs.updated-dependencies-json }}'
34+
35+ # Perform checks
36+ if [ "${{ steps.metadata.outputs.alert-state }}" = "OPEN" ]; then
37+ echo "⚠️ Security alert detected (GHSA: ${{ steps.metadata.outputs.ghsa-id }})"
38+ echo "CVSS Score: ${{ steps.metadata.outputs.cvss }}"
39+ echo "is_security_update=true" >> $GITHUB_OUTPUT
40+ else
41+ echo "is_security_update=false" >> $GITHUB_OUTPUT
42+ fi
43+
44+ if [ "${{ steps.metadata.outputs.compatibility-score }}" -lt 75 ]; then
45+ echo "⚠️ Low compatibility score: ${{ steps.metadata.outputs.compatibility-score }}"
46+ echo "is_compatible=false" >> $GITHUB_OUTPUT
47+ else
48+ echo "is_compatible=true" >> $GITHUB_OUTPUT
49+ fi
50+
51+ if [ "${{ steps.metadata.outputs.maintainer-changes }}" = "true" ]; then
52+ echo "⚠️ Maintainer changes detected"
53+ echo "has_maintainer_changes=true" >> $GITHUB_OUTPUT
54+ else
55+ echo "has_maintainer_changes=false" >> $GITHUB_OUTPUT
56+ fi
57+
58+ - name : Checkout repository
59+ uses : actions/checkout@v4
60+ if : ${{ steps.metadata.outputs.package-ecosystem == 'gomod' }}
61+
62+ - name : Setup Go
63+ uses : actions/setup-go@v5
64+ if : ${{ steps.metadata.outputs.package-ecosystem == 'gomod' }}
65+ with :
66+ go-version : ' stable'
67+
68+ - name : Process Go dependencies
69+ if : ${{ steps.metadata.outputs.package-ecosystem == 'gomod' }}
70+ run : |
71+ log_update_details() {
72+ local pr_number=$1
73+ echo "::group::Dependency Update Details for PR #$pr_number"
74+ echo "🔄 Dependencies: ${{ steps.metadata.outputs.dependency-names }}"
75+ echo "📦 Type: ${{ steps.metadata.outputs.dependency-type }}"
76+ echo "📈 Version: ${{ steps.metadata.outputs.previous-version }} → ${{ steps.metadata.outputs.new-version }}"
77+ echo "📂 Directory: ${{ steps.metadata.outputs.directory }}"
78+ [ "${{ steps.security_check.outputs.is_security_update }}" = "true" ] && \
79+ echo "🚨 Security update (CVSS: ${{ steps.metadata.outputs.cvss }})"
80+ echo "::endgroup::"
81+ }
82+
83+ echo "🔍 Fetching all Go-related Dependabot PRs..."
84+ GO_PRS=$(gh pr list \
85+ --author "dependabot[bot]" \
86+ --json number,title,createdAt,headRefName \
87+ --state open \
88+ --jq 'sort_by(.createdAt) | .[] | select(.title | contains("go.mod"))')
89+
90+ CURRENT_PR_PROCESSED=false
91+
92+ echo "$GO_PRS" | while read -r pr; do
93+ PR_NUMBER=$(echo "$pr" | jq -r .number)
94+ HEAD_BRANCH=$(echo "$pr" | jq -r .headRefName)
95+
96+ log_update_details $PR_NUMBER
97+
98+ # Skip indirect dependencies unless they're security updates
99+ if [ "${{ steps.metadata.outputs.dependency-type }}" = "indirect" ] && \
100+ [ "${{ steps.security_check.outputs.is_security_update }}" != "true" ]; then
101+ echo "⏭️ Skipping indirect dependency update"
102+ continue
103+ fi
104+
105+ # Special handling for security updates
106+ if [ "${{ steps.security_check.outputs.is_security_update }}" = "true" ]; then
107+ echo "🚨 Processing security update with priority"
108+ PRIORITY_MERGE=true
109+ fi
110+
111+ git fetch origin $HEAD_BRANCH
112+ git checkout $HEAD_BRANCH
113+ git pull origin $HEAD_BRANCH
114+
115+ echo "🛠️ Running go mod tidy for PR #$PR_NUMBER"
116+ go mod tidy
117+
118+ if git diff --quiet; then
119+ echo "✨ No changes required for PR #$PR_NUMBER"
120+ else
121+ echo "💾 Committing changes for PR #$PR_NUMBER"
122+ git config --global user.name "GitHub Actions"
123+ git config --global user.email "[email protected] " 124+ git commit -am "chore: go mod tidy for PR #$PR_NUMBER"
125+ git push origin $HEAD_BRANCH
126+ fi
127+
128+ # Auto-merge decision logic
129+ if [ "$PR_NUMBER" = "$CURRENT_PR_NUMBER" ]; then
130+ CURRENT_PR_PROCESSED=true
131+ if { [ "$UPDATE_TYPE" != "version-update:semver-major" ] || \
132+ [ "${{ steps.security_check.outputs.is_security_update }}" = "true" ]; } && \
133+ [ "${{ steps.security_check.outputs.is_compatible }}" = "true" ] && \
134+ [ "${{ steps.security_check.outputs.has_maintainer_changes }}" = "false" ]; then
135+ echo "🤖 Enabling auto-merge for current PR #$PR_NUMBER"
136+ gh pr merge --auto --merge "$PR_URL"
137+ fi
138+ elif [ "$CURRENT_PR_PROCESSED" = false ]; then
139+ echo "🔄 Processing older PR #$PR_NUMBER first"
140+ gh pr merge --auto --merge "$PR_NUMBER"
141+ fi
142+ done
143+ env :
144+ GITHUB_TOKEN : ${{ secrets.DEPENDABOT_PAT }}
145+ PR_URL : ${{ github.event.pull_request.html_url }}
146+ CURRENT_PR_NUMBER : ${{ github.event.pull_request.number }}
147+ UPDATE_TYPE : ${{ steps.metadata.outputs.update-type }}
148+
149+ # Handle other dependencies with security awareness
150+ - name : Enable auto-merge for pipeline dependencies
151+ if : |
152+ steps.security_check.outputs.is_compatible == 'true' &&
153+ steps.security_check.outputs.has_maintainer_changes == 'false' &&
154+ (steps.metadata.outputs.update-type != 'version-update:semver-major' || steps.security_check.outputs.is_security_update == 'true') &&
155+ contains(steps.metadata.outputs.directory, '.github/workflows')
156+ run : gh pr merge --auto --merge "$PR_URL"
157+ env :
158+ PR_URL : ${{github.event.pull_request.html_url}}
159+ GITHUB_TOKEN : ${{secrets.DEPENDABOT_PAT}}
160+
161+ - name : Enable auto-merge for other dependencies
162+ if : |
163+ steps.security_check.outputs.is_compatible == 'true' &&
164+ steps.security_check.outputs.has_maintainer_changes == 'false' &&
165+ (steps.metadata.outputs.update-type != 'version-update:semver-major' || steps.security_check.outputs.is_security_update == 'true') &&
166+ steps.metadata.outputs.package-ecosystem != 'gomod' &&
167+ !contains(steps.metadata.outputs.directory, '.github/workflows')
168+ run : gh pr merge --auto --merge "$PR_URL"
169+ env :
170+ PR_URL : ${{github.event.pull_request.html_url}}
171+ GITHUB_TOKEN : ${{secrets.DEPENDABOT_PAT}}
0 commit comments