إستراتيجية الإصدار الرشيق
الحصول على فيا أب ستور قراءة هذه المشاركة في التطبيق لدينا!
الإصدار الدلالي في رشيق.
دعنا نقول لدي 14 يوما تكرارات العدو حيث لدي عدة قصص عن الميزات الجديدة، بعض التحسينات وبعض الخلل لإصلاح. أنا أيضا نشر تلك التغييرات عندما تكون جاهزة، وأنا لا تنتظر نهاية السباق.
مشكلتي هي - كيفية تتبع الإصدار الدلالي من المنتجات المتقدمة والحفاظ عليها مثل هذا؟ إذا كان هناك سوف يكون الافراج عن كل 14 يوما سيكون من السهل، وسوف زيادة رقم الإصدار وملاحظة جميع التغييرات في التغيير. ولكن ماذا لو تم نشر التغييرات بشكل مستمر؟ هل ينبغي أن يكون هناك نسخة في كل مرة يتم نشر شيء؟ أو يجب أن انتظر حتى ينتهي سباق وبعد هذا، وجعل بعض "استئناف" وزيادة رقم الإصدار مرة واحدة فقط في التكرار بشكل مستقل على النشر الفعلي؟ ما هي أفضل الممارسات للإصدار الدلالي في رشيق؟
إديت: من أجل شرح احتياجاتي بشكل أفضل، أريد تغيير سجل أصحاب المصلحة في المقام الأول. أنا لا أعتقد أنها سوف تكون مهتمة في سجل جديد في التغيير بعد كل تغيير نشرها.
لإدارة الإصدار النموذجي، سوف تحتاج إلى إنشاء رقم بناء من نظام الإنشاء الخاص بك بحيث يتم إصدار دلز في كل مرة يتم نشرها. سيضمن هذا التحقق لاحقا من الإصدار الذي يتم نشره على خادم معين.
يجب ألا يتم تحديث إصدار "التسويق"، الذي يتم وضعه عادة في ملاحظات الإصدار أو نشره على موقعك، كل إصدار. وينبغي تجميع هذه الملاحظات الإصدار وتجميعها معا، من المرجح أن توقيت مع نهاية السباق الخاص بك.
إذا كان نظام النسخ الدلالي الكلاسيكي "MAJOR. MINOR. PATCH" منطقي، يعتمد على لمن نشر، وخصوصا متى وكيف في كثير من الأحيان كنت نشر للمستخدم النهائي. المخطط هو الأكثر فائدة إذا كنت تعمل مع الإصدار المستقر "4.5"، حيث تبدأ مع 4.5.0. تحتوي الإصدارات 4.5.1 و 4.5.2 وما إلى ذلك على إصلاحات الأخطاء فقط، بينما تعمل داخليا داخليا على الإصدار 4.6.
على سبيل المثال، إذا قمت بتوفير "فرع مستقر" للمستخدم النهائي الخاص بك، اعطه الإصدار 4.5.0 للنشر الأولي، و 4.5.1، 4.5.2 كلما قمت بتحرير التصحيح. في الداخلية الخاصة بك "رشيقة" التنمية ونشر منتصف العدو، هل يمكن أن يكون بالفعل الإصدار 4.6، مجرد استدعاء "نسخة بيتا". كلما قمت بنشره في منتصف العدو، إضافة عدد بناء ولدت تلقائيا مثل "4.6.beta بناء 123". عندما ينتهي العدو الخاص بك، تعيينه "4.6.0"، والتبديل رقم الإصدار للسباق المقبل داخليا إلى "4.7". بدءا من "0" هو مجرد اتفاقية، يمكنك أيضا استخدام "0.0" لوضع علامات إصدارات بيتا، والبدء مع ".1" للمستخدمين النهائيين الخاص بك. إمهو كلمة "بيتا" هو أكثر تعبيرا بكثير، تقول الجميع سباق "لم تكتمل بعد".
إذا قمت بتحرير سجل تغيير المستخدم النهائي الكامل مع كل إصدار بيتا متروك لكم، ولكن على الأقل في نهاية السباق يجب أن تكتمل سجل التغيير، وكلما قمت بتوفير خلل للمستخدم النهائي، يجب عليك أيضا تحديث وثائق التاريخ.
سوف تجد استراتيجية الافراج عن اثنين من فروع فصل، واحد "مستقر" فرع مع أرقام الإصدار الدلالي، و "فرع التنمية" ملحوظ مع أرقام بناء أو شيء مماثل، في الكثير من المنتجات مفتوحة المصدر مثل إنكسكيب، فايرفوكس أو 7 الرمز البريدي.
إذا، ومع ذلك، كنت لا تعمل مع فروع مستقرة والتنمية منفصلة، وإطلاق سراح نسخة جديدة لك المستخدم النهائي يوميا، يجب أيضا زيادة رقم الإصدار يوميا. في مثل هذه الحالة، أرقام الإصدار "4.5.1"، "4.5.2"،. ربما تعكس عمليات النشر الفردية، ولا تشير إلى الفرق بين إصلاحات الأخطاء والتغييرات الأخرى. يمكن أن يكون على ما يرام، انها ليست مجرد الكلاسيكية "الإصدار الدلالي" أي أكثر من ذلك. في هذا السيناريو، يمكنك أيضا نشر الإصدارات 4.5، 4.6، 4.7، 4.8، التي لا تعطي أي فرق حقيقي.
فيما يتعلق بسؤالك حول الإدخالات في سجل التغيير الخاص بك: إمهو عندما يكون هناك شيء مرئي للمستخدم النهائي، فإنه يستحق إدخال في التغيير، بمجرد نشر التغيير. على سبيل المثال، إذا كنت تستخدم ميزة تبديل وإجراء تغييرات على بعض ميزة نصف خبز التي لم يتم تفعيلها حتى الآن للمستخدم، التي لا تنتمي إلى التغيير. إذا كنت تفعل إعادة بيعها فقط، مع عدم وجود تغيير مرئي للمستخدم، التي لا تنتمي إلى التغيير. إذا قمت بإصلاح علة التي يمكن أن تؤثر على بعض المستخدمين، التي تنتمي بالتأكيد إلى التغيير - ويجب أن نذكر هناك في نفس الوقت عند نشر الخطأ. ولا يهم إذا كنت الإفراج يوميا أو شهريا أو سنويا.
وأود أن استخدام أرقام البناء. وعادة ما يتوافق رقم البناء مع أعلى إصدار من نظام التحكم في الإصدار. إذا كان عدد أيام البناء 1745 وقد تم فحص 5 تغييرات خلال يوم الثلاثاء، مساء يوم بناء عدد سيكون 1750.
ثم قم بعمل ملخص قصير لما تغير بين 1745 و 1750.
ثم في كل مرة تقوم بتحديث رقم الإصدار من النظام الخاص بك يمكنك إضافة ما يصل كل ملخصات قصيرة من يبني للحصول على التغييرات من رقم الإصدار الأخير إلى الجديد.
الأسلوب المفضل لدي والتي كنت تستخدم لسنوات قليلة على الأقل الآن هو عثرة الرقم بعد الانتهاء من كل قصة. وهذا يعني أن الإصدارات التي تم إصدارها في نهاية السباق لن تكون مستمرة، على سبيل المثال. بعد 1.2.3 قد تجد 1.5.2 بدلا من 1.4.0.
في التغيير يمكنك إما إدراج الإصدارات المتوسطة مع الأوصاف المقابلة أو مجرد مجموعة كل التغييرات في الإصدار "صدر" وتخطي الإصدارات بينهما.
في البداية، كنت أخشى المستخدمين سوف تجد "الثقوب" بين أرقام الإصدار إشكالية، ولكن بمجرد أن يعرفوا عن ذلك، فإنه ليس قضية في الممارسة العملية. ميزة كبيرة هي أن زيادة عدد بعد كل قصة يجعل العملية أقل عرضة للخطأ - لم يكن لديك للتحقق من العمل كله من 2 أسابيع لتقرر ما هو رقم الإصدار القادم سيكون - عند النظر في قصة واحدة، فمن الواضح . بالإضافة إلى ذلك، فإن "قفزات" في أرقام الإصدار بين كل إصدار تعطي تقديرا تقريبيا لكيفية العديد من التغييرات ذهب إلى الإصدار. في كل شيء، لقد وجدت هذا النظام للعمل بشكل جيد (وكان هذا مع العملاء الداخلي للشركة، ولكن إذا كنت تعمل بالفعل في دورة إطلاق رشيقة يجب أن تعمل للعملاء الخارجيين كذلك).
إستراتيجية الإصدار الرشيق
الحصول على فيا أب ستور قراءة هذه المشاركة في التطبيق لدينا!
ما هي إستراتيجية إصدار إصدارات التطبيقات؟ [مكرر]
هذا السؤال له إجابة هنا:
وأود أن تكون مهتمة للحصول على آراء المجتمع سو حول أفضل استراتيجية إصدار الإصدارات التطبيق.
كيف يمكنك تتبع رقم إصدار التطبيق؟ هل لديك تعريف رسمي لما يمثله كل رقم / حرف في هذا الإصدار؟
ماذا تعني الأرقام / السلاسل المختلفة في إصدار التطبيق لتطبيقك؟
هل تستخدم أي نظام تحديث تلقائي في تطبيقاتك (على سبيل المثال، شيء مثل سباركل) ومدى حسن تصرفك من أجلك؟
هل لديك إجراء تحديث منفصل للاختبار بيتا أو اختبار ما قبل النشر من التطبيق الخاص بك؟
تم وضع علامة على أنها مكررة من قبل غنات، ميكلت، كيليان فوث، 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 ++ أو جافا، يجب أن يتم تجميعها في ثنائي قبل أن تكون قادرة على تنفيذها. وهكذا يرتبط البناء عادة بعملية التجميع.
ولكن هذه ليست صورة كاملة. بعض اللغات أو الأطر، مثل بيثون أو أسب، لا تتطلب تجميعا صارما. ويمكن تفسيرها إما في حالة بايثون أو تجميعها على ذبابة في حالة أسب. ما الذي ينبغي القيام به لهذه الأنظمة؟ كيف يمكنك "بناء" تطبيق بايثون؟
هذا هو السبب في أنه من المفيد التفكير في بناء عملية التجميع، أو ببساطة التعبئة والتغليف. تماما مثل خط السلع الاستهلاكية، على سبيل المثال. والأحذية، يحصل تعبئتها قبل الشحن إلى المخازن، لذلك لا نظام البرمجيات، قبل أن يطلق سراحه.
مفهوم الحزمة هو ضروري لإصدار، لأن الحزمة هي مجموعة واحدة من القطع التي تتألف من نظام البرمجيات، أو جزء منه، وبالتالي يمكن تحديدها، وختم مع نسخة. مع نظام إدارة حزمة الحق (الذي ننظر في القسم التالي)، يمكن نشرها وتحديثها، وتحديد التبعيات على حزم أخرى.
البرمجيات اليوم هو أبدا ملف تنفيذي ثنائي واحد - هو عبارة عن مجموعة من الثنائيات المختلفة والمكتبات والوثائق وملفات التكوين والصور وغيرها من الموارد. حزمة ما يساعدنا على تجميعها معا، الإصدار والافراج عن العالم الخارجي.
ولا يلزم أن تكون الحزمة متطورة، على الرغم من أنها تساعد في بعض الحالات (مثل قواعد البيانات). يمكن أن يكون حتى ملف مضغوط بسيط، التي يمكن أن تحتوي على نسخة في اسم الملف، أو جزءا لا يتجزأ من ملف نصي. في الواقع، العديد من المشاريع مفتوحة المصدر تفعل ذلك - الإفراج هو زيب أو أرشيف. tar. gz.
الشيء المهم هو أن الحزمة هي وحدة واحدة، التي يتم تحريرها وتحديثها في نفس الوقت، مما يؤدي إلى الاتساق. من الشائع وجود عدة حزم، على سبيل المثال، تمثل مكونات "العميل" و "الخادم"، أو أي تجميع منطقي آخر ينطبق على نظام البرامج. ويمكن بعد ذلك يتم تحديث كل حزمة من تلقاء نفسها.
دعونا نلقي نظرة على بعض طرق التعبئة والتغليف المشتركة، ونهج الإصدار، والتطبيق الذي هي الأنسب ل.
مثبت الويندوز.
أفضل مناسبة: تطبيقات ويندوز غوي كاملة أو خدمات ويندوز أو برامج تشغيل.
أقدم، وطويلة الوقت الطريقة الوحيدة الموصى بها، لتثبيت التطبيقات على منصة ويندوز. أنه يحتوي على دعم الإصدار المدمج في ومتطورة (البعض يقول "معقدة") مجموعة من القواعد لتحديد متى لتحديث المكونات. في حين أن حزمة ويندوز إنزتالر (.msi) هو ملف واحد، في جوهره، هو عبارة عن مجموعة من المكونات المنطقية الصغيرة (وصولا إلى ملفات واحدة) التي يمكن تحديثها بشكل مستقل.
سيقوم ويندوز إنزتالر بالتحقق من كل ملف فردي يتم تثبيته، سواء كان لديه إصدار وما إذا كان الإصدار أكبر من ملف بنفس الاسم المثبت مسبقا. وهذا يعني أنه من المهم إصدار ليس فقط حزمة المثبت، ولكن كل ملف الواردة فيه. ولكن هذا يعني أيضا أنه من الصعب بشكل لا يصدق للقيام تخفيضات (أي التراجع) مع ويندوز إنزتالر.
هو الأنسب لتطبيقات ويندوز التقليدية (واجهة المستخدم الرسومية، والخدمات، والسائقين) التي يتم إصدارها للجمهور. ومع ذلك، فإنه ليس أفضل خيار للداخلية & أمب؛ والتطبيقات الموزعة، وأي نوع من تطبيقات الويب، أو أنظمة قواعد البيانات.
كما كان يستخدم لنشر المكتبات القابلة للتوزيع (دلز الأصلية) وكائنات كوم، ولكن مع التركيز اليوم على، فإنه ليس هو الآلية الصحيحة لتوزيع المكتبات.
نشر الويب.
الأفضل: تطبيقات الويب (إيس، أسب)
تم تصميم تقنية نشر الويب خصيصا لنشر التطبيقات ومزامنتها على خوادم ويب ميكروسوفت إيس. يستخدم النسخ المتماثل إيس ويب فارم ويب نشر الأوامر والحزم وراء الكواليس لمزامنة المواقع عبر مجموعة من الملقمات. يحتوي إيس ماناجر على إضافة (تمكين عن طريق تثبيت ويب ديبلوي) إلى "استيراد التطبيق"، والتي يمكن تثبيت أو تحديث تطبيق ويب باستخدام حزمة نشر ويب زيب.
أكبر عيب هو أنه لا يمكن إلا أن تستخدم لتطبيقات الويب على منصة مايكروسوفت إيس، وآلية محدودة لتخصيص التثبيت. في حين أنه يمكن أن تكون مناسبة لتطبيقات الويب البسيطة، فإنه يمكن أن تصبح محبطة بسرعة لأي شيء أكثر تطورا، أي المتغيرات والمنطق الشرطي وقواعد البيانات، وما إلى ذلك.
وبالإضافة إلى ذلك، فإنه لا يوجد لديه الدعم المتأصل للإصدار.
مدراء الحزم.
أفضل مناسبة: المكتبات المشتركة، التبعيات، سطر الأوامر المرافق.
مدراء حزمة كبيرة لإطلاق وإصدار المكونات المشتركة، وتتبع التبعيات بينهما. على سبيل المثال، إذا كان لديك مكتبة مشتركة تريد أن يستخدمها الآخرون، فإن مدير الحزم يسمح لك بنشر إصدارات متعددة جنبا إلى جنب، وبالنسبة لمستهلكي المكتبة للإشارة إلى الإصدار الذي يعتمدون عليه. يمكن لمديري الحزمة حل كافة التبعيات بين الحزمة، واسترداد الإصدارات التي من المتوقع فقط. في الواقع، مديري الحزمة حل مشكلة "الجحيم دل".
أفضل استخدامها أثناء التنمية، لحل التبعيات المكتبة. ومع ذلك، بعض إدارة الحزم، مثل شوكولاتي ويندوز أو أبت-جيت ل أوبونتو، موجهة نحو تثبيت البرنامج الكامل.
الأهم من ذلك، تم تصميم مديري حزمة حول مفهوم الإصدار. لذلك فهي آلية مثالية لتوزيع مكتبات البرامج المصورة.
لدينا لدينا نوجيت. وقد تم نشر الكثير من المكتبات المفتوحة المصدر في مستودعها على الإنترنت، وهي الآن المعيار الفعلي لتوزيع مكونات الطرف الثالث. ومن المشجع أن كل فريق يضع مستودع نوجيت الخاصة بهم لتبادل ونشر المكتبات وضعت داخليا بطريقة الإصدار.
نوجيت يمكن أن تستخدم حتى لاطلاق سراح أنظمة البرمجيات كاملة - انظر القسم التالي.
بيئات التنمية الأخرى لها الخاصة - نبم ل Node. js، نقطة ل بايثون، الأحجار الكريمة ل روبي، أبت-الحصول على لينكس. وقد ثبت مدراء حزمة لتكون مفيدة للغاية، وانفجرت في شعبيتها.
نشر الأخطبوط.
أفضل تناسب: إنترنالي ديفيلوبيد & أمب؛ البرامج التي تم نشرها.
يستخدم الأخطبوط نوجيت كما التعبئة والتغليف والإصدار قذيفة. وهو مشابه لمثبت، مدفوعة فقط بويرشيل، وهذا يعني المرونة لانهائية في كيفية البرنامج هو أن يتم نشرها. لدى بويرشيل بالفعل دعما كبيرا لتكوين خدمات ويندوز، تطبيقات ويب إيس، المهام المجدولة، سكل سيرفر، وأكثر من ذلك.
أما بالنسبة للبرامجيات الموزعة داخليا والموزعة (أي شركة تعمل في مجال حلول البرمجيات المحلية)، فهي مركبة مثالية لإدارة الإصدار. يتم إصدار الحزم ودفعها إلى تغذية نوجيت المشتركة (مثل مشاركة الشبكة)، حيث يمكن نشر الأخطبوط ونشر كل حزمة في البيئة المناسبة.
نوجيت هنا يلعب دور حزمة التطبيق / حاوية، مع نسخة ختمها على ذلك. حزمة يمكن أن يبنى مرة واحدة، ومن ثم نشر عدة مرات حسب الحاجة إلى أي بيئة.
الإصدار & أمب؛ قواعد بيانات التعبئة والتغليف.
إصدار قاعدة البيانات هو واحد من أكبر التحديات في مشاريع البرمجيات. تقريبا كل فريق واجهته، إما تجاهل تماما أو كان شيئا غير كاف في المكان. ومن المؤكد أنه يمثل تحديا - نظم قاعدة البيانات مزيج تعريف مخطط مع البيانات الحية الفعلية، وليس هناك واحد "ملف" التي يمكن أن تكون نسخة بشكل فعال.
علينا أن نعترف قاعدة البيانات كجزء لا يتجزأ من نظام البرمجيات. واحد الذي ينفذ على منصة طرف ثالث الملكية (سكل سيرفر، أوراكل، بوستغريزل، الخ)، ولكن المصدر الذي هو جزء من تعريف البرنامج. يمكن مقارنته بالنظم النصية، مثل Node. js أو بيثون، إلا أن النصوص مكتوبة بلغة لهجة سكل.
هناك أساسا ثلاثة نهج شعبية لإصدار قواعد البيانات، التي تدعم النشر الآلي (أنا لا تنظر النهج اليدوية، لأنها عرضة للخطأ، وليس لها علاقة مع الإصدار الحقيقي!).
دب - الترحيل.
"هجرات" هو مفهوم حيث يحتفظ المطورون مجموعة من الملفات النصي سكل المنظمة، مرقمة بالتتابع، حيث ينطبق كل سيناريو تعديلات على دب الهدف لجلبه إلى الحالة المتوقعة. كلما كان هناك حاجة إلى تغيير لقاعدة بيانات التطبيق، المطور بإنشاء برنامج نصي ترحيل جديد ينطبق التغييرات دلتا.
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.
Final words.
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!
Agile versioning strategy
الحصول على فيا أب ستور قراءة هذه المشاركة في التطبيق لدينا!
How do you do version numbering in an agile project? [closed]
Currently, we're using the following version numbering scheme for our C# winforms project:
"Major Release"."Minor Release"."Iteration Number"."Build Number within that Iteration"
We wanted to be able to identify the iteration number and the build number within that iteration just by looking at the version number.
In the past, we had done something like:"Major Release"."Minor Release"."Sequential Build Number from 1.0". For example, "4.0.648" would mean there were 648 builds since 1.0 - but this information is fairly useless and anecdotal, which is why we changed to reflect iterations and builds within iterations.
So considering this new agile version numbering, we now have the problem where a different product group would like to make changes in their iteration for our project. In this instance, the version number would not make sense, because their iteration and build numbers do not correspond. For example, my project's last build was 1.0.5.1 indicating the 1st build of iteration 5. Now this other project that in it's 3rd iteration would like to make changes to my project and rebuild.
How should I cope with this situation? How do you do version numbering in your agile project?
closed as primarily opinion-based by EJoshuaS, robinCTS, MikeT, Luke Peterson, Steven Scott Nov 14 '17 at 20:10.
Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.
I track the agile projects' iteration, not the software projects' iteration. If a late starter side project joins after another project it will therefore init with the current agile project iteration, and there will be no misalignment.
It should not be possible for a technical project outside of the agile project's domain to interact with a project within the domain. That would be a PM failure of the process and should be eliminated in all cases where a shared code base is in use with branching, to be patched into the trunk as a cleanup step after the project completion.
Personally, I think that the release versioning I've liked the best is to do away with the whole major. minor stuff altogether. I think that this is only really feasible for internal applications, but for that, it makes life a lot easier.
Typically, if you're developing internally facing applications, I've noticed that the business never actually cares about what major/minor version they are using. Instead, they tend to want to know a) when is the next release and b) what's going to be in or out - and that's about it. Trying to keep the fact that you're working on FOO-4.34.0.1-a and BAR-3.19.4.1 when nobody cares only serves to complicate communication.
At a prior group, we didn't really have major releases other than a project kickoff. Every release was as 'major' as the prior one.
As a result, I think that they did the sensible thing and instead communicated to the business as PROJECT_RELEASENUM . The release number incremented by '1' everytime we did a release, with patches as PROJECT_RELEASENUM_PATCHNUM , which also incremented by '1'.
It works well with the notion that development is done as a continual series of sprints until the business has all of the functionality that they need (which in practice never happens - there's always something more that they want). Business owners understood it, developers could communicate it, and it lent itself naturally to the continual development model we had.
I prefer Major. Minor. Build. Revision where Build - the number of public releases, Revision - a revision from source version system.
I prefer to separate the build and release process from the team development process, so I would hardly add the the iteration, sprint or similar to the version. Your case is a fine example on how having both things mixed is not easy to manage. What if you change methodology in the middle of the project (whatever the reason may be)?
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.
Coming up next.
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. Keep reading.
عن المؤلف.
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.
الحصول على فيا أب ستور قراءة هذه المشاركة في التطبيق لدينا!
ما هي إستراتيجية إصدار إصدارات التطبيقات؟ [مكرر]
هذا السؤال له إجابة هنا:
وأود أن تكون مهتمة للحصول على آراء المجتمع سو حول أفضل استراتيجية إصدار الإصدارات التطبيق.
كيف يمكنك تتبع رقم إصدار التطبيق؟ هل لديك تعريف رسمي لما يمثله كل رقم / حرف في هذا الإصدار؟
ماذا تعني الأرقام / السلاسل المختلفة في إصدار التطبيق لتطبيقك؟
هل تستخدم أي نظام تحديث تلقائي في تطبيقاتك (على سبيل المثال، شيء مثل سباركل) ومدى حسن تصرفك من أجلك؟
هل لديك إجراء تحديث منفصل للاختبار بيتا أو اختبار ما قبل النشر من التطبيق الخاص بك؟
تم وضع علامة على أنها مكررة من قبل غنات، ميكلت، كيليان فوث، 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 ++ أو جافا، يجب أن يتم تجميعها في ثنائي قبل أن تكون قادرة على تنفيذها. وهكذا يرتبط البناء عادة بعملية التجميع.
ولكن هذه ليست صورة كاملة. بعض اللغات أو الأطر، مثل بيثون أو أسب، لا تتطلب تجميعا صارما. ويمكن تفسيرها إما في حالة بايثون أو تجميعها على ذبابة في حالة أسب. ما الذي ينبغي القيام به لهذه الأنظمة؟ كيف يمكنك "بناء" تطبيق بايثون؟
هذا هو السبب في أنه من المفيد التفكير في بناء عملية التجميع، أو ببساطة التعبئة والتغليف. تماما مثل خط السلع الاستهلاكية، على سبيل المثال. والأحذية، يحصل تعبئتها قبل الشحن إلى المخازن، لذلك لا نظام البرمجيات، قبل أن يطلق سراحه.
مفهوم الحزمة هو ضروري لإصدار، لأن الحزمة هي مجموعة واحدة من القطع التي تتألف من نظام البرمجيات، أو جزء منه، وبالتالي يمكن تحديدها، وختم مع نسخة. مع نظام إدارة حزمة الحق (الذي ننظر في القسم التالي)، يمكن نشرها وتحديثها، وتحديد التبعيات على حزم أخرى.
البرمجيات اليوم هو أبدا ملف تنفيذي ثنائي واحد - هو عبارة عن مجموعة من الثنائيات المختلفة والمكتبات والوثائق وملفات التكوين والصور وغيرها من الموارد. حزمة ما يساعدنا على تجميعها معا، الإصدار والافراج عن العالم الخارجي.
ولا يلزم أن تكون الحزمة متطورة، على الرغم من أنها تساعد في بعض الحالات (مثل قواعد البيانات). يمكن أن يكون حتى ملف مضغوط بسيط، التي يمكن أن تحتوي على نسخة في اسم الملف، أو جزءا لا يتجزأ من ملف نصي. في الواقع، العديد من المشاريع مفتوحة المصدر تفعل ذلك - الإفراج هو زيب أو أرشيف. tar. gz.
الشيء المهم هو أن الحزمة هي وحدة واحدة، التي يتم تحريرها وتحديثها في نفس الوقت، مما يؤدي إلى الاتساق. من الشائع وجود عدة حزم، على سبيل المثال، تمثل مكونات "العميل" و "الخادم"، أو أي تجميع منطقي آخر ينطبق على نظام البرامج. ويمكن بعد ذلك يتم تحديث كل حزمة من تلقاء نفسها.
دعونا نلقي نظرة على بعض طرق التعبئة والتغليف المشتركة، ونهج الإصدار، والتطبيق الذي هي الأنسب ل.
مثبت الويندوز.
أفضل مناسبة: تطبيقات ويندوز غوي كاملة أو خدمات ويندوز أو برامج تشغيل.
أقدم، وطويلة الوقت الطريقة الوحيدة الموصى بها، لتثبيت التطبيقات على منصة ويندوز. أنه يحتوي على دعم الإصدار المدمج في ومتطورة (البعض يقول "معقدة") مجموعة من القواعد لتحديد متى لتحديث المكونات. في حين أن حزمة ويندوز إنزتالر (.msi) هو ملف واحد، في جوهره، هو عبارة عن مجموعة من المكونات المنطقية الصغيرة (وصولا إلى ملفات واحدة) التي يمكن تحديثها بشكل مستقل.
سيقوم ويندوز إنزتالر بالتحقق من كل ملف فردي يتم تثبيته، سواء كان لديه إصدار وما إذا كان الإصدار أكبر من ملف بنفس الاسم المثبت مسبقا. وهذا يعني أنه من المهم إصدار ليس فقط حزمة المثبت، ولكن كل ملف الواردة فيه. ولكن هذا يعني أيضا أنه من الصعب بشكل لا يصدق للقيام تخفيضات (أي التراجع) مع ويندوز إنزتالر.
هو الأنسب لتطبيقات ويندوز التقليدية (واجهة المستخدم الرسومية، والخدمات، والسائقين) التي يتم إصدارها للجمهور. ومع ذلك، فإنه ليس أفضل خيار للداخلية & أمب؛ والتطبيقات الموزعة، وأي نوع من تطبيقات الويب، أو أنظمة قواعد البيانات.
كما كان يستخدم لنشر المكتبات القابلة للتوزيع (دلز الأصلية) وكائنات كوم، ولكن مع التركيز اليوم على، فإنه ليس هو الآلية الصحيحة لتوزيع المكتبات.
نشر الويب.
الأفضل: تطبيقات الويب (إيس، أسب)
تم تصميم تقنية نشر الويب خصيصا لنشر التطبيقات ومزامنتها على خوادم ويب ميكروسوفت إيس. يستخدم النسخ المتماثل إيس ويب فارم ويب نشر الأوامر والحزم وراء الكواليس لمزامنة المواقع عبر مجموعة من الملقمات. يحتوي إيس ماناجر على إضافة (تمكين عن طريق تثبيت ويب ديبلوي) إلى "استيراد التطبيق"، والتي يمكن تثبيت أو تحديث تطبيق ويب باستخدام حزمة نشر ويب زيب.
أكبر عيب هو أنه لا يمكن إلا أن تستخدم لتطبيقات الويب على منصة مايكروسوفت إيس، وآلية محدودة لتخصيص التثبيت. في حين أنه يمكن أن تكون مناسبة لتطبيقات الويب البسيطة، فإنه يمكن أن تصبح محبطة بسرعة لأي شيء أكثر تطورا، أي المتغيرات والمنطق الشرطي وقواعد البيانات، وما إلى ذلك.
وبالإضافة إلى ذلك، فإنه لا يوجد لديه الدعم المتأصل للإصدار.
مدراء الحزم.
أفضل مناسبة: المكتبات المشتركة، التبعيات، سطر الأوامر المرافق.
مدراء حزمة كبيرة لإطلاق وإصدار المكونات المشتركة، وتتبع التبعيات بينهما. على سبيل المثال، إذا كان لديك مكتبة مشتركة تريد أن يستخدمها الآخرون، فإن مدير الحزم يسمح لك بنشر إصدارات متعددة جنبا إلى جنب، وبالنسبة لمستهلكي المكتبة للإشارة إلى الإصدار الذي يعتمدون عليه. يمكن لمديري الحزمة حل كافة التبعيات بين الحزمة، واسترداد الإصدارات التي من المتوقع فقط. في الواقع، مديري الحزمة حل مشكلة "الجحيم دل".
أفضل استخدامها أثناء التنمية، لحل التبعيات المكتبة. ومع ذلك، بعض إدارة الحزم، مثل شوكولاتي ويندوز أو أبت-جيت ل أوبونتو، موجهة نحو تثبيت البرنامج الكامل.
الأهم من ذلك، تم تصميم مديري حزمة حول مفهوم الإصدار. لذلك فهي آلية مثالية لتوزيع مكتبات البرامج المصورة.
لدينا لدينا نوجيت. وقد تم نشر الكثير من المكتبات المفتوحة المصدر في مستودعها على الإنترنت، وهي الآن المعيار الفعلي لتوزيع مكونات الطرف الثالث. ومن المشجع أن كل فريق يضع مستودع نوجيت الخاصة بهم لتبادل ونشر المكتبات وضعت داخليا بطريقة الإصدار.
نوجيت يمكن أن تستخدم حتى لاطلاق سراح أنظمة البرمجيات كاملة - انظر القسم التالي.
بيئات التنمية الأخرى لها الخاصة - نبم ل Node. js، نقطة ل بايثون، الأحجار الكريمة ل روبي، أبت-الحصول على لينكس. وقد ثبت مدراء حزمة لتكون مفيدة للغاية، وانفجرت في شعبيتها.
نشر الأخطبوط.
أفضل تناسب: إنترنالي ديفيلوبيد & أمب؛ البرامج التي تم نشرها.
يستخدم الأخطبوط نوجيت كما التعبئة والتغليف والإصدار قذيفة. وهو مشابه لمثبت، مدفوعة فقط بويرشيل، وهذا يعني المرونة لانهائية في كيفية البرنامج هو أن يتم نشرها. لدى بويرشيل بالفعل دعما كبيرا لتكوين خدمات ويندوز، تطبيقات ويب إيس، المهام المجدولة، سكل سيرفر، وأكثر من ذلك.
أما بالنسبة للبرامجيات الموزعة داخليا والموزعة (أي شركة تعمل في مجال حلول البرمجيات المحلية)، فهي مركبة مثالية لإدارة الإصدار. يتم إصدار الحزم ودفعها إلى تغذية نوجيت المشتركة (مثل مشاركة الشبكة)، حيث يمكن نشر الأخطبوط ونشر كل حزمة في البيئة المناسبة.
نوجيت هنا يلعب دور حزمة التطبيق / حاوية، مع نسخة ختمها على ذلك. حزمة يمكن أن يبنى مرة واحدة، ومن ثم نشر عدة مرات حسب الحاجة إلى أي بيئة.
الإصدار & أمب؛ قواعد بيانات التعبئة والتغليف.
إصدار قاعدة البيانات هو واحد من أكبر التحديات في مشاريع البرمجيات. تقريبا كل فريق واجهته، إما تجاهل تماما أو كان شيئا غير كاف في المكان. ومن المؤكد أنه يمثل تحديا - نظم قاعدة البيانات مزيج تعريف مخطط مع البيانات الحية الفعلية، وليس هناك واحد "ملف" التي يمكن أن تكون نسخة بشكل فعال.
علينا أن نعترف قاعدة البيانات كجزء لا يتجزأ من نظام البرمجيات. واحد الذي ينفذ على منصة طرف ثالث الملكية (سكل سيرفر، أوراكل، بوستغريزل، الخ)، ولكن المصدر الذي هو جزء من تعريف البرنامج. يمكن مقارنته بالنظم النصية، مثل Node. js أو بيثون، إلا أن النصوص مكتوبة بلغة لهجة سكل.
هناك أساسا ثلاثة نهج شعبية لإصدار قواعد البيانات، التي تدعم النشر الآلي (أنا لا تنظر النهج اليدوية، لأنها عرضة للخطأ، وليس لها علاقة مع الإصدار الحقيقي!).
دب - الترحيل.
"هجرات" هو مفهوم حيث يحتفظ المطورون مجموعة من الملفات النصي سكل المنظمة، مرقمة بالتتابع، حيث ينطبق كل سيناريو تعديلات على دب الهدف لجلبه إلى الحالة المتوقعة. كلما كان هناك حاجة إلى تغيير لقاعدة بيانات التطبيق، المطور بإنشاء برنامج نصي ترحيل جديد ينطبق التغييرات دلتا.
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.
Final words.
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!
Agile versioning strategy
الحصول على فيا أب ستور قراءة هذه المشاركة في التطبيق لدينا!
How do you do version numbering in an agile project? [closed]
Currently, we're using the following version numbering scheme for our C# winforms project:
"Major Release"."Minor Release"."Iteration Number"."Build Number within that Iteration"
We wanted to be able to identify the iteration number and the build number within that iteration just by looking at the version number.
In the past, we had done something like:"Major Release"."Minor Release"."Sequential Build Number from 1.0". For example, "4.0.648" would mean there were 648 builds since 1.0 - but this information is fairly useless and anecdotal, which is why we changed to reflect iterations and builds within iterations.
So considering this new agile version numbering, we now have the problem where a different product group would like to make changes in their iteration for our project. In this instance, the version number would not make sense, because their iteration and build numbers do not correspond. For example, my project's last build was 1.0.5.1 indicating the 1st build of iteration 5. Now this other project that in it's 3rd iteration would like to make changes to my project and rebuild.
How should I cope with this situation? How do you do version numbering in your agile project?
closed as primarily opinion-based by EJoshuaS, robinCTS, MikeT, Luke Peterson, Steven Scott Nov 14 '17 at 20:10.
Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.
I track the agile projects' iteration, not the software projects' iteration. If a late starter side project joins after another project it will therefore init with the current agile project iteration, and there will be no misalignment.
It should not be possible for a technical project outside of the agile project's domain to interact with a project within the domain. That would be a PM failure of the process and should be eliminated in all cases where a shared code base is in use with branching, to be patched into the trunk as a cleanup step after the project completion.
Personally, I think that the release versioning I've liked the best is to do away with the whole major. minor stuff altogether. I think that this is only really feasible for internal applications, but for that, it makes life a lot easier.
Typically, if you're developing internally facing applications, I've noticed that the business never actually cares about what major/minor version they are using. Instead, they tend to want to know a) when is the next release and b) what's going to be in or out - and that's about it. Trying to keep the fact that you're working on FOO-4.34.0.1-a and BAR-3.19.4.1 when nobody cares only serves to complicate communication.
At a prior group, we didn't really have major releases other than a project kickoff. Every release was as 'major' as the prior one.
As a result, I think that they did the sensible thing and instead communicated to the business as PROJECT_RELEASENUM . The release number incremented by '1' everytime we did a release, with patches as PROJECT_RELEASENUM_PATCHNUM , which also incremented by '1'.
It works well with the notion that development is done as a continual series of sprints until the business has all of the functionality that they need (which in practice never happens - there's always something more that they want). Business owners understood it, developers could communicate it, and it lent itself naturally to the continual development model we had.
I prefer Major. Minor. Build. Revision where Build - the number of public releases, Revision - a revision from source version system.
I prefer to separate the build and release process from the team development process, so I would hardly add the the iteration, sprint or similar to the version. Your case is a fine example on how having both things mixed is not easy to manage. What if you change methodology in the middle of the project (whatever the reason may be)?
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.
Coming up next.
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. Keep reading.
عن المؤلف.
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.
No comments:
Post a Comment