الفرق الحقيقي بين التكامل المستمر والنشر المستمر

هناك الكثير من المحتوى الذي يصف التكامل المستمر والتسليم المستمر والنشر المستمر. ولكن ما هي الأغراض التي تخدمها هذه العمليات في المقام الأول؟

من الأهمية بمكان فهم المشكلات التي يتم حلها CI و CD لاستخدامها بشكل صحيح. سيسمح ذلك لفريقك بتحسين عمليتك وتجنب بذل الجهد في مطاردة المقاييس الفاخرة التي لا تحقق أي قيمة لعمليتك.

التكامل المستمر هو مشكلة الفريق

إذا كنت تعمل في فريق ، فمن المحتمل أن يكون هناك العديد من المطورين الذين يعملون في نفس المستودع. يوجد فرع رئيسي في المستودع يحمل أحدث إصدار من الكود. يعمل المطورون على أشياء مختلفة في فروع مختلفة. بمجرد أن ينتهي شخص ما من التغيير ، سيدفعه أو يدمجه في الفرع الرئيسي. في النهاية ، سيسحب الفريق بأكمله هذا التغيير.

السيناريو الذي نريد تجنبه هو أن يؤدي الالتزام الخاطئ إلى الفرع الرئيسي. خطأ يعني أن الكود لا يتم تجميعه أو أن التطبيق لن يبدأ أو أنه غير قابل للاستخدام. لماذا ا؟ ليس بسبب تعطل التطبيق أو لأن جميع الاختبارات يجب أن تكون خضراء دائمًا. هذه ليست مشكلة - يمكنك أن تقرر عدم نشر هذا الإصدار وانتظار الإصلاح.

المشكلة هي أن فريقك بأكمله عالق. سيقضي جميع المطورين الذين سحبوا الالتزام الخاطئ 5 دقائق في التساؤل عن سبب عدم نجاحه. سيحاول العديد على الأرجح العثور على الالتزام الخاطئ. سيحاول البعض إصلاح المشكلة بأنفسهم بالتوازي مع مؤلف الكود الخاطئ.

هذا مضيعة للوقت لفريقك. أسوأ جزء هو أن الحوادث المتكررة تغذي عدم الثقة في الفرع الرئيسي وتشجع المطورين على العمل بشكل منفصل.

يتمحور التكامل المستمر حول منع الفرع الرئيسي من الانهيار حتى لا يتعثر فريقك. هذا هو. ومن لا حول وجود جميع الاختبارات الخاصة بك الخضراء في كل وقت وفرع للنشر الرئيسي للإنتاج في كل يرتكبها.

عملية التكامل المستمر مستقلة عن أي أداة. يمكنك التحقق يدويًا من أن دمج الفرع والفرع الرئيسي يعمل محليًا ، وبعد ذلك فقط دفع الدمج فعليًا إلى المستودع. لكن هذا سيكون غير فعال للغاية. لهذا السبب يتم تنفيذ التكامل المستمر باستخدام الفحوصات الآلية.

تضمن الفحوصات ، كحد أدنى:

  • يجب أن يبني التطبيق ويبدأ
  • يجب أن تعمل معظم الميزات الهامة في جميع الأوقات (تسجيل المستخدم / رحلة تسجيل الدخول وميزات العمل الرئيسية)
  • يجب أن تكون الطبقات الشائعة للتطبيق التي يعتمد عليها جميع المطورين مستقرة. هذا يعني اختبارات الوحدة على تلك الأجزاء.

من الناحية العملية ، هذا يعني أنك بحاجة إلى سحب أي إطار عمل لاختبار الوحدة يناسبك وتأمين الطبقات المشتركة للتطبيق. في بعض الأحيان لا يكون هناك الكثير من التعليمات البرمجية ويمكن القيام به بسرعة إلى حد ما. تحتاج أيضًا إلى إضافة "اختبار الدخان" للتحقق من أن الكود يتم تجميعه وأن التطبيق يبدأ. هذا مهم بشكل خاص في التقنيات التي تحتوي على حقن تبعية مجنونة مثل Java Spring أو .NET core. في المشاريع الكبيرة ، من السهل جدًا إساءة استخدام تبعياتك ، مما يجعل التحقق من بدء تشغيل التطبيق دائمًا أمرًا لا بد منه.

إذا كان لديك مئات أو آلاف الاختبارات ، فلن تحتاج إلى تشغيلها جميعًا لكل عملية دمج. سيستغرق الأمر الكثير من الوقت وربما تتحقق معظم الاختبارات من ميزات "مانع غير الفريق".

سنرى في الأقسام التالية كيف ستستفيد عملية التسليم المستمر من هذه الاختبارات العديدة.

لا يتعلق الأمر بالأدوات

الأدوات والفحوصات الآلية كلها جيدة. ولكن إذا قام مطوروك بدمج الفروع العملاقة التي يعملون عليها لأسابيع فقط ، فلن يساعدوك. سيقضي الفريق وقتًا طويلاً في دمج الفروع وإصلاح حالات عدم توافق الكود التي ستظهر في النهاية. إنه مضيعة للوقت بقدر ما يتم حظره من خلال التزام خاطئ.

التكامل المستمر لا يتعلق بالأدوات. يتعلق الأمر بالعمل في أجزاء صغيرة ودمج الكود الجديد في الفرع الرئيسي والسحب بشكل متكرر.

في كثير من الأحيان يعني على الأقل يوميا. قسّم المهمة التي تعمل عليها إلى مهام أصغر. ادمج الكود الخاص بك كثيرًا واسحب كثيرًا. بهذه الطريقة ، لا أحد يعمل منفصلاً لأكثر من يوم أو يومين ، والمشكلات ليس لديها الوقت لتصبح كرات ثلجية.

لا تحتاج المهمة الكبيرة إلى أن تكون كلها في فرع واحد. لا ينبغي أبدا. تسمى تقنيات دمج العمل الجاري في الفرع الرئيسي "التفريع بواسطة التجريد" و "تبديل الميزات". انظر منشور المدونة كيفية البدء في التكامل المستمر لمزيد من التفاصيل.

النقاط الرئيسية لبناء CI جيد

انها بسيطة جدا. اختصر. يجب أن تكون 3-7 دقائق كحد أقصى. لا يتعلق الأمر بوحدة المعالجة المركزية والموارد. يتعلق الأمر بإنتاجية المطورين. أول قاعدة للإنتاجية هي التركيز. افعل شيئًا ، أنهِه ، ثم انتقل إلى الشيء التالي.

تبديل السياق مكلف. تشير الدراسات إلى أن الأمر يستغرق حوالي 23 دقيقة لإعادة التركيز بعمق على شيء ما عندما تشعر بالانزعاج.

تخيل أنك تدفع فرعك لدمجه. تبدأ مهمة أخرى. تقضي 15-20 دقيقة في الدخول فيه. بعد دقيقة من وجودك في المنطقة ، تتلقى إشعار "فشل الإنشاء" من إنشاء CI الخاص بك لمدة 20 دقيقة للمهمة السابقة. عدت لإصلاحه. تدفعه مرة أخرى. لقد فقدت بسهولة أكثر من 20 دقيقة من التحرك ذهابًا وإيابًا.

اضرب 20 دقيقة مرة أو مرتين في اليوم في عدد المطورين في فريقك ... هذا الكثير من الوقت الثمين الضائع.

تخيل الآن ما إذا كانت التعليقات قد جاءت في غضون 3 دقائق. ربما لم تكن قد بدأت المهمة الجديدة على الإطلاق. سيكون لديك دليل على قراءة الرمز الخاص بك مرة أخرى أو مراجعة العلاقات العامة أثناء الانتظار. سيأتي الإخطار الفاشل وستقوم بإصلاحه. ثم يمكنك الانتقال إلى المهمة التالية. هذا هو نوع التركيز الذي يجب أن تتيحه عمليتك.

الحفاظ على إنشاء CI قصيرًا يجعله مقايضة. يجب نقل الاختبارات التي تعمل لفترة أطول أو تقدم قيمة قليلة في سياق CI إلى خطوة القرص المضغوط. ونعم ، هناك حاجة أيضًا إلى إصلاح الفشل. ولكن نظرًا لأنها لا تمنع أي شخص من القيام بعمله ، يمكنك اعتبار الإصلاحات "مهمة تالية" عند الانتهاء من ما تقوم به. ما عليك سوى إيقاف تشغيل الإشعارات أثناء العمل والتحقق من ذلك بين الحين والآخر. حافظ على تبديل السياق إلى الحد الأدنى.

التسليم والنشر المستمر هي مشاكل هندسية

دعنا نستقر على التعريفات لنخرج ذلك من الطريق.

يدور التسليم المستمر حول القدرة على نشر أي إصدار من التعليمات البرمجية الخاصة بك في جميع الأوقات. في الممارسة العملية ، هذا يعني الإصدار الأخير أو ما قبل الأخير من التعليمات البرمجية. لا يتم النشر تلقائيًا ، عادةً لأنك لست مضطرًا إلى أو مقيد بدورة حياة مشروعك. ولكن بمجرد أن يشعر شخص ما بذلك ، يمكن إجراء النشر في أقل وقت ممكن. يمكن أن يكون هذا الشخص هو فريق الاختبار / ضمان الجودة الذي يريد اختبار الأشياء في بيئة مرحلية أو ما قبل الإنتاج. أو قد يكون الوقت قد حان بالفعل لطرح الكود على الإنتاج.

تتمثل فكرة التسليم المستمر في إعداد القطع الأثرية في أقرب وقت ممكن مما تريد تشغيله في بيئتك. يمكن أن تكون هذه ملفات .jar أو .war إذا كنت تعمل باستخدام Java ، أو ملفات قابلة للتنفيذ إذا كنت تعمل مع .NET. يمكن أن تكون هذه أيضًا مجلدات من كود JS المنقول أو حتى حاويات Docker ، أيًا كان ما يجعل النشر أقصر (على سبيل المثال ، لقد بنيت مسبقًا قدر الإمكان).

من خلال إعداد القطع الأثرية ، لا أقصد تحويل الكود إلى قطع أثرية. هذا عادة ما يكون عبارة عن نصوص قليلة ودقائق للتنفيذ. يعني التحضير:

قم بإجراء جميع الاختبارات التي يمكنك إجراؤها للتأكد من أن الكود سيعمل بالفعل بمجرد نشره. قم بتشغيل اختبارات الوحدة ، واختبارات التكامل ، والاختبارات من البداية إلى النهاية ، وحتى اختبارات الأداء إذا كان بإمكانك أتمتة ذلك.

وبهذه الطريقة ، يمكنك تصفية إصدارات فرعك الرئيسي الجاهزة للإنتاج بالفعل وأيها غير جاهز. مجموعة الاختبار المثالية:

  • يضمن عمل الوظائف الرئيسية للتطبيق. من الناحية المثالية ، جميع الوظائف
  • يضمن عدم تقديم أي كسر لصفقة الأداء ، لذلك عندما يصطدم إصدارك الجديد بالعديد من المستخدمين ، يكون لديه فرصة للاستمرار
  • قم بتشغيل أي تحديثات لقاعدة البيانات تحتاجها التعليمات البرمجية لتجنب المفاجآت

لا يلزم أن تكون سريعة جدًا. 30 دقيقة أو 1 ساعة مقبولة.

النشر المستمر هو الخطوة التالية. يمكنك نشر أحدث إصدار جاهز للإنتاج من التعليمات البرمجية الخاصة بك في بعض البيئات. إنتاج مثالي إذا كنت تثق في مجموعة اختبار القرص المضغوط بما يكفي.

لاحظ أنه بناءً على السياق ، هذا ليس ممكنًا دائمًا أو يستحق الجهد المبذول. غالبًا ما يكون التسليم المستمر كافيًا ليكون منتجًا ، خاصة إذا كنت تعمل في شبكة قريبة ولديك بيئات محدودة يمكنك النشر فيها. يمكن أيضًا أن تمنع دورة إصدار البرنامج عمليات النشر غير المخطط لها.

التسليم المستمر والنشر المستمر (دعنا نسميها القرص المضغوط من الآن فصاعدًا) ليست مشاكل الفريق. إنهم يدورون حول إيجاد التوازن الصحيح بين وقت التنفيذ وجهود الصيانة ومدى ملاءمة مجموعة الاختبارات الخاصة بك لتتمكن من قول "هذا الإصدار يعمل كما ينبغي".

وهو توازن. إذا استمرت اختباراتك لمدة 30 ساعة فهذه مشكلة. شاهد هذا المنشور الملحمي حول الشكل الذي تبدو عليه مجموعة اختبار قاعدة بيانات Oracle. ولكن إذا قضيت الكثير من الوقت في تحديث اختباراتك بأحدث الكود الذي يعيق تقدم الفريق ، فهذا ليس جيدًا أيضًا. وأيضًا إذا كانت مجموعة الاختبار الخاصة بك لا تضمن شيئًا إلى حد كبير ... فهي عديمة الفائدة في الأساس.

في عالم مثالي ، نريد مجموعة واحدة من القطع الأثرية القابلة للنشر لكل التزام بالفرع الرئيسي. يمكنك أن ترى أن لدينا مشكلة قابلية التوسع الرأسي: كلما انتقلنا بشكل أسرع من الكود إلى العناصر الأثرية ، كلما كنا أكثر استعدادًا لنشر أحدث إصدار من الكود.

ما هو الاختلاف الكبير؟

التكامل المستمر هو مشكلة قابلية التوسع الأفقي. تريد للمطورين دمج التعليمات البرمجية الخاصة بهم كثيرًا ، لذا يجب أن تكون عمليات التحقق سريعة. من الناحية المثالية في غضون دقائق لتجنب المطورين تبديل السياق طوال الوقت مع ردود الفعل غير المتزامنة للغاية من بنيات CI.

كلما زاد عدد المطورين لديك ، زادت قوة الحوسبة التي تحتاجها لإجراء فحوصات بسيطة (بناء واختبار) على جميع الفروع النشطة.

بناء CI جيد: يضمن عدم تقديم رمز يكسر الأشياء الأساسية ويمنع أعضاء الفريق الآخرين من العمل إلى الفرع الرئيسي ، وهو سريع بما يكفي لتقديم ملاحظات للمطورين في غضون دقائق لمنع تبديل السياق بين المهام.

يعتبر التسليم والنشر المستمران من مشكلات قابلية التوسع الرأسية. لديك عملية واحدة معقدة إلى حد ما.

بناء قرص مضغوط جيد: يضمن عمل أكبر عدد ممكن من الميزات بشكل صحيح ، وكلما كان الأسرع أفضل ، لكن الأمر لا يتعلق بالسرعة. بناء 30-60 دقيقة على ما يرام.

من المفاهيم الخاطئة الشائعة أن ترى القرص المضغوط على أنه مشكلة قابلية للتوسع الأفقي مثل CI: كلما تمكنت من الانتقال بشكل أسرع من الكود إلى القطع الأثرية ، زادت الالتزامات التي يمكنك معالجتها بالفعل ، وكلما اقتربت من السيناريو المثالي.

لكننا لسنا بحاجة لذلك. عادة ما يكون إنتاج القطع الأثرية لكل التزام وبأسرع وقت ممكن مبالغة. يمكنك التعامل جيدًا مع القرص المضغوط على أساس أفضل مجهود: احصل على قرص مضغوط واحد سيختار آخر التزام للتحقق بمجرد الانتهاء من بناء معين.

لا تخطئ بشأن القرص المضغوط. من الصعب حقا. عادةً ما يعمل الحصول على ثقة كافية للاختبار ليقول أن برنامجك جاهز للنشر تلقائيًا على التطبيقات منخفضة السطح مثل واجهات برمجة التطبيقات أو واجهات المستخدم البسيطة. من الصعب جدًا تحقيقه على واجهة مستخدم معقدة أو نظام مترابط كبير.

استنتاج

الأدوات والمبادئ المستخدمة في تنفيذ CI و CD غالبًا ما تكون متشابهة جدًا. لكن الأهداف مختلفة جدا.

يعتبر التكامل المستمر بمثابة مقايضة بين سرعة حلقة التغذية الراجعة للمطورين وأهمية فحوصات الأداء (الإنشاء والاختبار). لا يوجد رمز من شأنه أن يعيق تقدم الفريق يجب أن يصل إلى الفرع الرئيسي.

يدور التسليم المستمر للنشر حول إجراء فحوصات شاملة قدر الإمكان للقبض على المشكلات في التعليمات البرمجية الخاصة بك. إن اكتمال عمليات الفحص هو العامل الأكثر أهمية. عادة ما يتم قياسه من حيث تغطية الكود أو التغطية الوظيفية لاختباراتك. يؤدي اكتشاف الأخطاء مبكرًا إلى منع نشر التعليمات البرمجية المعطلة في أي بيئة وتوفير الوقت الثمين لفريق الاختبار الخاص بك.

صمم تصميمات CI و CD لتحقيق هذه الأهداف والحفاظ على إنتاجية فريقك. لا يوجد سير عمل مثالي. سوف تظهر المشاكل بين الحين والآخر. استخدمها كدروس مستفادة لتقوية سير عملك في كل مرة يفعلون فيها ذلك.

نُشر في 27 نوفمبر 2019 على مدونة Fire CI.