Skip to main content

إستراتيجية إصدار البرامج


الإصدار الدلالي 2.0.0.
نظرا لنسخة رقم MAJOR. MINOR. PATCH، زيادة:
الإصدار الرئيسي عند إجراء تغييرات أبي غير متوافقة، نسخة مينور عند إضافة وظيفة بطريقة متوافقة مع الوراء، ونسخة باتش عند إجراء إصلاحات الشوائب متوافق مع الوراء.
تتوفر تسميات إضافية للبيانات الأولية قبل إصدار البيانات وبناءها كإضافات بتنسيق MAJOR. MINOR. PATCH.
المقدمة.
في العالم من إدارة البرمجيات هناك مكان الفزع يسمى "الجحيم التبعية". أكبر نظامك ينمو والمزيد من الحزم التي تدمجها في البرنامج الخاص بك، والأرجح أن تجد نفسك، يوم واحد، في هذا حفرة من اليأس.
في النظم مع العديد من التبعيات، والإفراج عن إصدارات حزمة جديدة يمكن أن تصبح بسرعة كابوسا. إذا كانت مواصفات التبعية ضيقة جدا، فأنت في خطر من قفل الإصدار (عدم القدرة على ترقية حزمة دون الحاجة إلى إصدار إصدارات جديدة من كل حزمة تابعة). إذا تم تحديد التبعيات فضفاضة جدا، وسوف يكون حتما لعض من قبل نسخة الاختلاط (على افتراض التوافق مع الإصدارات المستقبلية أكثر مما هو معقول). الجحيم التبعية هو أين أنت عند قفل الإصدار و / أو إصدار بروميسكويتي يمنعك من بسهولة وأمان نقل المشروع إلى الأمام.
كحل لهذه المشكلة، أقترح مجموعة بسيطة من القواعد والمتطلبات التي تملي كيفية تعيين أرقام الإصدار وزيادة. وتستند هذه القواعد إلى، ولكن لا تقتصر بالضرورة على الممارسات الشائعة الواسعة الانتشار الموجودة سابقا، المستخدمة في كل من البرامج المغلقة والمفتوحة المصدر. لهذا النظام للعمل، تحتاج أولا إلى إعلان أبي العامة. وقد يتكون ذلك من الوثائق أو ينفذها القانون نفسه. وبغض النظر عن ذلك، من المهم أن تكون هذه المعلومات واضحة ودقيقة. بعد تحديد واجهة برمجة التطبيقات العامة، يمكنك توصيل التغييرات إليها بزيادات محددة إلى رقم الإصدار. النظر في صيغة إصدار X. Y.Z (الرائد. ماينور. باتش). إصلاحات الشوائب التي لا تؤثر على زيادة أبي النسخة التصحيح، إضافات أبي متوافق / التغييرات الإضافية زيادة الإصدار الثانوي، وتغييرات أبي غير متوافقة إلى الوراء زيادة الإصدار الرئيسي.
أدعو هذا النظام "الإصدار الدلالي". في إطار هذا المخطط، أرقام الإصدار والطريقة التي تغيرها تنقل معنى حول التعليمات البرمجية الأساسية وما تم تعديله من نسخة واحدة إلى أخرى.
مواصفات الإصدار الدلالي (سيمفر)
يجب أن تكون الكلمات الرئيسية "مست" و "مست نوت" و "ريكيرد" و "شال" و "شال" و "شولد" و "شولد" و "ريكومندد" و "ماي" و "أوبتيونال" في هذا المستند ليتم تفسيرها كما هو موضح في رك 2119.
البرمجيات باستخدام الدلالي فيرسيونينغ يجب أن تعلن أبي العامة. يمكن أن يتم الإعلان عن أبي في التعليمات البرمجية نفسها أو موجودة بدقة في الوثائق. ومع ذلك يتم ذلك، فإنه ينبغي أن يكون دقيقا وشاملا.
يجب أن يكون رقم الإصدار العادي هو النموذج X. Y.Z حيث X و Y و Z عبارة عن أعداد صحيحة غير سالبة، ويجب ألا تحتوي على أصفار رائدة. X هو الإصدار الرئيسي، Y هو الإصدار الثانوي، و Z هو النسخة التصحيح. يجب أن يزيد كل عنصر عدديا. على سبيل المثال: 1.9.0 - & غ؛ 1.10.0 - & غ؛ 1.11.0.
مرة واحدة وقد تم الافراج عن حزمة الإصدار، محتويات هذا الإصدار يجب أن لا يتم تعديلها. يجب إصدار أي تعديلات كإصدار جديد.
النسخة الرئيسية صفر (0.y. z) هو للتطوير الأولي. قد يتغير أي شيء في أي وقت. لا ينبغي اعتبار أبي العامة مستقرة.
الإصدار 1.0.0 يحدد أبي العامة. تعتمد الطريقة التي يتم بها زيادة رقم الإصدار بعد هذا الإصدار على واجهة برمجة التطبيقات العامة هذه وكيفية تغييرها.
التصحيح نسخة Z (x. y.Z | x & غ؛ 0) يجب أن تكون متزايدة إذا تم تقديم إصلاحات الشوائب المتوافقة إلى الوراء فقط. يتم تعريف إصلاح الأخطاء كتغيير داخلي يقوم بإصلاح سلوك غير صحيح.
النسخة الصغرى Y (x. Y.z | x & غ؛ 0) يجب أن تكون متزايدة إذا تم تقديم وظيفة متوافقة جديدة إلى الوراء أبي العامة. يجب أن يتم زيادة إذا تم وضع علامة على أي وظيفة أبي العامة بأنها مهملة. ويمكن زيادتها إذا تم إدخال وظائف أو تحسينات جديدة جوهرية ضمن الشفرة الخاصة. قد تشمل تغييرات مستوى التصحيح. يجب إعادة تعيين التصحيح النسخة إلى 0 عندما يتم زيادة إصدار طفيفة.
الإصدار الرئيسي X (X. y.z | X & غ؛ 0) يجب زيادة إذا تم إدخال أي تغييرات غير متوافقة إلى الوراء إلى أبي العامة. قد تشمل تغييرات طفيفة و مستوى التصحيح. يجب إعادة تعيين التصحيح والنسخة البسيطة إلى 0 عند زيادة الإصدار الرئيسي.
يمكن الإشارة إلى إصدار ما قبل الإصدار عن طريق إلحاق الواصلة وسلسلة من المعرفات المفصولة بنقطة مباشرة بعد إصدار التصحيح. يجب أن تتكون المعرفات فقط من أبجدية رقمية أسي و واصلة [0-9A-زا-z-]. يجب ألا تكون المعرفات فارغة. يجب أن لا تتضمن المعرفات الرقمية الأصفار الرائدة. الإصدارات السابقة للإصدار لها أسبقية أقل من النسخة العادية المرتبطة بها. يشير إصدار ما قبل الإصدار إلى أن الإصدار غير مستقر وقد لا يفي بمتطلبات التوافق المقصودة كما هو موضح في النسخة العادية المرتبطة به. أمثلة: 1.0.0-ألفا، 1.0.0-ألفا.1، 1.0.0-0.3.7، 1.0.0-x.7.z.92.
قد يتم إنشاء بيانات التعريف من خلال إلحاق علامة زائد وسلسلة من المعرفات المفصولة بنقطة على الفور بعد التصحيح أو إصدار ما قبل الإصدار. يجب أن تتكون المعرفات فقط من أبجدية رقمية أسي و واصلة [0-9A-زا-z-]. يجب ألا تكون المعرفات فارغة. يجب تجاهل البيانات الوصفية عند تحديد أولوية الإصدار. وبالتالي نسختين تختلفان فقط في البيانات الوصفية للبناء، لها نفس الأسبقية. أمثلة: 1.0.0-ألفا + 001، 1.0.0 + 20180313144700، 1.0.0-بيتا + exp. sha.5114f85.
تشير الأسبقية إلى كيفية مقارنة الإصدارات مع بعضها البعض عند طلبها. يجب أن تحسب الأسبقية عن طريق فصل النسخة إلى معرفات رئيسية، وصغيرة، وتصحيح، وما قبل النشر في هذا الترتيب (بناء البيانات الوصفية لا تعتبر في الأسبقية). وتحدد الأسبقية بالفارق الأول عند مقارنة كل من هذه المعرفات من اليسار إلى اليمين على النحو التالي: تتم دائما مقارنة الإصدارات الرئيسية والثانوية والتصحيحية عدديا. مثال: 1.0.0 & لوت؛ 2.0.0 & لوت؛ 2.1.0 & لوت؛ 2.1.1. عندما تكون كبيرة، طفيفة، والتصحيح متساوية، إصدار ما قبل الإصدار له أسبقية أقل من النسخة العادية. مثال: 1.0.0-ألفا & لوت؛ 1.0.0. يجب تحديد الأسبقية لنسختين مسبقتين مع نفس الإصدار الرئيسي والثانوي والتصحيح من خلال مقارنة كل معرف من النقاط المفصولة من اليسار إلى اليمين حتى يتم العثور على الفرق على النحو التالي: تتم مقارنة المعرفات المكونة من أرقام فقط رقميا ومعرفات تحتوي على أحرف أو الواصلات مقارنة مع ترتيب أسي. وتكون للمعرفات الرقمية دائما أسبقية أقل من المعرفات غير الرقمية. مجموعة أكبر من حقول ما قبل النشر لها أسبقية أعلى من مجموعة أصغر، إذا كانت جميع المعرفات السابقة متساوية. مثال: 1.0.0-ألفا & لوت؛ 1.0.0-alpha.1 & لوت؛ 1.0.0-alpha. beta & لوت؛ 1.0.0-بيتا & لوت؛ 1.0.0-beta.2 & لوت؛ 1.0.0-beta.11 & لوت؛ 1.0.0-rc.1 & لوت؛ 1.0.0.
لماذا استخدام الإصدار الدلالي؟
هذه ليست فكرة جديدة أو ثورية. في الواقع، ربما تفعل شيئا قريبا من هذا بالفعل. المشكلة هي أن "وثيقة" ليست جيدة بما فيه الكفاية. وبدون الامتثال لبعض المواصفات الرسمية، فإن أرقام الإصدارات غير مجدية أساسا لإدارة التبعية. من خلال إعطاء اسم وتعريف واضح للأفكار المذكورة أعلاه، يصبح من السهل على التواصل نواياكم لمستخدمي البرنامج الخاص بك. وبمجرد أن تكون هذه النوايا واضحة، يمكن أخيرا وضع مواصفات تبعية مرنة (ولكنها ليست مرنة جدا).
مثال بسيط سوف يبرهن كيف يمكن للغة الدلالية أن تجعل التبعية الجحيم شيئا من الماضي. النظر في مكتبة تسمى "فيريتروك". فإنه يتطلب حزمة فيرسيونيمد اسميا "سلم". في الوقت الذي يتم إنشاء فيريتروك، سلم في الإصدار 3.1.0. منذ يستخدم فيريتروك بعض الوظائف التي أدخلت لأول مرة في 3.1.0، يمكنك تحديد بأمان التبعية سلم أكبر من أو يساوي 3.1.0 ولكن أقل من 4.0.0. الآن، عندما سلالم الإصدار 3.1.1 و 3.2.0 تصبح متاحة، يمكنك تحريرها إلى نظام إدارة الحزمة الخاصة بك ومعرفة أنها سوف تكون متوافقة مع البرامج المعتمدة القائمة.
كمطور مسؤول سوف، بطبيعة الحال، تريد التحقق من أن أي وظيفة ترقية حزمة كما المعلن عنها. العالم الحقيقي هو مكان فوضوي. لا يوجد شيء يمكننا القيام به حيال ذلك ولكن كن حذرا. ما يمكنك القيام به هو السماح الإصدار الدلالي توفر لك طريقة عاقل للافراج عن وترقية حزم دون الحاجة إلى لفة إصدارات جديدة من الحزم التابعة، مما يوفر لك الوقت والمتاعب.
إذا كان كل هذا يبدو مرغوبا فيه، كل ما عليك القيام به لبدء استخدام الدلالي فيرسيونينغ هو أن تعلن أن تقوم بذلك ثم اتبع القواعد. رابط إلى هذا الموقع من ريدمي الخاص بك حتى الآخرين يعرفون القواعد ويمكن الاستفادة منها.
كيف يمكنني التعامل مع المراجعات في مرحلة التطوير الأولي 0.y. z؟
أبسط شيء يجب القيام به هو بدء إصدار التطوير الأولي في 0.1.0 ثم زيادة الإصدار الثانوي لكل إصدار لاحق.
كيف أعرف متى يتم إصدار 1.0.0؟
إذا كان يتم استخدام البرنامج الخاص بك في الإنتاج، فإنه من المحتمل أن يكون بالفعل 1.0.0. إذا كان لديك أبي مستقرة التي قد تأتي للمستخدمين الاعتماد، يجب أن يكون 1.0.0. إذا كنت قلقا كثيرا حول التوافق مع الخلف، فمن المحتمل أن تكون بالفعل 1.0.0.
أليس هذا يثبط التطور السريع والتكرار السريع؟
الإصدار الرئيسي الصفر هو كل شيء عن التطور السريع. إذا كنت تقوم بتغيير واجهة برمجة التطبيقات كل يوم يجب أن تكون إما في الإصدار 0.y. z أو على فرع تطوير منفصل يعمل على الإصدار الرئيسي التالي.
إذا كان حتى أصغر التغييرات المتعارضة إلى الوراء إلى أبي العامة تتطلب عثرة نسخة رئيسية، لن ينتهي الأمر في الإصدار 42.0.0 بسرعة كبيرة؟
وهذه مسألة تنمية مسؤولة وبصيرة. يجب عدم إدخال التغييرات غير المتوافقة بشكل خفيف على البرامج التي تحتوي على الكثير من التعليمات البرمجية التابعة. والتكلفة التي يجب تكبدها للترقية يمكن أن تكون كبيرة. إن الاضطرار إلى عثرة الإصدارات الرئيسية لإطلاق تغييرات غير متوافقة يعني أنك ستفكر من خلال تأثير التغييرات، وتقيم نسبة التكلفة / المنفعة المعنية.
توثيق أبي العام بأكمله هو الكثير من العمل!
ومن مسؤوليتكم كمطور محترف لتوثيق البرامج التي يقصد استخدامها من قبل الآخرين بشكل صحيح. إدارة تعقيد البرمجيات هو جزء مهم للغاية من الحفاظ على كفاءة المشروع، وهذا من الصعب القيام به إذا كان لا أحد يعرف كيفية استخدام البرنامج الخاص بك، أو ما هي طرق آمنة للاتصال. على المدى الطويل، الإصدار الدلالي، والإصرار على أبي العامة محددة بشكل جيد يمكن أن تبقي الجميع وكل شيء بسلاسة.
ماذا أفعل إذا قمت بطريق الخطأ بإطلاق تغيير غير متوافق مع الإصدارات السابقة كنسخة ثانوية؟
بمجرد أن تدرك أنك قد كسر مواصفات الإصدار الدلالي، قم بإصلاح المشكلة وقم بإصدار نسخة ثانوية جديدة تقوم بتصحيح المشكلة واستعادة التوافق إلى الوراء. وحتى في ظل هذه الظروف، من غير المقبول تعديل النشرات المصورة. إذا كان ذلك ملائما، فقم بتوثيق النسخة المسيئة وإبلاغ المستخدمين بالمشكلة حتى يكونوا على دراية بالإصدار المسيء.
ماذا علي أن أفعل إذا قمت بتحديث التبعيات الخاصة بي دون تغيير أبي العامة؟
ويعتبر ذلك متوافقا لأنه لا يؤثر على واجهة برمجة التطبيقات العامة. البرنامج الذي يعتمد صراحة على نفس التبعيات كما الحزمة الخاصة بك يجب أن يكون مواصفات التبعية الخاصة بها وسوف يلاحظ المؤلف أي تضارب. تحديد ما إذا كان التغيير هو مستوى تصحيح أو تعديل مستوى ثانوي يعتمد على ما إذا قمت بتحديث التبعيات الخاصة بك من أجل إصلاح الخلل أو إدخال وظائف جديدة. وأتوقع عادة رمز إضافي لهذا المثال الأخير، وفي هذه الحالة فإنه من الواضح زيادة مستوى ثانوي.
ماذا لو غيرت عن غير قصد واجهة برمجة التطبيقات العامة بطريقة لا تتوافق مع تغيير رقم الإصدار (بمعنى أن الرمز يقدم بشكل غير صحيح تغييرا كبيرا في إصدار التصحيح)؟
استخدام أفضل حكم. إذا كان لديك جمهور ضخم من شأنه أن يتأثر بشكل كبير من خلال تغيير السلوك مرة أخرى إلى ما أبي العامة المقصود، ثم قد يكون من الأفضل لأداء إصدار النسخة الرئيسية، على الرغم من أن الإصلاح يمكن أن تعتبر صارمة إطلاق التصحيح. تذكر، الإصدار الدلالي هو كل شيء عن نقل معنى كيف يتغير رقم الإصدار. إذا كانت هذه التغييرات مهمة للمستخدمين، فاستخدم رقم الإصدار لإعلامهم.
كيف يمكنني التعامل مع وظيفة إبطال؟
إن إهمال الوظائف الموجودة هو جزء طبيعي من تطوير البرمجيات وغالبا ما يكون مطلوبا لتحقيق تقدم إلى الأمام. عند إبطال جزء من واجهة برمجة التطبيقات العامة، يجب عليك تنفيذ أمرين: (1) تحديث المستندات لإعلام المستخدمين بالتغيير، (2) إصدار إصدار ثانوي جديد مع الإيقاف في المكان. قبل إزالة الوظيفة بشكل كامل في إصدار رئيسي جديد يجب أن يكون هناك إصدار صغير واحد على الأقل يحتوي على الإيقاف بحيث يمكن للمستخدمين الانتقال بسلاسة إلى واجهة برمجة التطبيقات الجديدة.
هل لدى سيمفر حد حجم على سلسلة الإصدار؟
لا، ولكن استخدام الحكم الجيد. ربما تكون سلسلة إصدار حرف 255 مفرطة، على سبيل المثال. أيضا، قد تفرض أنظمة محددة حدودها الخاصة على حجم السلسلة.
مواصفات تأليف الدلالي تأليف توم بريستون-فيرنر، مخترع غرافاتارس ومؤسس مؤسس جيثب.
إذا كنت ترغب في ترك ردود الفعل، يرجى فتح مشكلة على جيثب.

إستراتيجية إصدار البرامج
الحصول على فيا أب ستور قراءة هذه المشاركة في التطبيق لدينا!
ما هي إستراتيجية إصدار إصدارات التطبيقات؟ [مكرر]
هذا السؤال له إجابة هنا:
وأود أن تكون مهتمة للحصول على آراء المجتمع سو حول أفضل استراتيجية إصدار الإصدارات التطبيق.
كيف يمكنك تتبع رقم إصدار التطبيق؟ هل لديك تعريف رسمي لما يمثله كل رقم / حرف في هذا الإصدار؟
ماذا تعني الأرقام / السلاسل المختلفة في إصدار التطبيق لتطبيقك؟
هل تستخدم أي نظام تحديث تلقائي في تطبيقاتك (على سبيل المثال، شيء مثل سباركل) ومدى حسن تصرفك من أجلك؟
هل لديك إجراء تحديث منفصل للاختبار بيتا أو اختبار ما قبل النشر من التطبيق الخاص بك؟
تم وضع علامة على أنها مكررة من قبل غنات، ميكلت، كيليان فوث، GlenH7، رين هنريش 29 أبريل '13 في 2:42.
وقد طرح هذا السؤال من قبل، ولديه بالفعل جواب. إذا كانت هذه الإجابات لا تعالج سؤالك بشكل كامل، فيرجى طرح سؤال جديد.
ترحيل من ستاكوفيرفلو 18 مايو 1111 في 13:48.
وجاء هذا السؤال من موقعنا لمبرمجين المحترفين والمتحمسين.
كيف يمكنك تتبع رقم إصدار التطبيق؟ هل لديك تعريف رسمي لما يمثله كل رقم / حرف في هذا الإصدار؟
ماذا تعني الأرقام / السلاسل المختلفة في إصدار التطبيق لتطبيقك؟
أستخدم ما يلي:
الرائد - الإصدار الرئيسي هو الافراج واضح للمنتج. زادت عندما تكون هناك تغييرات كبيرة في الأداء الوظيفي.
طفيفة - يتم زيادة إصدار طفيفة عندما يتم إضافة ميزات جديدة فقط أو إصلاحات الشوائب الرئيسية.
ترقية / تصحيح - ترقية يشير إلى استبدال منتج مع إصدار أحدث من product. It يتزايد فقط عندما يتم توفير الترقية على إصدار رئيسي معين. يبدأ إصدار باتش مع 0 وتزايد فقط عندما تم حل علة.
بناء لا - يتم زيادة رقم البناء عند إنشاء بنية جديدة.
هل تستخدم أي نظام تحديث تلقائي في تطبيقاتك (على سبيل المثال، شيء مثل سباركل) ومدى حسن تصرفك من أجلك؟
نحن نستخدم أداة البناء الذي يبني تلقائيا التطبيق في الليل الذي نسميه بناء ليلا وهذا يزيد بناء عدد في كل مرة يتم إنشاء بناء.
هل لديك إجراء تحديث منفصل للاختبار بيتا أو اختبار ما قبل النشر من التطبيق الخاص بك؟
لا. اختبارات اختبار على بناء ليلا في كل صباح الذي نسميه بات (بناء قبول الاختبار) والتحقق من بناء ليلا.
واسمحوا لي أن ألاحظ أولا أنه لا يوجد اتفاق فيما يبدو بشأن استراتيجية "أفضل". يمكنني فقط مشاركة تجربتي في مشروع الحالي.
يتم تعريف إصدار النظام يدويا في خاصية بناء. يحدث ذلك عندما يوافق الفريق على إصدار جديد. كما فيرسيونينغ إضافية نستخدم رقم البناء الذي يتم إنشاؤه تلقائيا من قبل بناء سي.
نحن نتابع بشكل فضفاض نظام تسمية أوبونتو YY. MM. version. patch_buildNumber كما وجدنا أن إصدار الرائد. مينور يعبر عن توقعات العملاء؛)
لا توجد تحديثات تلقائية كما أن التطبيق يجب أن تدحرجت من قبل المشرفين.
إن الإصدارات التجريبية أكثر تواترا من إصدارات غا، ولكن يجب أن يكون ذلك كله.
اختبرت العديد من أنظمة الإصدار والآن أنا سعيد جدا مع هذا واحد:
يتم تعيين الرائد بشكل يدوي والرجوع إلى إصدار بما في ذلك التحسينات الرئيسية يتم تعيين الصغرى أيضا يدويا وتشير إلى إصدار ترقية / صيانة، بما في ذلك تحسينات طفيفة & أمب؛ الإصلاحات يتم إنشاء المراجعة تلقائيا وتشير إلى مراجعة دقيقة في المستودع.
آخر واحد يسمح لنا أن تكون مرنة جدا مع فيرسيونينغ. يمكننا أن نشحن إصدارات متعددة للعديد من العملاء، ولا تزال قادرة على تصحيح & أمب؛ إصلاح مع سهولة عن طريق الحصول على نسخة محددة من ريبوس، ثم دمج مرة أخرى مع الجذع.
بناء، التعبئة والتغليف & أمب؛ النشر مؤتمتة بالكامل. الإجراء اليدوي الوحيد هو عندما نقوم بنقل الحزمة الأخيرة إلى ملقم الإنتاج بواسطة فتب. نحن نريد للحفاظ على السيطرة على ذلك لضمان أننا لا تسليم حماقة في الإنتاج. يذهب إلى مرحلة أولية حيث الأوائل يمكن قراءة ملاحظات الافراج ثم تقرر تحميل واستخدام النسخة. يمكن للعملاء الذين يواجهون البق محددة الحصول على نسخة ثابتة سريع جدا باستخدام واحد من هذه الإصدارات.
يمكنني استخدام الإصدار الدلالي لمكتباتي مفتوحة المصدر وتجد أنه من الأسهل بكثير للعمل مع المكتبات الأخرى التي تفعل كذلك. وهو يوفر أساسا مشتركا لفهم ما قد يعنيه تغيير الإصدار. هل المكتبة لا تزال في مرحلة تجريبية؟ هو إصدار فقط لإصلاحات الشوائب؟ هل سيكون هناك تغييرات متقطعة في واجهة برمجة التطبيقات؟
وهو في الأساس تدوين لأفضل ممارسات الإصدار التي تستخدمها بالفعل معظم المشاريع المفتوحة المصدر.

استراتيجيات إصدار البرامج.
عالقة الكمال في العالم الحقيقي.
إصدار البرمجيات يمكن أن تكون واحدة من تلك المناطق حيث كنت لا تشعر وكأنك حصلت عليه بالضبط الحق. ليس هناك توجيه محدد هناك مع حل من شأنه أن يرضي الجميع. معظم فرق البرمجيات إما الخلط حول هذا الموضوع، أو يختارون تجاهل ذلك. ويهدف هذا الدليل إلى سد الفجوة، وتقديم نظرة عملية على مختلف الاستراتيجيات الشعبية والمفاضلة.
بعض التقنيات سوف تكون موجهة نحو ميكروسوفت كومة (ويندوز،)، كما هو ما أنا الأكثر خبرة مع، ولكن المبادئ تنطبق بشكل عام. لينكس، Node. js، بيثون & أمب؛ كما تم تطرق روبي قليلا.
إصدارات في كل مكان.
نحن جميعا جميلة تستخدم لمصطلح "نسخة" في الوقت الحاضر. الأكثر شيوعا في العالم البرمجيات، فقد تسربت إلى وسائل الإعلام وغيرها من الصناعات. ويجري حاليا إصدار إصدارات الفيلم - "فاست & أمب؛ فوريوس 7" (7!؟)، ويجري الآن إصدار الأحذية - "إير جوردان XX8"، والأكثر شعبية، يتم حاليا إصدار الكتب - "مدير دقيقة واحدة، طبعة 1984". في الواقع، بالنظر إلى الكتب، والناس قد تم إصدار بعض الوقت الآن - "موسوعة بريتانيكا"، منذ 1768!
الفرضية بسيطة - حيث أن المنتجات تعيش على ومواصلة تحسين، الإصدارات الجديدة يجب أن تكون متميزة عن الإصدارات السابقة. اسم المنتج لا يتغير، لأن السوق أصبحت بالفعل مألوفة معها، لذلك يتم إلحاق شيء في النهاية للإشارة إلى أنه هو أحدث (أو مختلفة).
في حين أن الإصدارات موجودة منذ فترة طويلة من العصر الرقمي، والبرمجيات دفعت حقا القضية إلى الأمام. يعد تعديل نسخة جديدة من البرمجيات وإصدارها عملية سريعة جدا، أسرع بكثير من تغيير خط الإنتاج الصناعي لإنتاج قطعة جديدة من الملابس أو طباعة طبعة جديدة للكتاب. وهكذا دورات التكرار البرمجيات هي أقصر بكثير، وإمكانية للكثير من الطبعات المتزامنة هو أكبر من ذلك بكثير.
ببساطة استخدام سنوات (أو حتى أشهر)، كما هو الحال في طبعات الكتاب، ليست كافية. ويمكن إنتاج إصدارات جديدة من البرنامج في غضون دقائق. وبالإضافة إلى ذلك، والبرمجيات لديها جانب مواز هائل لذلك - تيارات البرمجيات - حيث يمكن أن توجد العديد من الإصدارات الرئيسية، وكلها يمكن تحديثها باستمرار في نفس الوقت. هذا نادرا ما يحدث مع حذائك. (أتمنى لو فعلت ذلك، وأحيانا أنا فقط لا أريد أن الترقية إلى نموذج كتالوج هذا العام، أريد تحسين زوجي القديم!)
لماذا الإصدار؟
قبل الغوص في كيفية تنفيذ الإصدار، دعونا نتوقف وننظر لماذا نحن نريد أن نفعل ذلك في المقام الأول! بعد كل شيء، إذا كنا نعرف الأسباب الدقيقة لماذا هو مفيد، ثم يمكننا أن نحكم بشكل أفضل ما إذا كانت الحلول المقترحة هي مناسبة.
لقد أشرنا إلى هذا في القسم الأخير، مشيرا إلى ما يسمى النسخة العامة. هذا هو الإصدار المرئي بشكل عام، وغالبا ما يحمل وزن التسويق (بمعنى أنه من المرجح أن يتم تعريفه من قبل قسم التسويق / المبيعات). "ويندوز 7" و "إفون 5S" و "أوفيس 2018" - كلها أمثلة على إصدار عام.
ويهدف الإصدار العام لتكون بسيطة ولا تنسى، مشيرا إلى العملاء أنه جديد & أمب؛ لامعة (على افتراض أن الناس يريدون عموما "جديدة وبراقة"). الناس لا يفهمون "10.6.6527.14789" - لكنهم يحصلون على "2018" أو "5". لقد كانت شعبية متزايدة لاستخدام السنة من الإفراج عن عدد الإصدار العام، كما أنها ببساطة وبقوة ينقل ما يصل إلى تاريخ الوضع. كانت شركات صناعة السيارات تفعل ذلك لفترة طويلة.
الإصدار الخاص هو ما كنا عليه في عالم البرمجيات. طابع داخلي (نأمل) يحدد بشكل فريد قطعة معينة من البرمجيات. البرمجيات، مثل سيارة، يمكن أن تكون مصنوعة من أجزاء كثيرة. أخذ قياس السيارة كذلك، السيارة "نسخة خاصة" هو رقم الشاسيه فين. المصنعين الافراج عن والحفاظ على كتالوجات ضخمة من أجزاء، ورسم خرائط لسيارة "أرقام الإصدار". يمكن ميكانيكي ثم أمر جزء بالضبط التي تناسب سيارتك.
بدون "رقم الجزء الخاص"، لن تكون قادرا على خدمة البرنامج الخاص بك في البرية، لأنك لن تعرف بالضبط "الشكل" أن وحدة استبدال يجب أن تكون لتناسب النظام العام. تخيل إذا كنت اضطر لتغيير السيارة بأكملها عندما كسر ضوء الذيل.
لذلك، يتم استخدام رقم الإصدار الخاص تماما مثل معرف الكتالوج. الغرض منه هو أن تستخدم عند استكشاف الأخطاء وإصلاحها أو صيانة البرنامج. (أنا أحب جيف أتوود في "دوغتاغ" قياسا!) يجب أن خريطة إلى وصف ما قطعة البرنامج هو مثل - ما هو شكله وظيفة. وما أفضل "وصف" من شفرة المصدر الأصلي نفسه!
الاستخدام يتلخص أساسا إلى:
تحديد شفرة المصدر الأصلية لجزء من البرنامج، لتمكين التصحيح التدريجي وتأكيد عملية معيبة تحديد ما إذا كان جزء واحد "متوافق" مع آخر، أو ما إذا كان يمكن أن يحل محله.
يتم إنجاز كل هذا مع رقم الإصدار الخاص. الإصدار العام هو مجرد علامة التسويق، ويخطط إلى واحد أو أكثر من أجزاء البرمجيات الداخلية، ولكل منها نسخة خاصة بها. (تماما مثل تويوتا كورولا 2018 يحتوي على إطار ZRE142 ومحول عزم الدوران 32000-12420)
استخدام الإصدار.
في ويندوز يتم دعم مفهوم رقم الإصدار بواسطة طبقة من نظام التشغيل. يتم تضمين أرقام الإصدار في كافة الملفات الثنائية القابلة للتنفيذ، ويمكن أن ينظر إليها عند تحوم فوق إيكس / دل في مستكشف ويندوز، أو عند عرض خصائص. في الواقع، أي ملف يمكن أن يكون "الموارد" يمكن أن يكون إصدار، لأنه يتم تخزينها في المورد فيرسيونينفو.
ويستخدم التنسيق العام الذي نستخدمه جميعا: main. minor. build. revision (على سبيل المثال "1.2.360.0"). من المهم أن نلاحظ أن كل عدد يقتصر على 16 بت، وحتى لا يمكن أن يتجاوز 65535. وهذا له بعض الآثار على ما يمكن أن تمثل مع هذه الأرقام.
لاحظ أن تسمية لهذه الأرقام ليست محددة بدقة - فهي بسيطة 4 أعداد صحيحة قصيرة. ويشار إلى الأولين باسم الرئيسية والثانوية جميلة بالإجماع. آخر اثنين هو حيث نرى بعض الاختلاف، اعتمادا على نظام الإصدار.
يستخدم هذا الإصدار بشكل بارز أثناء عملية تحديث ويندوز، والذي يستخدم تقنية ويندوز إنزتالر (مسي) لتحديث أجزاء مختلفة من النظام. بشكل أساسي، يتبع ويندوز إنزتالر قواعد معينة لتحديد ما إذا كان التحديث الذي يتم تثبيته أحدث من ما تم تثبيته بالفعل. إذا كان الإصدار أكبر، ثم انها موافق لتحديث.
بطبيعة الحال هذا المفهوم يتدفق إلى الإطار، الذي بني حول العديد من المفاهيم ويندوز القائمة. لدينا فئة الإصدار، الذي يتبع 4 عدد صحيح نموذج. يمكننا أيضا تعريف أسمبليفيرزيوناتريبوت و أسمبليفيليفرزيوناتريبوت، التي تحدد إصدار التجميع ومصدر إصدار ويندوز على التوالي.
في الإصدار التجميعي موجود بشكل منفصل عن الإصدار الأساسي الذي يستند إلى ويندوز فيرسيونينفو، وهو ما تراه في مستكشف ويندوز (أو خصائص الملف). وهو يشكل جزءا من اسم الجمعية قوية، ويستخدم حصرا من قبل الإطار عند حل التجميعات. اثنين - نسخة التجميع وإصدار ملف ويندوز - يمكن أن تكون مختلفة، ولكن في كثير من الأحيان أنها هي نفسها لتجنب الارتباك.
يستخدم إصدار تتبع التبعية، بمعنى الإشارة إلى نسخ التجميعات المشار إليها، مما يجعلها واضحة عندما يكسر التحديث التوافق للتطبيق الذي يعتمد على مكتبة معينة. هذه خطوة إلى الأمام من إصدار ملف ويندوز الأصلي، والذي كان يستخدم فقط أثناء عملية التحديث، وليس عند الرجوع إلى مكتبة، مما يؤدي إلى سيئة السمعة "الجحيم دل".
ومن الجدير بالذكر أن النسخة ق يسمح 4 أعداد صحيحة 32 بت، في حين أن أسمبليفيليفرزيوناتريبوت يقتصر على 16 بت، كما أنها خرائط مباشرة إلى الموارد فيرسيونينفو. وبالتالي، إذا أردنا أسمبليفرزيوناتريبوت و أسمبليفيليفرزيوناتريبوت أن تكون هي نفسها، وهذا يضع فعالا حد على مكونات الإصدار التجمع كذلك.
لينكس، بشكل عام، يستخدم طريقة مختلفة لمعالجة الإصدار. لا تحتوي الملفات الثنائية على طابع إصدار مضمن، مثل معظم ويندوز الثنائيات القيام به. وبدلا من ذلك، يشير اسم ملف المكتبة المشتركة إلى إصداره، على سبيل المثال. /usr/local/lib/mylib. so.1.5.
يتم إنشاء عدد من الروابط الرمزية، على سبيل المثال. mylib. so - & غ؛ mylib. so.1 و mylib. so.1 - & غ؛ mylib. so.1.5. يمكن تطبيق مرجع مكتبة عن طريق رابط رمزي، مثل mylib. so.1، والحصول على أحدث نسخة متوافقة 1.x مثبتة.
هذا يعمل بشكل جيد إلى حد ما، طالما الجميع يتبع هذه الاتفاقية. كل مكتبة يمكن ثم، بدوره، تحميل المكتبات يعتمد على بطريقة مماثلة.
كما سيكون مستخدمو لينوكس على دراية ب "أداة الحزمة المتقدمة" الشهيرة، أبت-جيت، التي تستخدم بشكل واسع على الأنظمة المستمدة من دبيان مثل أوبونتو. كونه مدير حزمة صحيح أنه يدعم تثبيت جنبا إلى جنب الإصدارات وتتبع تبعيات بين الحزم. نلقي نظرة فاحصة على مزايا مديري الحزم في الأقسام التالية.
مخططات أرقام الإصدار.
هناك العديد من برامج الترقيم نسخة شعبية للبرامج، ولكن كل منهم هو الاختلاف من نفس الموضوع وتبادل الصفات المشتركة. وجود مكونات النسخة الرئيسية والثانوية هو نفسه في جميع المجالات. إن ما يمثلونه متسق إلى حد ما:
زيادة عدد كبير: يمثل تغيرات كبيرة في نظام البرمجيات، في كثير من الأحيان غير متوافقة مع الوراء، أو إضافة كمية كبيرة من وظائف جديدة زيادة عدد قليل: يمثل تغييرات تطورية أقل جوهرية، وذلك أساسا التحديثات أو التحسينات في الوظائف الموجودة، أو إضافة جديد أصغر مجموعة الميزات.
أعلاه هو دليل واحد فقط - لا توجد قواعد محددة حول ما هي الإصدارات الرئيسية والثانوية من المفترض أن تمثل. فقط أن من المفترض أن تزيد كما يتم إضافة المزيد من الميزات إلى البرنامج مع مرور الوقت.
ويندوز وثنائيات تحديد مخطط إصدار 4-جزء: الرئيسية. تحت السن القانوني . بناء. مراجعة . والمكونان الأخيران هما شكلان حران إلى حد ما، وهناك العديد من الاختلافات في ما يمثلونه، فبعضها يستخدم عدادات بناء تدريجية، وبعض تاريخ / وقت استخدام المبنى، وبعضها يستمدها من أرقام المراجعة الداخلية لمراقبة المصدر.
يتجاهل الكثيرون رقم المراجعة، والتركيز فقط على البناء. مثبت ويندوز، على سبيل المثال، يحتوي فقط على 3 مكونات. إذا كنت تريد الإصدار الخاص بك لتمتد على كل من الثنائيات والحزمة التي تحتوي على، فمن الأفضل للحد من نفسك إلى ثلاثة أرقام فقط: الرئيسية. تحت السن القانوني . بناء.
في أي حال، فإن النمط العام: كلما زاد عدد الإصدار، وأكثر حداثة البرنامج.
وقد أطلق على نظام إصدار شعبية في السنوات الأخيرة (وخاصة بين المشاريع مفتوحة المصدر) النسخة الدلالية (الملقب سيمفر)، وتوثيقها في سيمفر. فإنه يقدم بضعة مكونات أخرى، ويجعل نسخة سلسلة أبجدية رقمية، بدلا من رقم نقي - فتح بعض الاحتمالات مثيرة للاهتمام.
المكونات الثلاثة الأولى هي نفس ما ناقشنا بالفعل، مع التصحيح يجري اختياري. التصحيح هو إلى حد كبير يعادل عنصر بناء، ولكن الدلالات يمكن أن تكون مختلفة. إصدار الدلالي في الواقع يصف عند كل عنصر يجب أن تكون متزايدة (على أساس "أبي العامة" التغييرات).
التجريبي، إذا كان محددا، عبارة عن سلسلة أبجدية رقمية تستخدم لوضع علامة على إصدار كتلك التي تسبق الإصدار النهائي. على سبيل المثال، 1.3.567-rc1 سيسبق 1.3.567. هذا مفيد لإرفاق معنى أكثر إلى تسمية الإصدار من ببساطة عن طريق استخدام الأرقام.
تعد البيانات الوصفية عنصرا اختياريا آخر، مما يسمح بوضع علامات إضافية على تسمية الإصدار (عادة باستخدام طابع زمني للبناء)، إلا أنه لا يشارك في ترتيب الإصدار، أي الإصدارات التي تختلف فقط في البيانات الوصفية تعتبر نفسها.
بريليليس مفيد مع مديري حزمة مثل نوجيت، التي تعاملهم بشكل مختلف - أنها تعتبر غير مستقرة وغير مرئية لعامة الناس، إلا إذا طلب صراحة. وهذا يسمح بالإفراج عن إصدارات ألفا / بيتا دون التأثير على تلك التي تعتمد على الإصدارات المستقرة.
يمكن أن تكون علامات التجريبي مفيدة أيضا في تدفق الإصدار الداخلي عند التعامل مع الإصلاحات العاجلة المتوازية والبنيات الخاصة، كما تمت مناقشته لاحقا في هذه المقالة.
إصدار الملفات غير الثنائية.
لذلك نحن نعرف كيفية ختم نسخة على الملفات الثنائية. ولكن ماذا عن الملفات الأخرى التي تتألف من نظام البرمجيات - ملفات التكوين والصور والوثائق والخطوط، وما إلى ذلك؟ كيف يمكنك ختم نسخة عليها؟
ماذا عن أطر الويب مثل أسب (أو روبي، Node. js، بيثون، الخ) حيث يمكن تعديل ملفات المصدر والصفحات في مكانها، وتحديثها تلقائيا؟ كيف يمكننا تصحيح نظام ويب، بمعنى تحديث بعض الملفات المستهدفة، وما زلنا نحتفظ بها في الإصدار؟
الجواب هو - لا تحديث الملفات الفردية! لا توجد طريقة بالنسبة لك للحفاظ على رقم إصدار مفيد لتطبيق البرنامج الخاص بك، إذا كان يمكن تحديث الملفات غير الثنائية الفردية المخصصة كإصلاحات عاجلة.
تحديث باستخدام حزمة بدلا من ذلك.
أهمية البناء والحزمة.
عندما تسمع مصطلح "بناء"، عادة ما يتبادر إلى الذهن تجميع - معظم اللغات المترجمة، مثل C #، C ++ أو جافا، يجب أن يتم تجميعها في ثنائي قبل أن تكون قادرة على تنفيذها. وهكذا يرتبط البناء عادة بعملية التجميع.
ولكن هذه ليست صورة كاملة. بعض اللغات أو الأطر، مثل بيثون أو أسب، لا تتطلب تجميعا صارما. ويمكن تفسيرها إما في حالة بايثون أو تجميعها على ذبابة في حالة أسب. ما الذي ينبغي القيام به لهذه الأنظمة؟ كيف يمكنك "بناء" تطبيق بايثون؟
هذا هو السبب في أنه من المفيد التفكير في بناء عملية التجميع، أو ببساطة التعبئة والتغليف. تماما مثل خط السلع الاستهلاكية، على سبيل المثال. والأحذية، يحصل تعبئتها قبل الشحن إلى المخازن، لذلك لا نظام البرمجيات، قبل أن يطلق سراحه.
مفهوم الحزمة هو ضروري لإصدار، لأن الحزمة هي مجموعة واحدة من القطع التي تتألف من نظام البرمجيات، أو جزء منه، وبالتالي يمكن تحديدها، وختم مع نسخة. With the right Package Management system (which we look at in the next section), it can be deployed and updated, and specify dependencies on the other packages.
Software today is never a single binary executable file - it is a collection of various binaries, libraries, documents, configuration files, images, and other resources. A package is what helps us group them together, version and release to the outside world.
A package doesn't have to be sophisticated, although it helps in some situations (e. g. databases). It can even be a simple ZIP file, that can contain version in the file name, or embedded as a text file. In fact, many open source projects do just that - a release is a ZIP or a. tar. gz archive.
The important thing is that a package is a single unit, that is released and updated at the same time, leading to consistency . It is common to have several packages, for example, representing "client" and "server" components, or any other logical grouping applicable to a software system. Each package can then be updated on its own.
Let's take a look at some of the common packaging methods, the versioning approach, and which application they are best suited for.
Windows Installer.
Best Suited : Complete Windows GUI Applications, Windows Services, or Drivers.
The oldest, and for a long time the only recommended way, to install applications on a Windows platform. It has a built-in versioning support and a sophisticated (some would say "complicated") set of rules for determining when to update components. While a Windows Installer package (.msi) is a single file, in essence, it is a collection of small logical components (down to single files) that can be updated independently.
Windows Installer will actually check each individual file that is being installed, whether it has a version and whether the version is greater than a file with the same name already installed. That means it is important to version not just the installer package, but each file contained in it. But it also means that it is incredibly difficult to do downgrades (i. e. rollbacks) with Windows Installer.
It is best suited for traditional Windows Applications (GUI, services, drivers) that are released to the public. It is, however, not the best choice for internally developed & distributed applications, any kind of Web applications, or database systems.
It was also used to deploy distributable libraries (native DLLs) and COM objects, but with today's focus on , it is not the right mechanism for distributing libraries.
Web Deploy.
Best Suited : Web Applications (IIS, ASP)
Web Deploy technology was specifically designed for deploying and synchronizing applications on Microsoft IIS web servers. IIS Web Farm replication uses Web Deploy commands and packages behind the scenes to synchronize sites across a set of servers. IIS Manager has an extension (enabled by installing Web Deploy) to "Import Application", which can install or update a web application using a Web Deploy zip package.
Its biggest disadvantage is that it can only be used for web applications on Microsoft IIS platform, and the limited mechanism for customizing installation. While it could be suited for simple web applications, it can quickly become frustrating for anything more sophisticated, i. e. variables, conditional logic, databases, etc.
In addition, it has no inherent support for versioning .
Package Managers.
Best Suited : Shared Libraries, Dependencies, Command-line Utilities.
Package Managers are great for releasing and versioning shared components, and tracking dependencies between them. For example, if you have a shared library that you want others to use, then a Package Manager allows you to publish multiple versions side-by-side, and for consumers of the library to reference the version they depend on. Package Managers can resolve all inter-package dependencies, and retrieve only the versions that are expected. In effect, Package Managers solve the "DLL Hell" problem.
They are best used during development, to resolve library dependencies. However some Package Manager, like Chocolatey for Windows or apt-get for Ubuntu, are geared towards installing complete software.
Most importantly, Package Managers are designed around the versioning concept . So they are a perfect mechanism for distributing versioned software libraries.
For we have NuGet. A lot of open-source libraries have been published to its online repository, and it is now the defacto standard for distributing 3rd party components. It is encouraged that every team sets up their own NuGet repository to share and publish internally developed libraries in a versioned manner.
NuGet can even be used to release complete software systems - see next section.
Other development environments have their own - npm for Node. js, pip for Python, gems for Ruby, apt-get on Linux. Package Managers have been proven to be extremely useful, and have exploded in popularity.
Octopus Deploy.
Best Suited : Internally Developed & Deployed Software.
Octopus uses NuGet as the packaging and versioning shell. It is similar to an installer, only driven by PowerShell, meaning infinite flexibility in how the software is to be deployed. PowerShell already has a great support for configuring Windows Services, IIS Web Applications, Scheduled Tasks, SQL Server, and more.
For internally developed and distributed software (i. e. for a company running home-grown software solutions) this is a perfect release management vehicle. Packages are versioned and pushed to a shared NuGet feed (e. g. a network share), from where Octopus Deploy can release and deploy each package into the appropriate environment.
NuGet here plays a role of the application package/container, with a version stamped on it. Package can be built once, and then deployed as many times as needed to whatever environment.
Versioning & Packaging Databases.
Database versioning is one of the biggest challenges in software projects. Almost every team I encountered, either completely ignored it or had something inadequate in place. It certainly presents a challenge - database systems mix schema definition with actual live data , and there is no single "file" that can be effectively versioned.
We have to recognize the database as an integral part of the software system. One that executes on a proprietary 3rd-party platform (SQL Server, Oracle, PostgreSQL, etc), but the source of which is part of the software definition. It can be compared to script-based systems, such as Node. js or Python, only the scripts are written in a SQL dialect.
There are essentially three popular approaches to database versioning, that support automated deployments (I am not considering manual approaches, because they are error-prone, and have nothing to do with real versioning!).
DB - Migrations.
"Migrations" is a concept where developers keep a set of organized SQL script files, numbered sequentially, where each script applies modifications to the target DB to bring it to the expected state. Whenever a change is needed to the application database, a developer creates a new migration script that applies the delta changes.
All of the scripts are kept as part of the source control, and are packaged with the application (either embedded into the executable binary, or installed along-side). A migrations library then checks the target database for a dedicated table which holds the last "migration script number" applied, and then runs all the scripts with a number greater than that in order, effectively applying all of the changes in turn.
While this approach is simple to implement, and is favored among several popular frameworks (Ruby Rails, Entity Framework), it has a number of significant short-comings . Firstly, there is no single source view of all database objects (i. e. tables, stored procedures, etc), they are sprinkled through the multiple migration scripts. It is not clear which of the scripts contains which of the modifications. One has to "replay" them all to generate a database, and then look directly in the database (rather than source code).
Secondly, the migration scripts number becomes the "version" of the database, which is different from the software package version number for the rest of the application. This is somewhat confusing. In addition, this "version" does not really identify the state of the database, since a database can be changed outside an application without updating the "version". This may potentially break future installs, because migration scripts expect the database to be in a certain state to work.
Thirdly, developers have to be disciplined enough to follow the structure and apply ALL changes through migration scripts . Furthermore, when developing and debugging locally, one often has to go through several iterations before getting that table or store procedure change right. Yet only the final changes should make it into the migration script , meaning they have to be remembered and written manually. Otherwise, migration scripts would contain all of the intermediate changes made by all developers on the project. It is easy to see how that can grow out of proportion quickly.
Finally, there is an argument that migration scripts are a "history of changes", and it is a bit of a redundancy to store them in source control, which already is a "history" of code changes. We would be storing a history of a history . There's something philosophical about that.
Supported by some frameworks and libraries (Rails, DbUp, RoundHousE, EF Code First) Can work with any database Potentially high degree of control over SQL scripts.
Have to manually maintain all migration scripts Tracking changes through source control is difficult Not robust against target database out-of-band changes.
DB - SQL Compare.
Most often this is used in a manual approach, comparing a database between two environments (e. g. development vs test) to copy over the changes. We are considering an automated approach, suitable for the packaging and versioning strategies being discussed.
In source control, database is represent by a series of creation scripts (e. g. to create tables, stored procedures, triggers, etc), such that a new database with the right schema can be created from scratch. Usually each script file logically represents a corresponding object in the database, e. g. Table1.sql would be the create script for Table1 table. All of the scripts are included in the released package (sometimes even combined into a large single create script, by concatenating them).
The idea is that during automated package deployment a temporary fresh database copy is created, by running all of the creation scripts , and then a SQL Compare tool is executed to compare the pristine copy with the target database to generate a migration delta script on the fly.
The advantage of this approach is that it is robust against the target database out-of-band changes, since delta script is generated during deployment , rather than during development. SQL Compare tools (such a RedGate's SQLCompare or XSQL Compare) are sophisticated and mature enough tools that we can have some confidence in the generate SQL code. Each can be controlled by a multitude of options to fine-tune behavior with respect to renames, reordering columns, avoiding drops, etc.
In this case, target database is considered as a runtime environment , and we avoid having the issue of versioning it . Instead we version the package that contains all of the creation scripts , which is much easier, and use it to synchronize target database with what's expected in each version.
The big disadvantage of this approach is the difficulty of getting it right - there is no off-the-shelf framework that would support it, and it has to be developed. For SQL Server, read the next section for a better approach. For others, some day I may put together the set of scripts and logic necessary to achieve this, based on some of my prior work (unless someone else beats me to it).
Automatically detect and migrate changes, regardless of target DB state Only maintaining DDL (i. e. create) scripts in source control, meaning easy change tracking.
More difficult to setup, especially to be automated Having to create a temporary database during each deployment (need " create database " permission)
DB - DACPAC (SQL Server)
For SQL Server there is now a new recommended approach - DACPAC, and it can be produced by Visual Studio 2018 and above, if using the SQL Server database project. Really, this is a slick variation of the "SQL Compare" method above, just that Microsoft has done all the heavy lifting for you!
Essentially, DACPAC is a zip package which contains an XML schema model of what the target database should look like. It is compiled by Visual Studio based on the creation scripts in your project. In fact, it represents that temporary pristine database that we would have had to create manually. Only it is done automatically and the schema represented in an XML format. The real bonus is that a DACPAC can be versioned , i. e. its metadata supports storing a version number.
SQL Server Data Tools can be used to deploy a DACPAC package, which really performs a SQL Compare operation between the in-memory database model loaded from DACPAC and the target database. It does the same thing as SQL Compare, but avoids having to create the extra temporary database copy to do the comparison.
For applications having SQL Server as a back-end, a DACPAC can be included as one of the deployable packages, stamped with appropriate version generated during the build. Starting with SQL Server 2008 R2, database can be registered as a Data-Tier Application, and the latest DAC version is tracked in a system view that can be queried.
Can package the whole DB definition into a single package (or several packages) Can apply the same version to the package as the rest of the software system Same advantages as the SQL Compare method.
SQL Server only Need to treat lookup data in a special way (post-deploy MERGE script)
Build Auto-versioning.
Given the importance of consistent versioning discussed above, it makes sense to implement a strategy for automatically generating and stamping a version number during the software automated build process. We want the version number to be applied to the produced packages, and also applied to all the binaries generated through compilation.
There are several well-known and not so well-known ways of achieving this. We look at pros and cons of each.
Applying Build Number.
There are some who prefer to update the version number manually just before a release. I will argue that this is a bad practice. Firstly, it is easy to forget to do it, if you don't have an automated system for incrementing the version build number. And, if it is easy to forget, it will be forgotten at some point.
Secondly, without automatically updating build number, there will be multiple packages produced from the source code that have the same version number, but different functionality (as more commits are made to the source control). This will be confusing to say the least.
It is better to have a process, like ones described below, where version number build component is automatically updated whenever a non-local build is made.
Multiple Versions for Multiple Components.
If there are multiple software components, where each needs to have its own version number, then it is best to split them each into its own separate build. Don't mix multiple version numbers in the same build, as it unnecessarily increases the complexity, and raises a question about which of the build numbers should be used to label the build itself (in addition to having to tag each source sub-tree separately).
Developer vs Continuous vs Release Builds.
Release build is the one that will potentially be released to public or a particular environment - test, staging, production, etc. That's the build that needs to be consistently versioned to keep track of changes that are included and to link back to the source code at the time of compilation.
Note that the Release build can scheduled - it is popular to have a Daily or Nightly build. In most situations it should be the Release build, i. e. it should be versioned and packaged ready to be released.
Continuous Integration builds run whenever someone commits to the repository and are used to validate that the code compiles, and passes unit tests. There is no need to version this build, as it is not intended to be released.
Developers must also be able to do a Developer build , whether it is to test/fix the build process itself, or to generate shared software components to be used in development. Such builds are intended to be run locally only and should never be publicly released.
You can default the build part of the version number to "0". This will identify Developer builds, i. e. ones that are not supposed to be released. For Release builds pass the build number to your build scripts as a property. Have MSBuild stamp a version number on all generated assemblies and packages.
Tagging Source Control.
Since one of the primary reasons for having a version number is to be able to link back to source code used to build the software (see beginning of the article), it is important to create tags/labels in source control that identify the state of source code at the time that version was built.
Various systems call it differently - TFS has "Labels", Git has "tags". Tag should include the full version (including the build number) of the build, so that it can later be found, if needed.
Build Number - Version File Auto Increment.
Common technique is to record version number together with source code, usually in a separate file (e. g. "version. txt"). The build process then finds the file, reads the version, increments the build number portion, and commits the file back to repository.
If the commit message also includes the version number, e. g "Auto-increment: 1.3.156.0" , then it comes in handy when viewing commit history. You can see the changes that occurred between versions clearly by seeing the commits between the two "Auto-increment: . " messages.
This works fairly well, but has a few drawbacks. Mainly due to the fact that "version" becomes part of the source code. When merging changes between say release branch and main, you have to resort to "cherry-picking" (i. e. selecting just the code changesets) to avoid merging the modified version number. That requires being always careful, because you can accidentally change the versioning sequence of another branch just by merging the "version file" into it.
Control over the build number sequence (i. e. sequential) Can make it easy to see changes between versions in source control history.
Difficult to control merging between code branches in source control.
Build Number - External.
Overcoming the drawbacks of the auto increment approach, it is possible to track the build number outside of the source tree. Build server software such as CruiseControl or TFS Builds can do that - they track a build number internally for each "project" and are able to pass it as a parameter to MSBuild.
Version file is still used, but it records major and minor versions only, and doesn't have to change between each build. This makes it easier to merge changes from release branches back to main and others, since they will contain only code changes, without being intermingled with version increments. Major/minor version changes would occur early in the development cycle, when starting work on the next update, and are already set by the time release branch is created.
Not modifying source tree on every build makes merging between branches easier Versioned builds are forced to be built by a dedicated build server.
Relies on a build system that can supply a build number (e. g. CruiseControl, TFS Builds) Changing build number sequence can be difficult (e. g. TFS Builds)
Build Number - Derived from Date/Time.
A popular alternative is to derive build number for the date/time of the build. The advantage being that it carries more meaning (useful in diagnosis), and each build inherently should get a different build number (with later builds getting a higher number).
The trick, of course, is fitting all this into a 16-bit number, if using the standard 4-part Windows version number. While some solve it by using both, the build and revision components, I cannot recommend it, because revision cannot always be applied to external packages (like Windows Installer, or NuGet), which use only a 3-part version number.
This only allows only 4 unique builds per day, which is not a lot, unless all you want is a daily build .
Not depending on keeping track of the last build number Build number can be given more meaning, if it derives from a date.
Build number is not sequential (but it increases nevertheless) Limited to 16-bit (maximum 65535), so some overflow into revision (4th) number.
Build Number - Derived from Source Control.
A variation of the previous technique is to derive build number from a unique property in source control. With a centralized SCM like Subversion or TFS, a revision or changeset number is an ever increasing number that is tied directly to the source code. The big problem with it is that it can quickly overflow the 16-bit limit, meaning you may have to accept build numbers looping back to zero.
An alternative in distributed SCM, like Git, is to use the size of the commit history log as the build number. This will monotonously increase for any single branch, as new commits are made. It too can overflow the 16-bit limit, but goes a lot further than the global revision number.
Example: git rev-list HEAD --count.
Not depending on keeping track of the last build number No possibility of "forgetting" to update version file, or accidentally merge it to/from another branch.
Commit history size will grow beyond 65,535 at some point, overflowing the 16-bit build number.
Parallel Branches.
It's no secret that developing for multiple versions requires multiple branches in source control, each representing a "version" stream for the software. They can be roughly divided into:
Development branches - where unstable code for the next version lives, and where developers commit daily work Feature branches - veering off from development branches, encorporating larger feature development, that would otherwise disrupt other team members Release branches - representing versions of released software, or a release undergoing stabilization.
Each release branch needs to have an identifying version, and is usually named after it, e. g. "1.7" . A decision of whether to create a new release branch depends on how long it is expected that it will be in stabilization mode before releasing, and whether concurrent live versions are permitted (i. e. for packaged software). If you need to be able to maintain & hotfix the current released version, while a new version is being tested & stabilized, then create a new branch.
Development and feature branches need to have a version number that is above any of the existing release branches to avoid confusion. For example, if a 1.7 release branch is created, for the upcoming 1.7 release, then immediately update development branch version sequence to 1.8 .
Versioning feature branches is more difficult, since you don't want to start a new versioning sequence for every feature . Nothing should be "released" from feature branches, so this version is for internal purposes only. If using Semantic Versioning, attach a prerelease tag to clearly indicate this is a version for a feature branch, e. g. 1.8.781-dev-feature-x .
In any case, you wouldn't deploy anything built from a feature branch to the shared testing or production environment, or release a package from it. So it is acceptable to have version sequence overlap with that of development branch.
Finally, in the next section we look at how to version patches & hotfixes that are applied to release branches.
Handling Patches / Hotfixes.
Devising a system to handle patches depends heavily on the rest of the software development cycle, which is what many teams forget when searching for the "one, true way" of handling concurrent patching of the released/production software in parallel with working on the new version.
For example, having a short QA/test cycle, where most of the tests are automated, results in a more simplified and robust system, which does not have to deal with multiple parallel hotfixes "in test".
Overlapping hotfixes.
One difficulty that comes with managing parallel development is consistent versioning and deployment strategy that would overcome inherent conflicts. Consider following scenario: you have recently released a software package 1.5.167. Two urgent show-stopping issues have slipped past your QA process and now require a quick fix. You assign two developers to work on each one in parallel. How would they commit their fixes to minimize conflicts? How do you test each fix? How do you release one independent of the other?
This is a good example of the complexity of software release processes that can be encountered in real-world teams. It applies both to internal software and packaged software, but distribution of the hotfix might be slightly different for each one.
First, let's consider what happens if we remove concurrency . In the case where the two issues are worked one after the other , the solution becomes simple. The first fix gets committed into the maintenance/hotfix branch for 1.5 release stream, a new build is generated, with an incremented build number. Build goes through a quick QA cycle to make sure there is no regression, and then it is ready to be deployed. Same process repeats for the second fix.
The problem with concurrent approach is the time when development is in parallel, creating the entangled case where there is no build/package that contains only one of the fixes , i. e. independent of the other. This problem is magnified by a slow QA cycle , usually meaning there are no automated tests. While one fix is in test, if a commit for a second fix is made to the same branch, and a problem is discovered with the first one, it becomes very difficult to separate the two now.
The culprit here is, of course, the concept of a partial fix - the state where the fix is not complete. It has been committed, but has a problem with it, requiring further commits . This can easily create the case of a hotfix branch where the two fixes are "entangled" (quantum physics on the code level!).
Solution is to remove possibility of a partial hotfix .
This means that each hotfix has to be coded and tested in a separate code stream, independent of the other. Once tested, and ready for release, it is merged into the main hotfix release branch, where the automated build can create a new package and apply versioning (i. e. increment build number, for example, to 1.5.168).
Second hotfix, once tested, also has to be merged into the main hotfix release branch. But, because during the work on this second hotfix, the first hotfix got released, we first merge the first hotfix into the second hotfix's branch ! This ensures that we can test how the second hotfix operates, when applied on top of the first hotfix, and merge any code conflicts, if any.
In the end, you want a system with both hotfixes applied - that is the "next" version. So it makes sense that whatever hotfix is "second", it is applied on top of the "first" one. And creating a packaged release from the single hotfix release branch ensures that the version number is consistently incremented for the whole system.
Of course, above means that we must create a separate branch for each hotfix. Some version control systems, namely Git, make this very easy and part of the expected developer workflow. If you are using a version control system like TFS, then creating new branches for each hotfix is a bit more painful. In TFS, I suggest using named Shelvesets feature to emulate Git's process, and perform initial QA tests for a hotfix from a Shelveset-branch build. Then commit Shelveset into the hotfix branch to build the official hotfix package (and perform necessary merging).
What about the versioning of the interim hotfix builds ? The main hotfix release branch would have a standard versioning scheme applied (as discussed above), either incrementing a build number, or using a timestamp. Each new hotfix, applied on top of all previous hotfixes, gets an increased build number , and the software version keeps moving forward.
However, when building from the developer hotfix branch (or Shelveset in TFS), we also need to apply a version to distinguish it from other builds, and be able to deploy it into QA/test environment. We want to be able to test each hotfix in isolation, applied on top of an existing released version of the software system. This becomes problematic, if you have a single test environment .
You do not want to apply both hotfixes into one test environment, because there is no guarantee that they won't conflict or affect each other. If you are able to quickly spin up a test environment for a hotfix development branch, then you can truly parallelize team efforts. For a shared test environment, they have to be applied one at a time :
Force install latest release version (e. g. 1.5.168) to bring environment to a known state Install the hotfix version to be tested Perform the tests (preferably automated) For shared test environnments this is the bottleneck, since no other hotfixes can be tested at the same time (automation can help minimize the time spent in this step) Repeat 1-3, until tests are satisfactory.
What this means is that each hotfix has to have its build version number greater than the latest released version, the one it is being applied on top of. There are several ways to achieve that. If using a derived build number , this should just work out of the box. If incrementing or using external build numbers, then the easiest option is to simply force the build for hotfix development branch (or Shelveset) to use a number greater than latest released version (i. e. .168).
With Semantic Versioning, we can setup hotfix builds to use a "prerelease" tag that clearly marks it as a hotfix-test build. For example - 1.5.169-check14761 , where the trailing number could be a reference to the issue tracking system. This works especially well when using NuGet as the packaging mechanism.
Once tested, the changes can be merged into hotfix release branch, and an official build generated, with incremented build version number.
NOTE: Above process to resolve concurrent hotfixes is undoubtedly complicated. It is intended to solve a particular real-world scenario, but one that does not happen too often. If there are no concurrent fixes expected, you can simplify your life by applying fixes directly to the hotfix release branch.
Patching a large system.
If applying hotfixes to a large system, we don't want to upgrade the whole thing, which may involve a lot of different components - services, GUI applications, scheduled jobs, databases, etc. Instead, we want to apply the fix only to affected parts.
This is where splitting the system into multiple packages helps. Each corresponds to a logically contained piece of the system - for example, each service, application, database, etc is its own package. That means they can be patched independently by applying just that package .
Care must be taken about dependencies, if hotfix affects multiple packages at once. Although, in that case, ask yourself is it really a hotfix or a new minor version?
Patching for specific installation.
Some software shops may have developed the practice of patching the software for individual customers (for packaged software), in other words creating a "custom" version for just that installation, without including this fix in the rest of released software streams. This is one of the worst situations to be in, with regards to versioning, since it creates a large number of variations that have to be maintained separately.
Instead, release a general update , moving the overall software version forward for that release stream. Adopt a "feature" system , where parts of the software can be turned on & off based on configuration. If a specific fix is needed for a particular installation, then that code can be encapsulated behind a configuration switch which turns this section of the code on or off. That particular customer can turn it on , while the rest can have it off!
This is also a popular technique in web applications, of which only one installation exists (on the server), where various "features" can be enabled based on "configuration" for each user , or a set of users.
Patching the changes only.
There is often the temptation to simply patch in the changes to the live/production system by editing/replacing one file, or updating one table or stored procedure. The change is small, and it seems like the fastest way to solve the imminent issue, without changing anything else in the system.
While it seems like a smaller risk to make only the necessary updates directly, it makes it a whole lot harder to know the state of the system in the future. As more and more such "small" patches get applied, there is no longer any reliable way to link the running system back to the original source code, making further maintenance exponentially more complicated (and, ironically, increasing the risk).
Updating individual non-binary (e. g. config files) or altering database objects does not update any version number . That means it is difficult to tell which changes have been made to the system, leading to "maintenance hell" (a variation of the infamous "DLL Hell").
Rule of thumb: Any change to the system should change the version number.
NOTE : Windows Installer allows a so called "small update", where product version number does not have to change, used for small hotfix patches. I believe this creates too much confusion, and so I do not recommend it. Windows Installer does track each patch, through package code, so you always know which patches have been applied. But it means now having to track and remove patches on subsequent product updates, which complicates the process. It may work for Microsoft Windows and Microsoft Office, but I wouldn't recommend using it for any system.
الكلمات الأخيرة.
This turned out to be a much longer article than I originally anticipated when I sat down to write about versioning . I am hoping it proves useful for software engineers out there looking for some guidance on how to apply these concepts in their own projects.
Still this seems like only a partial treatment of the topic.
Everything I wrote above has been learned through the painful process of trial & error over the years. If just a few readers have an "aha!" moment while reading this, then I have achieved my goal!

Software versioning strategy


الحصول على فيا أب ستور قراءة هذه المشاركة في التطبيق لدينا!
A good strategy for implementing a versioning system.
I have been struggling with versioning software for a while now. I'm not talking about a naming convention, I'm talking about how to actually apply a version in a build system all the way through to a release.
I generally use major. minor. maintenance-[release type] i. e. 1.0.2-rc1.
The problem is managing the version number. I've tried many ways (sticking it in a build file, a properties file, a database, etc, etc) but I haven't found anything that really works well.
I'm wondering if anyone has any good ideas about this. Also, wondering how people handle releasing a version. i. e. If I release/deploy version 1.0.0-rc1 do bugs found in this release then get logged into 1.0.0 (the next/production release).
Microsoft uses <major>.<minor>.<patch>-<build number> (or a variation).
I like using <major>.<minor>.<buildnumber>
Where I'm working we use the Maven system: artifact[-major-minor-revision][-SNAPSHOT] which allows us to develop "in progress" versions that change at a moments notice (SNAPSHOT) and those which have been formally released. وفيما يلي بعض الأمثلة:
email-services-1.0.0-SNAPSHOT. jar email-web-2.3.11.war crm-2.5.0.ear.
If it has SNAPSHOT in it then it hasn't passed the full suite of tests or is just a developer experiment. If it doesn't have SNAPSHOT then it is a release candidate. We maintain a repository of release candidates and the most recent is sent for deployment once the testers are happy with it.
All of this can be managed with a few simple entries in a build file under Maven. See Maven2 tutorial.
This is probably a dead post now, but I'll add my two cents anyways. I'm of the opinion that build numbers should mean something to everyone who sees it. So I personally think that this is a good way to name versions:
major. minor. patch. revision - e. g. 1.1.4.2342.
Major/minor numbers are pretty self-explanatory. But from the perspective of the 3rd number, it still needs to mean something to the customer. I've released this new version to you, Mr. Customer, but it wasn't worth a new minor number since we just fixed some bugs. So we've incremented the patch number.
The 4th number usually means absolutely NOTHING to the customer, so you might as well make it useful to you and anyone else in your company that sees it. So for us, that number is the SVN revision number. It tells us exactly which revision was responsible for that version so that we can pull it out any any time to recreate it. Branching code obviously achieves this too, but not to 100% certainty.
Also, another advantage with an all-numeric version number is that it easily integrates into nearly every continuous build system.
Anyways, that's my two cents.
+1 on the Jira/Bamboo solution. The only additional information about the build I would include (for my purposes) is the Subversion Release, although the Tagging operation is 80% of what I want.
Manually maintaining the release/version information is a royal pain. Letting JIRA drive it is a great idea.
On the final question, about where bugs/defects get logged and releasing a version:
Defect/Issue is logged against the release where it appears. A defect in 1.0.0-rc1 gets logged against 1.0.0-rc1 JIRA has (or maybe we added) a 'Fix-For' field that would have the planned release, in this case 1.0.0 If the defect/issue is severe enough, it may be necessary to add another 'rc' release. The release is made when there are no outstanding critical defects/issues and the customer (or management) agrees that any remaining issues can be deferred.
The beauty of managing this through JIRA is that adding releases, generating change-logs, etc. is automated fairly well.
We also use <major>.<minor>.<buildnumber> and we manage this with CruiseControl/() on our build server. And use Wix and CruiseControl Config to manage the Major minor numbers - still increment those by hand - but the build number happens automatically when on the build server. You could set up a rule an increment the major/minor automatically too I believe - we just have like to do that manually so that it takes concious thinking by a dev when it is time to name a particular release level.
Major and Minor are set by us, manually incrementing them as we see fit.
BuildDateNumber is the number of months since the project start multiplied by 100, plus the day number of the current month.
DailyBuildNumber is incremented for every build after midnight each day, starting at zero.
مثلا 4th build of release 5.2 on 10 July, where the project started 1 Jan that year, would have version number.
This is all calculated for us by the Version task in Nant.
This keeps the version numbers unique and also allows us to quickly calculate when an installation was built.

Feature branching your way to greatness.
Or task branching your way there. Or release branching. You choose.
The Agile Coach.
Almost all version control systems today support branches–independent lines of work that stem from one central code base. Depending on your version control system, the main branch may be called master, mainline, default, or trunk. Developers can create their own branches from the main code line and work independently alongside it.
Why bother with branching?
Branching allows teams of developers to easily collaborate inside of one central code base. When a developer creates a branch, the version control system creates a copy of the code base at that point in time. Changes to the branch don't affect other developers on the team. This is a good thing, obviously, because features under development can create instability, which would be highly disruptive if all work was happening on the main code line. But branches need not live in solitary confinement. Developers can easily pull down changes from other developers to collaborate on features and ensure their private branch doesn’t diverge too far from the master.
ProTip : Branches aren't just good for feature work. Branches can insulate the team from important architectural changes like updating frameworks, common libraries, etc.
Three branching strategies for agile teams.
Branching models often differ between teams, and are the subject of much debate in the software community. One big theme is how much work should remain in a branch before getting merged back into master.
Release branching.
Release branching refers to the idea that a release is contained entirely within a branch. This means that late in the development cycle, the release manager will create a branch from the master (e. g., “1.1 development branch”). All changes for the 1.1 release need to be applied twice: once to the 1.1 branch and then to the master code line. Working with two branches is extra work for the team and it's easy to forget to merge to both branches. Release branches can be unwieldy and hard to manage as many people are working on the same branch. We’ve all felt the pain of having to merge many different changes on one single branch. If you must do a release branch, create the branch as close to the actual release as possible.
Warning: Release branching is an important part of supporting versioned software out in the market. A single product may have several release branches (e. g., 1.1, 1.2, 2.0) to support sustaining development. Keep in mind that changes in earlier versions (i. e., 1.1) may need to be merged to later release branches (i. e., 1.2, 2.0). Check out our webinar below to learn more about managing release branches with Git.
Feature branching.
Many agile teams looking for a more flexible branching model have moved from release branching to feature branching. A feature branch model keeps all of the changes for a particular feature inside of a branch. When the feature is fully tested and validated by automated tests, the branch is then merged into master.
Feature branches are often coupled with feature flags–"toggles" that enable or disable a feature within the product. That makes it easy to deploy code into master and control when the feature is activated, making it easy to initially deploy the code well before the feature is exposed to end-users.
ProTip: Another benefit of feature flags is that the code can remain within the build but inactive while it's in development. If something goes awry when the feature is enabled, a system admin can revert the feature flag and get back to a known good state rather than have to deploy a new build.
Task branching.
At Atlassian, we focus on a branch-per-task workflow. Every organization has a natural way to break down work in individual tasks inside of an issue tracker, like JIRA Software. Issues then becomes the team's central point of contact for that piece of work. Task branching, also known as issue branching, directly connects those issues with the source code. Each issue is implemented on its own branch with the issue key included in the branch name. It’s easy to see which code implements which issue: just look for the issue key in the branch name. With that level of transparency, it's easier to apply specific changes to master or any longer running legacy release branch.
Since agile centers around user stories, task branches pair well with agile development. Each user story (or bug fix) lives within its own branch, making it easy to see which issues are in progress and which are ready for release. For a deep-deep dive into task branching (sometimes called issue branching or branch-per-issue), grab some popcorn and check out the webinar recording below–one of our most popular ever.
Now meet branching's evil twin: the merge.
We’ve all endured the pain of trying to integrate multiple branches into one sensible solution. Traditionally, centralized version control systems like Subversion have made merging a very painful operation. But newer version control systems like Git and Mercurial take a different approach to tracking versions of files that live on different branches.
With Git, merging is trivial–freeing us to exploit the full power of branching workflows.
Branches tend to be short-lived, making them easier to merge and more flexible across the code base. Between the ability to frequently and automatically merge branches as part of continuous integration (CI), and the fact that short-lived branches simply contain fewer changes, "merge hell" becomes is a thing of the past for teams using Git and Mercurial.
That's what makes task branching so awesome!
Validate, validate, validate.
A version control system can only go so far in affecting the outcome of a merge. Automated testing and continuous integration are critical as well. Most CI servers can automatically put new branches under test, drastically reducing the number of "surprises" upon the final merge upstream and helping to keep the main code line stable.
Products discussed.
Sign up for more articles.
Recommended Reads.
Put it into practice.
Get serious about branching.
Manage Git repositories, set up permissions, and collaborate on code. Secure, fast, and enterprise-grade. Explore Bitbucket.
التالي.
Why code reviews matter.
Code review helps developers learn the code base, new technologies, and new techniques. But the kicker is that they actually save you time.
May we also recommend.
Awesome issues for Git branching workflows.
Learn about three rookie mistakes teams make when adopting a feature branching workflow, and how to correct them by using issues to track work in JIRA Software. تابع القراءة.
عن المؤلف.
Dan Radigan.
Senior Agile Evangelist, Atlassian.
Agile has had a huge impact on me both professionally and personally as I've learned the best experiences are agile, both in code and in life. You'll often find me at the intersection of technology, photography, and motorcycling. Find me on Twitter! @danradigan.

Comments

Popular posts from this blog

تداول العملات الأجنبية من خلال بنك قياسي

تداول العملات: كيف تحولت 100000 $ إلى 1M زائد في 30 يوما - جوبورغ مدقق. ريكي جاكوبسوهن من جوهانسبرغ: أزيز في تداول العملات العالمية. وكانت صفقات العملات المذهلة التي تستند إلى الأحداث الإخبارية الكبرى هي التحركات الفائزة لمدقق جوهانسبرغ الذي فاز بأول مسابقة تجارية عالمية في ستاندرد بانك ويبترادر. قام ريكي جاكوبسون، 25 عاما، بتحويل أموال إنفاق افتراضية قدرها 100 ألف دولار أمريكي إلى أكثر من 1،3 مليون دولار أمريكي في 30 يوما. وحصل على لقب أفضل مستثمر وجائزة نقدية بقيمة 625 دولارا أمريكيا. ودخل نحو 300 1 شخص في المسابقة بهدف تعريف جنوب افريقيا بالاستثمار الذاتي في الأسواق العالمية من خلال منصة التداول المحلية على شبكة الإنترنت. فمن السهل شراء وبيع الأسهم والأوراق المالية الأخرى في نيويورك ولندن وغيرها من الأسواق باستخدام بدل الاستثمار الأجنبي الخاص بك. أنت لا تحتاج سا إذن بنك الاحتياطي للاستثمار R1m الأولى الخاصة بك. من أجل استثمار R4m إضافية كل عام، سوف تحتاج إلى موافقة دائرة الإيرادات في جنوب أفريقيا. واستخدمت المنافسة الاستثمارية العملة الافتراضية، حيث قدم كل مشارك 000 100 دولار من دول...

استراتيجيات التداول على أساس الحجم

استراتيجيات التداول استنادا إلى المجلد، الجزء 2: تأكيد الاتجاهات. يمكن أن يساعد حجم التداول على تأكيد الاتجاه يجب أن يزداد حجم التداول خلال التحركات في اتجاه الاتجاه الصحيح يعتبر ور / أوسد مثالا حاليا لهذه المبادئ. بالنسبة لسلسلة المقالات هذه، نوصي بتنزيل مؤشر الحجم الحقيقي من فكسماابس. فهو حر تماما. وبمجرد تركيب، يمكننا إضافة حجم حقيقي على المخططات لدينا تماما مثل أي مؤشر آخر على سطح المكتب محطة التداول. هذا المؤشر لن تعمل على منصة التداول منصة الويب. في وقت سابق من هذا الأسبوع، نشرت الجزء الأول من & لدكو؛ استراتيجيات التداول استنادا إلى وحدة التخزين & رديقو؛ سلسلة تبين كيف يمكن أن حجم يمكن القيام بعمل عظيم في تأكيد الانفجارات. إضافة هذا الفلتر جنبا إلى جنب مع استراتيجية الاختراق يمكن أن تقلل من كمية الكاذب الكاذب المتداولة ويمكن أن تزيد الربحية الإجمالية. اليوم نستمر في النظر في حجم ولكن تحويل انتباهنا نحو اتجاهات التداول. تداول الاتجاه هو عنصر أساسي في حساب تداول العملات الأجنبية الخاص بي. وتحديد الاتجاه السائد الزوج يتجه وتبحث فقط عن الفرص التي تتداول في نفس الاتجاه. ولكن ف...

الخيار تداول المال وهمية

خطوة أخرى أيضا. يرجى إكمال الفحص الأمني ​​للوصول إلى سكامبروكر. لماذا يتعين علي إكمال اختبار كابتشا؟ إكمال اختبار كابتشا يثبت أنك إنسان وتمنحك إمكانية الوصول المؤقت إلى موقع الويب. ماذا يمكنني أن أفعل لمنع ذلك في المستقبل؟ إذا كنت على اتصال شخصي، كما هو الحال في المنزل، يمكنك تشغيل فحص مكافحة الفيروسات على جهازك للتأكد من أنه لم يصاب مع البرامج الضارة. إذا كنت في مكتب أو شبكة مشتركة، يمكنك أن تطلب من مسؤول الشبكة إجراء فحص عبر الشبكة تبحث عن الأجهزة التي تمت تهيئتها بشكل خاطئ أو المصابة. طريقة أخرى لمنع الحصول على هذه الصفحة في المستقبل هي استخدام بريفاسي باس. تحقق من إضافة المتصفح في فايرفوكس أد-أونس ستور. كلودفلار راي إد: 3d29dc4354b48ca0 & بول؛ إب الخاص بك: 78.109.24.111 & الثور؛ الأداء & أمب؛ الأمن من قبل كلودفلار. سوق الأسهم لعبة. تنافس، خالية من المخاطر مع 100،000 $ في النقد الافتراضي. تبدأ مع 100،000 $ في النقد الافتراضي ووضع مهارات التداول الخاصة بك على المحك! التنافس مع الآلاف من التجار إنفستوبيديا والتجارة في طريقك إلى الأعلى! تواصل مع أكثر من 700،000 في جميع أنحا...