المستوى المطلوب: متوسط — تعرف GitHub Actions الأساسية، ومرتاح في YAML، وفاهم semver basics.
لو فريقك بيستلم 30 إلى 40 PR من Dependabot كل شهر، عندك واحد من تلاتة بيحصل: إما بتدمج بعينك مغمضة وبتكسر الإنتاج، إما بيقعدوا مفتوحين 3 أسابيع، إما بتقفلهم بـ "ابحث لاحقًا". المقال ده بيوريك ازاي تبني workflow في GitHub Actions يدمج تحديثات الأمان والـ patch تلقائيًا لو الـ CI نجح، ويسيب الـ major version bumps لمراجعتك بنفسك.
أتمتة auto-merge لـ Dependabot بشكل آمن
المشكلة باختصار
Dependabot أداة من GitHub بتفتحلك PR كل ما حزمة من حزم مشروعك يطلعلها إصدار جديد، خصوصًا لو الإصدار ده فيه إصلاح لثغرة أمنية معروفة (CVE). شغّاله 24/7 وما بيتعب. المشكلة إنه بيفتح كتير، والفريق بيدفع ضريبة المراجعة.
الإحصائية اللي قاسيناها على ريبو فيه 412 dependency: متوسط 38 PR شهريًا، 84% منهم patch (مثلًا 1.4.2 → 1.4.3) و 11% minor (1.4 → 1.5) و 5% بس major (1.x → 2.x). يعني 95% من الـ PRs بتكون آمنة نسبيًا حسب قواعد semver، لكنها بتاكل وقت الفريق رغم كده.
ايه هو semver وليه يهمك؟ (مثال للمبتدئ)
تخيّل إن الإصدار 2.4.7 هو رقم لوحة سيارة بتلات أجزاء.
- major (2) = شكل العربية. لو اتغيّر يبقى عربية مختلفة كليًا. ممكن المفتاح القديم ميشتغلش معاها.
- minor (4) = إضافات داخلية، زي شاشة جديدة أو فتحة سقف. نفس العربية لكن فيها مزايا أكتر، والمفتاح القديم لسه شغّال.
- patch (7) = صيانة. مسح زجاج، تغيير زيت، فلتر هواء. مفيش مزايا، بس بقت أنضف وأكثر أمانًا.
التعريف الرسمي من semver.org: تغيير الـ major معناه breaking changes، يعني الـ API مش هيشتغل زي ما كان. تغيير الـ minor معناه إضافات backwards-compatible. الـ patch إصلاح أخطاء فقط بدون تغيير في الـ contract الخارجي. في النظرية، patch و minor آمنين للترقية الفورية. في التطبيق الفعلي، 2 إلى 3% من الـ minor releases بتكسر شيء بسبب bugs أو سوء استخدام الـ semver من المؤلف.
الحل: workflow بيدمج auto حسب نوع التحديث
الفكرة بسيطة. كل PR من Dependabot بيجي معاه metadata بيقول هل التحديث patch، minor، ولا major. هنستخدم action رسمي من GitHub اسمه dependabot/fetch-metadata عشان نقرا النوع، وبعدين نسمح بالـ auto-merge لو patch أو minor بس، وبعد ما الـ tests تنجح كاملة.
الملف ده بيتحط في .github/workflows/dependabot-auto-merge.yml:
name: Dependabot Auto Merge
on: pull_request
permissions:
contents: write
pull-requests: write
jobs:
auto-merge:
runs-on: ubuntu-latest
if: github.actor == 'dependabot[bot]'
steps:
- name: Get PR metadata
id: meta
uses: dependabot/fetch-metadata@v2.2.0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Approve patch and minor
if: steps.meta.outputs.update-type == 'version-update:semver-patch' || steps.meta.outputs.update-type == 'version-update:semver-minor'
run: gh pr review --approve "$PR_URL"
env:
PR_URL: ${{ github.event.pull_request.html_url }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Enable auto-merge
if: steps.meta.outputs.update-type == 'version-update:semver-patch' || steps.meta.outputs.update-type == 'version-update:semver-minor'
run: gh pr merge --auto --squash "$PR_URL"
env:
PR_URL: ${{ github.event.pull_request.html_url }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}