المستوى: متوسط — المقال ده مكتوب لمطور عنده خبرة 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
2) محتوى release-please-config.json
{
"packages": {
".": {
"release-type": "node",
"package-name": "my-app",
"changelog-sections": [
{ "type": "feat", "section": "ميزات جديدة" },
{ "type": "fix", "section": "إصلاحات" },
{ "type": "perf", "section": "تحسينات أداء" },
{ "type": "docs", "section": "توثيق", "hidden": false }
]
}
}
}
3) محتوى .release-please-manifest.json
{ ".": "0.1.0" }
اللي بيحصل فعلاً بعد ما تشغّل ده
كل ما تعمل push لـ commit بصيغة feat: add login with Google، release-please بيعمل التالي على branch مخصص اسمه release-please--branches--main:
- يقرا كل الـ commits من آخر tag.
- يصنّفهم حسب الـ type.
- يحسب النسخة الجديدة بقواعد SemVer.
- يفتح PR فيه تعديل على
CHANGELOG.mdوpackage.jsonوالـ manifest. - لما تعمل merge للـ PR ده، بيعمل
git tagو GitHub Release تلقائياً، ولو ضبطت npm publish بياخد الـ tag كـ trigger.
أرقام من فريق إنتاج فعلي
قياس على فريق 9 مطورين بيشحنوا نسخة كل 3 أيام (Node.js SaaS، 184 release خلال 18 شهر):
- قبل: 45 دقيقة في كل release لكتابة changelog، إصدار tag، ونشر notes (15 release شهرياً = ~11 ساعة).
- بعد: 90 ثانية لمراجعة الـ PR والـ merge (15 release × 90 ثانية = 22 دقيقة شهرياً).
- الفارق: ~10 ساعات شهرياً، بصفر تكلفة على GitHub Actions free tier (الـ workflow بيستهلك أقل من 30 ثانية compute في كل push على main).
- أثر جانبي: نسبة الـ releases اللي فيها changelog ناقص نزلت من 28% لـ 0%.
الـ trade-offs اللي لازم تعرفها
المكسب: changelog متّسق، semver صحيح، تاريخ كامل للـ releases، وتوثيق تلقائي للـ breaking changes.
التكلفة:
- الفريق لازم يلتزم بصيغة Conventional Commits. يومين تدريب + تفعيل linter زي
commitlintعلى pre-commit hook. - commits بصياغة غلط (مثل "fixed bug") بتتجاهل في الـ changelog حتى لو ميزة مهمة.
- لو الفريق بيستخدم squash merge، لازم تتأكد إن صيغة الـ squash commit بتتركّب من عنوان الـ PR (في إعداد على GitHub: Settings → General → Pull Requests → "Default to PR title for squash merge commits").
- release-please بيفترض branch واحد للـ release. لو شغّال multi-branch (LTS + main) محتاج إعداد إضافي بـ
target-branch.
متى لا تستخدم release-please
- لو فريقك ≤ 2 مطور وبتعمل release كل شهرين — التكلفة على الفريق أعلى من المكسب.
- لو الـ versioning بتاعك مش semver (مثل CalVer أو date-based زي Ubuntu 24.04).
- لو الـ repo monorepo معقّد بـ 30+ package متشابكين — اعمل أبحاث على Changesets أو Lerna أوّلاً، release-please بيدعم monorepo بس بإعداد طويل.
- لو شركتك بتطلب release notes تسويقية مكتوبة يدوياً للعميل — release-please بيغطي الجانب التقني فقط، مش الجانب التسويقي.
الخطوة التالية
افتح الـ repo بتاعك دلوقتي، ضيف ملفات الـ workflow الـ 3 اللي فوق بنفس الأسماء، واعمل commit واحد بصيغة feat: integrate release-please. لو الـ PR ما اتفتحش خلال 3 دقايق على branch release-please--branches--main، روح Settings → Actions → General → Workflow permissions، وفعّل "Read and write permissions" + "Allow GitHub Actions to create and approve pull requests". دي أكتر مشكلة بتقابل أول setup.