المستوى: متوسط — المقال ده مكتوب لمطور عنده خبرة git و GitHub Actions، وعايز يأتمت إصدار النسخات والـ changelog بدون pull request يدوي كل أسبوعين.
لو فريقك بيشحن نسخة كل يومين، وكل مرة حد بيقعد ساعة يكتب changelog يدوي ويعمل tag، انت بتدفع 5 ساعات أسبوعياً ضريبة على شغل الآلة بتعمله أحسن منك. الـ release-please من Google بياخد الـ commits اللي على نظام Conventional Commits، يولّد changelog، يفتح PR، ولما تعمله merge بيعمل tag و GitHub Release تلقائياً.
أتمتة Releases من Conventional Commits
تخيّل الموقف ببساطة
لو عندك دفتر يومية بتكتب فيه كل يوم اللي عملته في البيت: "غسلت الأطباق"، "اشتريت خبز"، "صلّحت اللمبة". في آخر الشهر بتحب تطلّع تقرير منظم: "صيانة"، "مشتريات"، "تنظيف". لو كل سطر في دفترك بيبدأ بكلمة محددة (شراء/إصلاح/تنظيف)، تقدر برنامج بسيط يقسّم اليوميات لك ويطلّع التقرير في 3 ثواني. ده بالظبط اللي بيعمله release-please مع الـ git log: بيقرا الـ commits المنظمة ويصنّفها لقسم "ميزات"، "إصلاحات"، "تحسينات أداء"، ويبني CHANGELOG.md جاهز.
تعريف Conventional Commits بالتفاصيل
Conventional Commits مواصفة بسيطة بتقول: كل رسالة commit تبدأ بـ type(scope): description. الـ types الأساسية:
feat:ميزة جديدة → bump في minor version (1.2.3 → 1.3.0)fix:إصلاح bug → bump في patch version (1.2.3 → 1.2.4)feat!:أو سطرBREAKING CHANGE:في الـ body → bump في major version (1.2.3 → 2.0.0)chore:,docs:,refactor:,test:: مش بتعمل bump افتراضياً، بس ممكن تظهر في الـ changelog لو ضبطتها
المنطق ده مبني على Semantic Versioning 2.0.0: رقم النسخة MAJOR.MINOR.PATCH بيتغير حسب طبيعة التغيير، مش حسب التاريخ ولا مزاج الـ release manager.
الإعداد في 4 خطوات
هنشتغل على Node.js project كمثال، لكن release-please بيدعم Python و Go و Rust و Java و PHP و Ruby و Terraform بنفس الـ workflow.
- أنشئ ملف
.github/workflows/release-please.yml - أنشئ
release-please-config.jsonفي الـ root - أنشئ
.release-please-manifest.jsonفيه النسخة الحالية - اعمل push لأي commit بصيغة Conventional Commits
1) محتوى الـ workflow
name: release-please
on:
push:
branches: [main]
permissions:
contents: write
pull-requests: write
jobs:
release-please:
runs-on: ubuntu-latest
steps:
- uses: googleapis/release-please-action@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
config-file: release-please-config.json
manifest-file: .release-please-manifest.json