Release Branch هو فرع في Git Flow يتم إنشاؤه من develop لإعداد إصدار معين للنشر. يتم فيه تثبيت نسخة التطبيق، وإصلاح الأخطاء الأخيرة، وتحديث البيانات الوصفية — دون إضافة ميزات جديدة. وفقًا Vincent Driessen، 2010، فإن فرع الإصدار يفصل تحضير الإصدار عن التطوير الحالي، مما يسمح بتنفيذ كلا النشاطين بالتوازي.
النقاط الرئيسية
release/X.Y.Z حسب نسخة التطبيق.Release Branch (فرع الإصدار) هو فرع مؤقت في Git Flow، يتم إنشاؤه من develop عندما يقرر الفريق أن المجموعة الحالية من الميزات جاهزة للإصدار. إنه موجود تمامًا للمدة التي يستغرقها التحضير النهائي للإصدار — من بضع ساعات إلى بضعة أيام.
الغرض الرئيسي من فرع الإصدار هو تجميد مجموعة محددة من الميزات للإصدار دون إيقاف تطوير الإصدارات التالية. بينما يتم تحضير فرع الإصدار للنشر، يمكن للمطورين الآخرين الاستمرار في دمج فروع الميزات في develop للإصدار التالي.
في فرع الإصدار لا يتم إنشاء ميزات جديدة — فقط إصلاحات الأخطاء، تحديث نسخة التطبيق، الترجمة والتوثيق. بعد الانتهاء من جميع الأعمال، يتم دمج فرع الإصدار في main (موسومًا كإصدار) والعودة إلى develop (لتصل الإصلاحات إلى الإصدارات المستقبلية).
وفقًا Atlassian، 2024، فإن فروع الإصدار ضرورية جدًا للمشاريع ذات دورات الإصدار المنتظمة — فهي تضمن قابلية التوقع والاستقرار في عملية النشر.
دورة حياة فرع الإصدار من الإنشاء إلى الحذف تتضمن عدة مراحل. فهم كل مرحلة يساعد الفريق على تنسيق الإجراءات وتجنب الأخطاء.
release/2.5.0. يستمر develop في قبول فروع الميزات للإصدار التالي.v2.5.0.الخطوة 6 — الدمج العكسي في develop — غالبًا ما تُنسى، لكنها ضرورية جدًا. بدونها، لن تصل إصلاحات الأخطاء التي تمت في فرع الإصدار إلى develop، وقد تظهر نفس الأخطاء مرة أخرى في الإصدار التالي.
يعتمد عمر فرع الإصدار على تعقيد الإصدار وجودة الكود في develop. في المتوسط، يستغرق التحضير من 2 إلى 5 أيام عمل لتطبيق محمول متوسط الحجم.
في فرع الإصدار يتم تنفيذ مجموعة محدودة بدقة من المهام. أي انحراف عن هذه القائمة ينتهك نموذج Git Flow ويخلق مخاطر لاستقرار الإصدار.
| نوع التغيير | مسموح | مثال |
|---|---|---|
| إصدار النسخ | نعم | تحديث versionName في build.gradle |
| إصلاح الأخطاء | نعم | إصلاح تعطل التطبيق عند التشغيل |
| الترجمة | نعم | إضافة ترجمات للشاشات الجديدة |
| التوثيق | نعم | تحديث CHANGELOG و README |
| ميزات جديدة | لا | إضافة شاشة ملف شخصي جديدة |
| إعادة الهيكلة | لا | إعادة كتابة طبقة الشبكة |
| تحديث المكتبات | بحذر | فقط إصدارات patch لإصلاحات الأخطاء |
قاعدة حظر الميزات الجديدة هي الأهم في فرع الإصدار. إذا لم تنجح الميزة في الوصول للإصدار، فإنها تنتظر الدورة التالية. محاولة دفع ميزة غير مكتملة إلى فرع الإصدار هي السبب الرئيسي لتأخير المواعيد النهائية وظهور الأخطاء في الإنتاج.
في فرع الإصدار يتم تحديث رقم نسخة التطبيق إلزاميًا. لنظام Android، هذه هي الحقول versionCode و versionName في build.gradle؛ لنظام iOS — CFBundleShortVersionString في Info.plist.
// build.gradle (مستوى التطبيق) — تحديث النسخة في فرع release
android {
defaultConfig {
versionCode 42
versionName "2.5.0"
}
}
// لنظام iOS — تحديث Info.plist
// CFBundleShortVersionString = 2.5.0
// CFBundleVersion = 42
غالبًا ما يخلط المطورون المبتدئون بين فرعي release و hotfix، على الرغم من أن الغرض منهما مختلف جوهريًا. اختيار نوع الفرع الخاطئ يمكن أن يؤخر الإصلاح الحرج أو يعطل عملية الإصدار.
إذا تم العثور على خطأ أثناء تحضير الإصدار (في فرع release) — فهو إصلاح خطأ عادي. إذا تم العثور على خطأ في الإنتاج (على main) — فهو hotfix، ويتم إنشاؤه من main، حتى لو كان فرع release موجودًا بالفعل.
معيار موحد لتسمية فروع الإصدار يبسط التنقل في المستودع ويسمح لأنظمة CI/CD بتحديد تلقائيًا أن الفرع ينتمي إلى عملية الإصدار.
release/2.5.0.release/merlin.release/2024-12-01.التنسيق release/X.Y.Z هو المفضل، لأنه يربط الفرع بشكل صريح برقم النسخة الذي سيتم تعيينه للإصدار. هذا يبسط البحث والمعالجة التلقائية بواسطة نصوص CI/CD.
الدمج العكسي (merge back) لفرع الإصدار في develop هو واحد من أهم العمليات وفي نفس الوقت أكثرها تجاهلاً. بدونه، تبقى جميع إصلاحات الأخطاء التي تمت في فرع الإصدار فقط في نسخة الإصدار ولا تصل إلى دورة الإصدار التالية.
يتم تنفيذ عملية الدمج العكسي بعد أن تم دمج فرع الإصدار بالفعل في main. أولاً، يتم دمج release في develop، ثم يتم حذفه. هذا يضمن أن develop يحتوي على جميع الإصلاحات التي تمت أثناء تحضير الإصدار.
بعد الدمج العكسي، قد تحدث تعارضات — خاصة إذا ظهرت بالفعل فروع ميزات جديدة في develop كانت قد عدلت نفس الملفات. المطور المسؤول عن الإصدار يحل هذه التعارضات ويدفع develop إلى الخادم.
بعض الفرق تستخدم rebase بدلاً من merge للدمج العكسي للحفاظ على تاريخ خطي. ومع ذلك، فإن merge أكثر أمانًا لـ develop، لأنه لا يعيد كتابة تاريخ commits الذي قد يكون مستخدمًا بالفعل من قبل مطورين آخرين.
دعنا نستعرض الدورة الكاملة للعمل مع فرع release: من الإنشاء إلى الحذف بعد إصدار ناجح لتطبيق محمول نسخة 2.5.0.
# 1. إنشاء فرع release من develop
git checkout develop
git pull origin develop
git checkout -b release/2.5.0
# 2. تحديث النسخة وإصلاح الأخطاء
git add build.gradle
git commit -m "Bump version to 2.5.0"
# 3. إصلاح الأخطاء (إصلاحات فقط)
git add src/fix/
git commit -m "Fix crash on payment screen"
# 4. إرسال فرع release إلى الخادم
git push origin release/2.5.0
# 5. دمج release في main
git checkout main
git pull origin main
git merge --no-ff release/2.5.0
git tag -a v2.5.0 -m "Release 2.5.0"
git push origin main --tags
# 6. الدمج العكسي في develop
git checkout develop
git merge --no-ff release/2.5.0
git push origin develop
# 7. حذف فرع release
git branch -d release/2.5.0
git push origin --delete release/2.5.0
الأمران 5 و 6 — الدمج المزدوج — ضروريان جدًا. أولاً، يتلقى main كود الإصدار والعلامة، ثم يتزامن develop مع إصلاحات release. إذا تم تخطي الخطوة 6، فإن إصلاحات الإصدار لن تصل إلى دورة التطوير التالية.
للمشاريع المحمولة ذات الإصدارات المنتظمة، يمكن أتمتة عملية إنشاء فرع release وتحديث النسخة عبر نصوص CI/CD. يتيح GitHub Actions إنشاء سير عمل يؤدي عند الضغط على زر إلى إنشاء فرع release مع تحديث تلقائي للنسخة.
للمشاريع المحمولة ذات الإصدارات المنتظمة، يمكن أتمتة عملية إنشاء فرع release وتحديث النسخة عبر نصوص CI/CD. يتيح GitHub Actions إنشاء سير عمل يؤدي عند الضغط على زر إلى إنشاء فرع release مع تحديث تلقائي للنسخة.
# GitHub Actions — أتمتة إنشاء فرع release
name: Create Release Branch
on:
workflow_dispatch:
inputs:
version:
description: 'Release version (e.g. 2.5.0)'
required: true
jobs:
create-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create release branch
run: |
git checkout develop
git checkout -b release/${{ inputs.version }}
git push origin release/${{ inputs.version }}
الأسئلة الشائعة
فرع release واحد فقط في نفس الوقت، إذا كنت تتبع Git Flow. وجود فرعي release نشطين يعني أن الفريق يحاول إصدار نسختين بالتوازي — وهذا ينتهك مبدأ الإصدارات المتسلسلة ويسبب ارتباكًا في النسخ.
قم بإزالة commits الميزة غير المكتملة من فرع release عبر git revert وأجل الميزة حتى الإصدار التالي. لا تنشر أبدًا وظائف غير مكتملة في الإنتاج — الديون التقنية والأخطاء المحتملة لا تستحق العجلة.
للإصدارات البسيطة ذات الإصلاح الواحد، يمكن تخطي فرع release والدمج مباشرة من develop إلى main. ومع ذلك، للإصدارات القياسية، فرع release إلزامي — فهو يثبت النسخة، ويعزل التحضير، ويضمن الدمج المزدوج للإصلاحات.
استخدم git revert في main لإنشاء commit جديد يلغي جميع تغييرات الإصدار. ثم احذف علامة الإصدار بالأمر git push origin --delete vX.Y.Z. بعد إصلاح المشكلات، أنشئ فرع release جديد برقم patch متزايد.
Release candidate (RC) هو قطعة أثرية للبناء تخضع للاختبار النهائي. Release branch هو فرع Git الذي يُبنى منه release candidate. يمكن لفرع release واحد أن ينتج عدة بنيات RC (RC1، RC2، إلخ) مع إصلاح الأخطاء.
الملخص
release/X.Y.Z برقم نسخة SemVer.سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا