معمارية تطبيقات المصادر المفتوحة › هندسة إصدارات Firefox 28 / 51 السابق التالي

هندسة إصدارات فَيرفُكس

معمارية تطبيقات المصادر المفتوحة (المجلد الثاني)هندسة إصدارات Firefox

معمارية تطبيقات المصادر المفتوحة (المجلد الثاني) هندسة إصدارات Firefox

Chris AtLee و Lukas Blakk و John O'Duinn و Armen Zambrano Gasparian

إذا استمتعت بهذه الكتب، فقد تستمتع أيضًا بـ التصميم البرمجي بالأمثلة في Python والتصميم البرمجي بالأمثلة في JavaScript.

حقّز فريق هندسة الإصدارات في Mozilla مؤخرًا عددًا كبيرًا من التقدّم في أتمتة إصدارات Firefox. لقد قلّلنا متطلبات التدخل البشري أثناء التوقيع الرقمي وإرسال الإشعارات إلى أصحاب المصلحة، وأتمتنا العديد من الخطوات اليدوية الصغيرة الأخرى، لأن كل خطوة يدوية في هذه العملية فرصة لارتكاب خطأ بشري. ورغم أن ما لدينا اليوم ليس مثاليًا، فإننا نعمل دائمًا على تبسيط عمليتنا وإتماتها. هدفنا النهائي هو أن نتمكن من الضغط على زر ثم نمضي بعيدًا؛ فالتدخل البشري الأدنى سيُنهي الكثير من المتاعب وإعادة العمل التي عانينا منها في عمليات الإصدار القديمة التي كانت مزيجًا من اليدوي والآلي. وفي هذا الفصل سنستكشف ونشرح السكربتات وقرارات البنية التحتية التي تشكّل نظام الإصدارات السريع (rapid release) الكامل في Firefox، حتى إصدار Firefox 10.

سيرافقك النظام من منظور مجموعة تغييرات Mercurial صالحة للإصدار، وكيف تتحوّل إلى نسخة مرشّحة للإصدار—ثم إلى إصدار عام—متاح لأكثر من 450 مليون مستخدم يومي حول العالم. وسنبدأ بالبناء والتوقيع على الشيفرة، ثم بإعادة الحزم المخصّصة للشركاء والتعريب، وبعملية ضمان الجودة (QA)، وبكيفية توليدنا للتحديثات لكل إصدار ومنصّة وتعريب مدعوم. ويجب إتمام كل هذه الخطوات قبل أن يمكن دفع الإصدار إلى شبكة مرايا مجتمع Mozilla التي تقدّم التنزيلات إلى مستخدمينا.

سنطّلع على بعض القرارات التي اتُّخذت تحسينًا لهذه العملية؛ مثل سكربت التحقّق من السلامة (sanity-checking) الذي يساعد على إسقاط جانب كبير مما كان معرّضًا للخطأ البشري؛ وسكربت التوقيع الآلي؛ وتكاملنا لإصدارات الجوّال ضمن عملية إصدار سطح المكتب؛ وpatcher حيث تُنشأ التحديثات؛ وAUS (Application Update Service) حيث تُخدَم تحديثاتنا لمستخدمينا عبر إصدارات متعدّدة من البرنامج.

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

2.1. انظر في N اتّجاهات قبل بدء الإصدار

الانتقال من الشيفرة إلى إشارة «انتقل إلى البناء» الشكل 2.1: الانتقال من الشيفرة إلى «انتقل إلى البناء»

عندما بدأنا مشروع تحسين عملية إصدار Mozilla، انطلقنا من القناعة بأن كلما ازدادت شهرة Firefox اتّسع قاعدة مستخدمينا، وازدادت جاذبيته كهدف أمام الهاكرين العاجزين على استغلال الثغرات الأمنية. وكما أن ازدياد شهرة Firefox يعني ازدياد عدد المستخدمين الذين يتعيّن علينا حمايتهم من أي ثغرة أمنية مكتشفة حديثًا، فهو يعني أيضًا ازدياد أهمية قدرتنا على تسليم إصلاح أمني في أسرع وقت ممكن. بل لدينا مصطلح لذلك: إصدار «chemspill» (اختصارًا لعبارة «chemical spill» أي التسريب الكيميائي). وبدلًا من أن نُفاجأ بالحاجة العارضة إلى إصدار chemspill بين إصداراتنا المجدولة بانتظام، قررنا أن نخطّط وكأن كل إصدار قد يكون إصدار chemspill، وصمّمنا أتمتة الإصدار على هذا الأساس.

لهذه العقلية ثلاث نتائج مهمّة:

  1. نُجري تحليلًا بعد الإصدار (postmortem) في كل مرة، ونبحث عمّا يمكن جعله أكثر سلاسةً ويسرًا وسرعةً في المرة القادمة. وإذا أمكن على الإطلاق، فإننا نكتشف أمرًا واحدًا على الأقل، مهما صغر، ونصلحه فورًا—قبل الإصدار التالي. وهذا الصقل المستمر لأتمتة إصداراتنا يعني أننا نبحث دائمًا عن طرائق جديدة للاعتماد على تدخل بشري أقل مع تحسين المتانة وزمن turnaround. ويذهب جهد كبير في جعل أدواتنا وعملياتنا خالية من الثغرات إلى أقصى حد، بحيث تُلتقط الأحداث «النادرة»، مثل تعثّرات الشبكة أو مشكلات مساحة القرص أو الأخطاء المطبعية التي يرتكبها بشر حقيقيون أحياء، وتُعالَج في أبكر وقت ممكن. ورغم أننا نملك بالفعل سرعة كافية للإصدارات الاعتيادية غير من نوع chemspill، فإننا نريد تقليل خطر أي خطأ بشري في إصدار مستقبلي. ويصحّ هذا بصفة خاصة في إصدارات chemspill.
  2. عندما نُجري إصدار chemspill فعلًا، فإنما كانت أتمتة الإصدار أكثر متانة كان الضغط على البشريين في هندسة الإصدارات أقل. اعتدنا فكرة المضي بأقصى سرعة بدقّة هادئة، وقد بنينا أدوات لتنفيذ ذلك بأمان ومتانة على أفضل ما نعرف. وقلة الضغط تعني عملًا أكثر هدوءًا ودقّة ضمن عملية مُحكَّمة الإتقان، ما يساعد بدوره في أن تمرّ إصدارات chemspill بسلاسة.
  3. أنشأنا عملية «انتقل إلى البناء» على مستوى Mozilla بأكمله. عند إجراء إصدار اعتيادي (غير chemspill) يمكن للجميع مراجعة استعلامات الفرز ذاتها ومعرفة الوقت الذي دُمج فيه آخر إصلاح واختُبر بنجاح، ثمّ الاتفاق على وقت بدء البنايات. غير أنه في إصدار chemspill—حيث تكون الدقائق مهمّة—يصبح تتبّع كل تفاصيل العطل ومتابعة تأكيدات الأخطاء وإصلاحاتها أمرًا بالغ التعقيد في وقت قصير جدًا. ولتقليل التعقيد وخطر الأخطاء، صار لدى Mozilla موظف بدوام كامل يتابع جاهزية الشيفرة لاتخاذ قرار «انتقل إلى البناء». وتغيير العمليات أثناء chemspill محفوف بالمخاطر، ولضمان أن يكون الجميع ملمًّا بالعمليات في لحظات الدقائق، فإننا نستخدم هذه العملية نفسها في إصدارات chemspill والإصدارات الاعتيادية.

الخط الزمني الكامل للإصدار الشكل 2.2: الخط الزمني الكامل للإصدار، مع استخدام chemspill مثالًا

2.2. «انتقل إلى البناء»

مَن يحقّ له إرسال «انتقل إلى البناء»؟

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

تستخدم الشركات المختلفة مُسميات مختلفة لهذا الدور. ومن المسميات التي سمعنا بها: مدير الإصدار، مهندس الإصدار، مدير البرنامج، مدير المشروع، مدير المنتج، فرمان المنتج، قائد الإصدار. وسنستخدم في هذا الفصل مصطلح «منسّق الإصدار» (Release Coordinator) لأننا نراه الأكثر وضوحًا في تعريف الدور في عمليتنا على النحو الموصوف أعلاه. والنقطة المهمّة هنا هي أن الدور، والسلطة النهائية المنوطة به، مفهومان بوضوح لدى الجميع قبل بدء الإصدار، بغضّ النظر عن خلفياتهم أو خبراتهم السابقة في العمل. وفي لهيب يوم الإصدار، من المهمّ أن يعرف الجميع التقيّد بقرارات التنسيق التي يتّخذها هذا الشخص وثقتها.

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

كيف يُرسَل «انتقل إلى البناء»؟

أدت التجارب الأولى لإرسال «انتقل إلى البناء» في غرف IRC أو شفهيًا عبر الهاتف إلى سوء فهم، سبّب أحيانًا مشكلات للإصدار الجاري. ومن ثم نشترط الآن أن تتمّ إشارة «انتقل إلى البناء» لكل إصدار عبر البريد الإلكتروني، إلى قائمة بريدية تضمّ كل الأشخاص من كل المجموعات المشاركة في عمليات الإصدار. ويحتوي سطر الموضوع في الرسالة على «انتقل إلى البناء» إضافة إلى اسم المنتج ورقم الإصدار صراحةً؛ على سبيل المثال:

go to build Firefox 6.0.1

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

ماذا يحتوي بريد «انتقل إلى البناء»؟

  1. الشيفرة الدقيقة المستخدَمة في البناء؛ ويفضَّل أن يكون ذلك عنوان URL للتغيير المحدّد في مستودع شيفرة المصدر الذي ستُنشأ منه بنايات الإصدار. وتوجيهات مثل «استخدم أحدث شيفرة» غير مقبولة إطلاقًا؛ ففي أحد الإصدارات، وبعد إرسال رسالة «انتقل إلى البناء» وقبل بدء البنايات، دمج مطوّر حسن النية تغييرًا من دون موافقة في الفرع الخطأ. وقد أدخل الإصدار ذلك التغيير غير المرغوب في البنايات. ولحسن الحظ التُقط الخطأ قبل النشر، لكننا اضطررنا إلى تأجيل الإصدار بينما نقوم بإيقاف كامل وإعادة بناء كل شيء.
  2. في نظام تحكّم بالإصدارات قائم على الزمن مثل CVS، كن صريحًا تمامًا بشأن الوقت الدقيق المطلوب؛ أعطِ الوقت إلى الثانية، وحدّد المنطقة الزمنية. ففي أحد الإصدارات، حين كان Firefox ما زال قائمًا على CVS، حدّد منسّق الإصدار وقت cutoff المطلوب للبناءات لكنه لم يذكر المنطقة الزمنية. وحين لاحظت هندسة الإصدارات غياب معلومات المنطقة الزمنية، كان منسّق الإصدار نائمًا. وخمّنت هندسة الإصدارات على نحو صحيح أن المقصود كان التوقيت المحلّي في كاليفورنيا، لكن خطأ خلط في وقت متأخر من الليل بين PDT وPST جعلنا يفوت آخر إصلاح حرج. والتقطه ضمان الجودة قبل النشر، لكننا اضطررنا إلى إيقاف البنايات والبدء في البناء من جديد باستخدام وقت cutoff الصحيح.

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

  1. بعض الإصدارات «اعتيادية» ويمكن العمل عليها ضمن ساعات العمل المعتادة. فهي إصدارات مخطّطة مسبقًا، وهي في موعدها، ولا توجد حالة طارئة. وبالطبع يجب إنشاء جميع بنايات الإصدار في الوقت المناسب، لكن لا داعي لمهندسي الإصدار لسهرات مبيت كاملة أو الإرهاق من أجل إصدار اعتيادي. وبدلًا من ذلك، نخطّط لها مسبقًا على الوجه الصحيح بحيث يبقى كل شيء في موعده مع عمل الناس ضمن ساعاتهم المعتادة. وهذا يُبقي الناس مرتاحين وأقدر على التعامل مع العمل العاجل غير المجدول إن نشأ.
  2. بعض الإصدارات من نوع «chemspill» وهي عاجلة، حيث تكون الدقائق مهمّة. وهي غالبًا لإصلاح استغلال أمني منشور، أو لإصلاح مشكلة تعطّل علوي (top-crash) ظهرت حديثًا وتؤثّر في نسبة كبيرة من قاعدة مستخدمينا. ويجب إنشاء إصدارات chemspill في أسرع وقت ممكن، وهي عادةً ليست إصدارات مخطّطة مسبقًا.
  3. بعض الإصدارات تنتقل من اعتيادية إلى chemspill أو من chemspill إلى اعتيادية. فمثلًا، إذا تسرّب إصلاح أمني في إصدار اعتيادي عن طريق الخطأ، فإن الإصدار صار الآن إصدار chemspill. وإذا تأخّر متطلّب تجاري، مثل إصدار «معاينة خاصة بلمحة» للإعلان عن مؤتمر قادم، لأسباب تجارية، فإن الإصدار ينتقل الآن من chemspill إلى اعتيادي.
  4. بعض الإصدارات يختلف الناس في رأيهم بشأن كون الإصدار عاديًا أم عاجلًا، بحسب منظورهم الخاص في الإصلاحات التي يشحن بها الإصدار.

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

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

طوال دورة beta في Firefox، نقوم أيضًا بإصدارات أسبوعية من مستودع mozilla-beta. يمرّ كل واحد من هذه الإصدارات التجريبية بأتمتة الإصدار الكاملة المعتادة لدينا، ويُعامَل تقريبًا تمامًا كإصداراتنا النهائية الاعتيادية. ولتقليل المفاجآت أثناء الإصدار، يكون مقصدنا ألّا تكون هناك أي تغييرات جديدة غير مختبَرة في أتمتة الإصدار أو البنية التحتية بحلول الوقت الذي نبدأ فيه بنايات الإصدار النهائية.

2.3. وضع الوسوم والبناء وحِزَم المصدر

الوسم الآلي الشكل 2.3: الوسم الآلي

في تحضير لبدء الأتمتة، بدأنا مؤخرًا في استخدام سكربت هو release_sanity.py، وقد كتبه في الأصل متدرّب صيفي في هندسة الإصدارات. يساعد هذا السكربت المكتوب بـ Python مهندس الإصدار على إعادة التحقّق من أن جميع إعدادات الإصدار تطابق ما هو مُودَع في مستودعات الأدوات والإعدادات لدينا. كما أنه يتحقّق مما ورد في مراجعات شيفرة الإصدار المحدّدة لكل من mozilla-release ولكل اللغات البشرية الخاصة بهذا الإصدار، وهي ما ستُولَّد منه البنايات وإعادة حزم اللغات.

يقبل السكربت ملفات إعدادات buildbot لأي إعدادات إصدار ستُستخدم مثل سطح المكتب أو الجوّال، والفرع المطلوب فحصه مثل mozilla-release، ورقم البناء ورقم الإصدار، وأسماء المنتجات التي ستُبنى مثل «fennec» أو «firefox». وسيفشل إذا لم تكن مستودعات الإصدار مطابقة لما ورد في الإعدادات، أو إذا لم تتطابق مجموعات تغييرات مستودعات اللغات مع لغاتنا المشحونة وملفات مجموعات تغييرات التعريب، أو إذا لم يتطابق رقم إصدار الإصدار ورقم البناء مع ما مُرِّر إلى أدوات البناء لدينا مع الوسم المولَّد باستخدام المنتج والإصدار ورقم البناء. وإذا اجتازت جميع اختبارات السكربت، فسيُعيد ضبط خادم buildbot master الذي يعمل عليه السكربت والذي ستُطلق منه بانيات الإصدار، ثمّ يولّد «send change» الذي يبدأ عملية الإصدار الآلية.

بعد أن يشغّل مهندس الإصدار البانيات، تكون أول خطوة آلية في عملية إصدار Firefox هي وضع الوسوم على جميع مستودعات شيفرة المصدر ذات الصلة، لتوثيق أي مراجعة من شيفرة المصدر ومستودعات اللغات والأدوات المرتبطة هي المستخدَمة في رقم الإصدار ورقم البناء لنسخة مرشّحة للإصدار. وتتيح لنا هذه الوسوم الاحتفاظ بسجل لأرقام إصدارات وإصدارات بناء Firefox وFennec أي Firefox للجوّال في مستودعات الإصدار لدينا. وبالنسبة لإصدارات Firefox، فإن مجموعة وسوم نموذجية هي FIREFOX_10_0_RELEASE FIREFOX_10_0_BUILD1 FENNEC_10_0_RELEASE FENNEC_10_0_BUILD1.

يستخدم إصدار واحد من Firefox شيفرة من نحو 85 مستودعًا للتحكّم بالإصدارات، تستضيف أمورًا مثل شيفرة المنتج ونصوص التعريب وشيفرة أتمتة الإصدارات والأدوات المساعدة. ووضع الوسوم على كل هذه المستودعات بالغ الأهمية لضمان تنفيذ جميع الخطوات اللاحقة من أتمتة الإصدار باستخدام المجموعة نفسها من المراجعات. كما أنه يجلب عددًا من الفوائد الأخرى: فبإمكان توزيعات Linux والمساهمين الآخرين إعادة إنتاج البنايات بالشيفرة والأدوات نفسها تمامًا التي دخلت في البنايات الرسمية، كما أنه يسجّل مراجعات المصدر والأدوات المستخدَمة لكل إصدار على حدة، تمهيدًا لمقارنة ما تغيّر بين الإصدارات لاحقًا. وبمجرد التفريع ووضع الوسوم على جميع المستودعات، تبدأ سلسلة من البانيات المعتمدة في العمل تلقائيًا: بانية واحدة لكل منصة من منصّات الإصدار، إضافة إلى حزمة مصدرية تضمّ كامل الشيفرة المستخدَمة في الإصدار. وتُرفَع حزمة المصدر والمثبِّتات المبنيّة جميعًا إلى مجلّد الإصدار فور توفّرها. ويتيح ذلك لأي شخص أن يرى بدقة ما في الإصدار من شيفرة، كما يوفّر لقطةً تمكّننا من إعادة إنشاء البنايات متى احتجنا إلى ذلك، مثلًا إذا أخفق نظام التحكّم بالإصدارات لدينا لسبب ما. وأحيانًا نحتاج، لأجل شيفرة بناء Firefox، إلى استيراد شيفرة من مستودع أسبق. فمثلًا، في الإصدار التجريبي يعني هذا جلب المراجعة المعتمَدة من Mozilla-Aurora، وهو مستودعنا الأكثر استقرارًا من Nightly، الخاصة بـ Firefox 10.0b1. أما في الإصدار النهائي فيعني ذلك جلب التغييرات المعتمَدة من Mozilla-Beta، وهي عادةً الشيفرة نفسها المستخدَمة في 10.0b6، إلى مستودع Mozilla-Release. ويُنشَأ فرع الإصدار هذا بعد ذلك كفرع مُسمًّى تكون مجموعته التغييرية الأصل هي المراجعة المعتمَدة في رسالة «انتقل إلى البناء» المقدَّمة من منسّق الإصدار. ويمكن استخدام فرع الإصدار، أي relbranch، لإجراء تعديلات خاصة بالإصدار على شيفرة المصدر، مثل رفع أرقام الإصدارات أو تثبيت مجموعة اللغات التي ستُبنى. وإذا اكتُشف في المستقبل ثغرة أمنية حرجة تتطلّب إصلاحًا فوريًا—أي chemspill—فسيُدخَل على فرع الإصدار هذا مجموعة دنيا من التغييرات لمعالجة الثغرة، ثمّ يُولَّد إصدار جديد من Firefox ويُنشر انطلاقًا منه. وعندما نضطر إلى إجراء جولة أخرى من البنايات لإصدار معيّن buildN، فإننا نستخدم فروع الإصدار هذه لجلب الشيفرة نفسها التي اعتُمدت في رسالة «انتقل إلى البناء»، وهي الموضع الذي دُخِّلت إليه أي تغييرات على شيفرة ذلك الإصدار. ثمّ تبدأ الأتمتة من جديد وترفع الوسوم إلى مجموعة التغييرات الجديدة على فرع الإصدار ذاك. وتُجري عملية وضع الوسوم لدينا كثيرًا من العمليات على مستودعات Mercurial المحلّية والبعيدة. ولتبسيط بعض العمليات الأكثر شيوعًا، كتبنا بعض الأدوات لمساعدتنا: retry.py وhgtool.py. وretry.py غلاف بسيط يتلقّى أمرًا معيّنًا ويشغّله، ويعيد المحاولة عدّة مرات إن فشل. كما يمكنه مراقبة حالات الإخراج غير الاعتيادية فيعيد المحاولة أو يُبلّغ عن الفشل في تلك الحالات. وقد اتّضح لنا أنه مفيد تغليف retry.py حول معظم الأوامر التي قد تفشل بسبب اعتماديات خارجية. فبالنسبة إلى وضع الوسوم، قد تفشل عمليات Mercurial بسبب انقطاع مؤقت للشبكة أو مشكلات في خادم الويب أو تحمّل زائد مؤقت على خادم Mercurial الخلفي. والقدرة على إعادة محاولة هذه العمليات تلقائيًا ثمّ المتابعة توفّر علينا وقتًا كبيرًا، إذ لا نضطر إلى الاسترداد يدويًا، ولا إلى تنظيف أي آثار جانبية، ثمّ إعادة تشغيل أتمتة الإصدار من جديد. أمّا hgtool.py فهو أداة تغلّف عدة عمليات Mercurial شائعة، مثل الاستنساخ والسحب والتحديث، باستدعاء واحد. كما يضيف دعمًا لامتداد Mercurial المعروف بـ share، وهو الامتداد الذي نستخدمه على نطاق واسع تفاديًا لوجود عدة استنساخات كاملة للمستودعات في مجلّدات مختلفة على الآلة نفسها. وقد أدّى دعم المستودعات المحلّية المشتركة إلى تسريع كبير في عمليتنا في وضع الوسوم، إذ أمكن تفادي معظم الاستنساخات الكاملة لمستودعات المنتج واللغات. ومن الدوافع المهمّة لتطوير أدوات كهذه جعل أتمتتنا قابلة للاختبار قدر الإمكان. فالأدوات مثل hgtool.py صغيرة ومحدودة الغرض ومبنيّة على مكتبات قابلة لإعادة الاستخدام، ما يجعل اختبارها على حدة أسهل بكثير.

تُجري وضع الوسوم اليوم في وظيفتين متوازيتين: واحدة لـ Firefox على سطح المكتب، تستغرق نحو 20 دقيقة حتى تكتمل لأنها تتضمّن وضع الوسوم على أكثر من 80 مستودع لغات، وأخرى لـ Firefox على الجوّال، تستغرق نحو 10 دقائق حتى تكتمل لأن لدينا لغات أقل حاليًا متاحة لإصداراتنا على الجوّال. وفي المستقبل نودّ أن نُبسّط عملية أتمتة الإصدار لدينا بحيث نضع الوسوم على جميع المستودعات المختلفة بالتوازي. ويمكن بدء البنايات الأولية بمجرّد وضع الوسوم على مستودع متطلّبات شيفرة المنتج والأدوات، من دون الحاجة إلى انتظار وضع الوسوم على جميع مستودعات اللغات. وبحلول الوقت الذي تنتهي فيه هذه البنايات، تكون بقية المستودعات قد وُسِمت بحيث يمكن إكمال إعادة حزم التعريب والخطوات اللاحقة. ونقدّر بأن هذا يمكن أن يخفّض الزمن الكلي حتى جاهزية البنايات بمقدار 15 دقيقة.

2.4. إعادة الحزم الخاصة بالتعريب والشركاء

بمجرد توليد بنايات سطح المكتب ورفعها إلى ftp.mozilla.org، تُطلق أتمتنتا مهامّ إعادة حزم التعريب. تأخذ إعادة حزمة التعريب البناء الأصلي الذي يحتوي لغة en-US، وتفكّه، وتستبدل نصوص en-US بنصوص لغة أخرى نشحنها في هذا الإصدار، ثمّ تعيد حزم جميع الملفات من جديد، ولهذا نسمّيها إعادة حزم. ونكرّر ذلك لكل لغة نشحنها في الإصدار. في البداية، كنا نفعل جميع عمليات إعادة الحزم بالتسلسل. لكن مع إضافة المزيد من اللغات، استغرق ذلك وقتًا طويلًا حتى يكتمل، واضطررنا إلى البدء من البداية إن فشل أي شيء في منتصف الطريق.

إعادة حزم Firefox لكل لغة تعريب الشكل 2.4: إعادة حزم Firefox لكل تعريب

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

أما عملية الجوّال على Android فهي مختلفة قليلًا، إذ ننتج مثبِّتين فقط: نسخة إنجليزية ونسخة متعددة اللغات تتضمّن أكثر من اثنتي عشرة لغة مدمجة في المثبِّت بدلًا من بناء منفصل لكل لغة. وحجم هذه النسخة متعددة اللغات يمثّل مشكلة، ولا سيما مع سرعات التنزيل البطيئة على الأجهزة المحمّبة الصغيرة. وأحد المقترحات للمستقبل هو أن تُطلب اللغات الأخرى عند الحاجة كإضافات من addons.mozilla.org.

في الشكل 2.4 يمكنك أن ترى أننا نعتمد حاليًا على ثلاثة مصادر مختلفة لمعلومات اللغات لدينا: shipped_locales وl10_changesets وl10n-changesets_mobile-release.json. وهناك خطة لنقل الملفات الثلاثة إلى ملف JSON موحّد. وتحتوي هذه الملفات على معلومات عن تعجماتنا المختلفة، وعن استثناءات معيّنة للمنصّات. وعلى وجه التحديد، نحتاج لكل تعريب معيّن أن نعرف أي مراجعة من المستودع نستخدمها لإصدار معيّن، ونحتاج أيضًا أن نعرف ما إذا كان التعريب قابلًا للبناء على جميع منصّاتنا المدعومة، مثلًا اليابانية لأجل Mac تأتي من مستودع مختلف تمامًا. يُستخدم ملفّان من هذه الملفات لإصدارات سطح المكتب وواحد لإصدار الجوّال، ويحتوي ملف JSON هذا على قائمة المنصّات ومجموعات التغييرات معًا.

من يقرّر أي اللغات نشحن؟ أولًا، المرخّصون أنفسهم يرشّحون مجموعة التغييرات الخاصة بهم لإصدار معيّن. وتُراجَع مجموعة التغييرات المرشَّحة من فريق التعريب في Mozilla وتظهر في لوحة تحكّم على الويب تسرد مجموعات التغييرات المطلوبة لكل لغة. ويراجع منسّق الإصدار ذلك قبل إرسال رسالة «انتقل إلى البناء». وفي يوم الإصدار، نسترجع هذه القائمة من مجموعات التغييرات ونعيد حزمها وفقًا لها.

إلى جانب إعادة حزم التعريب، فإننا نولّد أيضًا إعادة حزم للشركاء. وهذه بنايات مخصّصة لمختلف الشركاء لدينا الذين يريدون تخصيص التجربة لعملائهم. والنوع الرئيسي من التغييرات هو الإشارات المرجعية المخصّصة والصفحة الرئيسية المخصّصة ومحركات البحث المخصّصة، لكن أشياء كثيرة أخرى يمكن تغييرها. وتُولَّد هذه البنايات المخصّصة لأحدث إصدار من Firefox، لا للإصدارات التجريبية.

2.5. التوقيع الرقمي

كي يكون المستخدمون متأكّدين من أن النسخة التي نزّلوها من Firefox هي حقًا البناء غير المعدّل من Mozilla، فإننا نطبّق عدة أنواع مختلفة من التوقيعات الرقمية على البنايات.

النوع الأول من التوقيع هو لإصداراتنا على Windows. ونستخدم مفتاح توقيع Microsoft Authenticode أي signcode لتوقيع جميع ملفات .exe و.dll. ويستطيع Windows استخدام هذه التوقيعات للتحقّق من أن التطبيق يأتي من مصدر موثوق. ونوقّع أيضًا ملف المثبِّت التنفيذي الخاص بـ Firefox بمفتاح Authenticode.

بعد ذلك نستخدم GPG لتوليد مجموعة من قيم التحقّق MD5 وSHA1 لجميع البنايات على جميع المنصّات، ولتوليد توقيعات GPG منفصلة لملفات التحقّق وكذلك لجميع البنايات والمثبِّتات. وتستخدم هذه التوقيعات المرايا وأعضاء المجتمع الآخرين للتحقّق من تنزيلاتهم.

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

توقيع مثبِّتات Firefox الشكل 2.5: توقيع مثبِّتات Firefox

حتى وقت قريب كان يتضمّن هذا التوقيع على مهندس إصدار يعمل على خادم مخصّص يدعى «خادم التوقيع master» لما يقارب ساعة، ينزّل البنايات يدويًا ويوقّعها ويعيد رفعها إلى ftp.mozilla.org قبل أن تتمكّن الأتمتة من المتابعة. وبمجرد اكتمال التوقيع على الخادم الرئيسي ورفع جميع الملفات، كان يُرفَع ملف سجلّ لكل أنشطة التوقيع إلى مجلّد المرشّحين على ftp.mozilla.org. وكان ظهور ملف السجلّ هذا على ftp.mozilla.org يعني انتهاء عمل التوقيع البشري، ومن تلك النقطة تتمكّن البانيات المعتمدة التي تراقب ملف السجلّ ذاك من استئناف الأتمتة. وقد أضفنا مؤخرًا غلافًا إضافيًا من الأتمتة حول خطوات التوقيع. صار مهندس الإصدار يفتح الآن صدفة Cygwin على خادم التوقيع master ويضبط متغيّرات بيئية قليلة تتعلّق بالإصدار، مثل VERSION وBUILD وTAG وRELEASE_CONFIG، تساعد السكربت على إيجاد المجلّدات الصحيحة على ftp.mozilla.org وعلى معرفة متى تكون جميع مخرجات الإصدار قد نُزّلت بحيث يمكن بدء التوقيع. وبعد استخراج أحدث نسخة إنتاجية من أدوات التوقيع لدينا، يقوم مهندس الإصدار ببساطة بتشغيل make autosign. ثمّ يُدخل مهندس الإصدار عبارتَي سرّ، واحدة لـ gpg وأخرى لـ signcode. وبمجرد أن تتحقّق سكربتات make تلقائيًا من عبارتَي السرّ، تبدأ الأتمتة حلقة تنزيل تراقب البنايات وعمليات إعادة الحزم المرفوعة من أتمتة الإصدار وتنزّلها فور توفّرها. وبمجرد نزول جميع العناصر، تبدأ الأتمتة التوقيع فورًا، من دون تدخل بشري.

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

يُولَّد لكل مخرج من المخرجات ملفّا MD5SUM وSHA1SUM، وتُكتب قيم التجزئة تلك في ملفات بالاسم نفسه. وستُرفَع هذه الملفات مجددًا إلى مجلّد المرشّحين، كما تُزامَن إلى الموضع النهائي للإصدار على ftp.mozilla.org بمجرّد أن يصبح منشورًا، بحيث يتمكّن أي شخص ينزّل مثبِّت Firefox من إحدى مرايانا من التأكّد من أنه حصل على الكائن الصحيح. وبمجرد توفّر جميع البتّات الموقَّعة والتحقّق منها، تُرفَع إلى ftp.mozilla.org مع ملف سجلّ التوقيع، وهو الملف الذي تنتظره الأتمتة للمتابعة.

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

2.6. التحديثات

تُنشَأ التحديثات كي يتمكّن المستخدمون من التحديث إلى أحدث إصدار من Firefox بسرعة وسهولة باستخدام مُحدِّثنا المدمج، من دون الحاجة إلى تنزيل مثبِّت مستقل وتشغيله. ومن منظور المستخدم، فإن تنزيل حزمة التحديث يحدث بهدوء في الخلفية. ولا يعرض Firefox على المستخدم خيار تطبيق التحديث وإعادة التشغيل إلا بعد تنزيل ملفات التحديث ويصبحان جاهزين للتطبيق.

المشكلة أننا نولّد كثيرًا من التحديثات. فبالنسبة إلى سلسلة إصدارات في خطّ منتجات، نولّد تحديثات من جميع الإصدارات السابقة المدعومة في السلسلة إلى أحدث إصدار في ذلك خطّ المنتجات. وبالنسبة إلى Firefox LATEST، يعني ذلك توليد تحديثات لكل منصّة وكل لغة ولكل مثبّت من Firefox LATEST-1 وLATEST-2 وLATEST-3 و… في صيغتيه الكاملة والجزئية معًا. ونفعل كل ذلك لعدّة خطوط منتجات مختلفة في الوقت نفسه.

تُعدّل أتمتة توليد التحديثات لدينا ملفات إعدادات التحديثات لبناء كل إصدار انطلاقًا من فرع، لتحافظ على قائمتنا المعتمدة لأرقام الإصدارات والمنصّات والتعجمات التي يجب أن تُولَّد لها تحديثات لتُقدَّم للمستخدمين في هذا الإصدار الأحدث. ونقدّم التحديثات في صورة مقتطفات. وكما ترى في المثال أدناه، فإن هذا المقتطف ببساطة ملف مؤشّر بصيغة XML مستضاف على خدمتنا AUS أي Application Update Service، ويُخبر متصفّح Firefox المستخدم بمكان استضافة ملفات .mar أي Mozilla Archive الكاملة أو الجزئية.

التحديثات الكبرى في مقابل التحديثات الصغرى

<updates>
  <update type="minor" version="7.0.1" extensionVersion="7.0.1"
          buildID="20110928134238"
          detailsURL="https://www.mozilla.com/en-US/firefox/7.0.1/releasenotes/">
    <patch type="complete"
           URL="http://download.mozilla.org/?product=firefox-7.0.1-complete&os=osx&lang=en-US&force=1"
           hashFunction="SHA512"
           hashValue="7ecdbc110468b9b4627299794d793874436353dc36c80151550b08830f9d8c5afd7940c51df9270d54e11fd99806f41368c0f88721fa17e01ea959144f473f9d"
           size="28680122"/>
    <patch type="partial"
           URL="http://download.mozilla.org/?product=firefox-7.0.1-partial-6.0.2&os=osx&lang=en-US&force=1"
           hashFunction="SHA512"
           hashValue="e9bb49bee862c7a8000de6508d006edf29778b5dbede4deaf3cfa05c22521fc775da126f5057621960d327615b5186b27d75a378b00981394716e93fc5cca11a"
           size="10469801"/>
    </update>
</updates>

الشكل 2.6: نموذج مقتطف تحديث

كما ترى في الشكل 2.6، فإن مقتطفات التحديثات لديها سِمة type يمكن أن تكون إمّا major أو minor. والتحديثات الصغرى تُبقي الناس على اطّلاع بأحدث إصدار متاح في قطار إصداراتهم؛ فمثلًا، ستحدّث جميع مستخدمي إصدارات 3.6.* إلى أحدث إصدار 3.6، وجميع مستخدمي الإصدارات التجريبية السريعة إلى أحدث إصدار تجريبي، وجميع مستخدمي Nightly إلى أحدث بناء Nightly، إلخ. وفي معظم الأوقات، تكون التحديثات صغرى ولا تتطلّب أي تفاعل من المستخدم سوى تأكيد لتطبيق التحديث وإعادة تشغيل المتصفّح.

أمّا التحديثات الكبرى فتُستخدم حين نحتاج إلى إبلاغ مستخدمينا بأن أحدث إصدار وأفضله قد أصبح متاحًا، باستفزازهم برسالة «يتوفّر إصدار جديد من Firefox، هل ترغب في التحديث؟» وعرض لوحة إعلانية تُبرز أبرز الميزات في الإصدار الجديد. ويعني نظام الإصدارات السريعة الجديد لدينا أننا لم نعد بحاجة إلى إجراء هذا العدد الكبير من التحديثات الكبرى؛ وسيكون بإمكاننا التوقّف عن توليد التحديثات الكبرى بمجرّد انتهاء دعم قطار إصدارات 3.6.*.

التحديثات الكاملة في مقابل التحديثات الجزئية

عند وقت البناء نولّد ملفات .mar الخاصة بالتحديث الكامل، وهي تحتوي على جميع ملفات الإصدار الجديد، مضغوطة بـ bz2 ثمّ مؤرشفة في ملف .mar. ويُنزَّل كل من التحديثات الكاملة والجزئية تلقائيًا عبر قناة التحديث التي يكون Firefox المستخدم مسجّلًا فيها. ولدينا قنوات تحديث مختلفة، أي أن مستخدمي الإصدار يبحثون عن التحديثات على قناة الإصدار، ومستخدمو الإصدارات التجريبية يبحثون على القناة التجريبية، إلخ، كي نتمكّن من تقديم التحديثات، مثلًا، لمستخدمي الإصدار في وقت يختلف عن تقديمها لمستخدمي الإصدارات التجريبية.

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

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

بعد رفع المقتطفات واستضافتها على AUS، تُنفَّذ خطوة تحقّق من التحديثات من أجل اختبار تنزيل المقتطفات، وتشغيل المُحدِّث بالملف .mar المنزَّل للتأكّد من تطبيق التحديثات على نحو صحيح.

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

2.7. النشر إلى المرايا الداخلية وضمان الجودة

التحقّق من أن عملية الإصدار تُنتج المخرجات المتوقّعة هو أمر جوهري. ويتحقّق ذلك عبر عملية التحقّق والموافقة في ضمان الجودة.

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

عمليًا، تدفع أتمتنتا الملفات الثنائية إلى مرايانا الداخلية، وهي خوادم تستضيفها Mozilla، كي يتحقّق ضمان الجودة من التحديثات. ولا ندفعها إلى مرايا المجتمع إلا بعد أن ينتهي ضمان الجودة من التحقّق من البنايات والتحديثات. وهذه مرايا المجتمع ضرورية للتعامل مع الحمل العالمي من المستخدمين، إذ تتيح لهم طلب تحديثاتهم من عقد مرايا محلية بدلًا من ftp.mozilla.org مباشرة. ومن الجدير بالذكر أننا لا نطرح البنايات والتحديثات على مرايا المجتمع إلا بعد موافقة ضمان الجودة، بسبب المضاعفات التي تنشأ إن عثر ضمان الجودة على عطب مُعيط في اللحظة الأخيرة واحتجنا إلى سحب البناء المرشّح.

عملية التحقّق بعد توليد البنايات والتحديثات هي:

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

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

2.8. النشر إلى المرايا العامة وخدمة AUS

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

هنا بالضبط يصبح الإصدار رسميًا. وبعد أن يرسل منسّق الإصدار رسالة «انطلق» النهائية، تقوم هندسة الإصدارات بتحديث الروابط الرمزية على خادم الويب بحيث يجد زوّار موقع الويب وموقع FTP لدينا أحدث إصدار جديد من Firefox. كما ننشر جميع مقتطفات التحديثات للمستخدمين على الإصدارات السابقة من Firefox إلى AUS.

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

2.9. الدروس المستفادة

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

أهمية كسب التزام بقية أصحاب المصلحة

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

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

إشراك المجموعات الأخرى

جعل عملية الإصدار أكثر كفاءة وموثوقية تطلّب عملًا من هندسة الإصدارات ومن مجموعات أخرى في أنحاء Mozilla. غير أنه كان لافتًا كم مرّة ما تُرجمت عبارة «يستغرق إصدار إصدارًا وقتًا طويلًا» خطأً على أن «هندسة الإصدارات تستغرق وقتًا طويلًا لإصدار إصدار». وكان هذا سوء الفهم يتجاهل عمل الإصدار الذي تنفّذه مجموعات خارج هندسة الإصدارات، وكان مُحبِطًا لمهندسي الإصدارات. وكان إصلاح هذا سوء الفهم يتطلّب تثقيف الناس في أنحاء Mozilla حول مكان قضاء الوقت فعليًا في الإصدارات من قبل المجموعات المختلفة. وقد فعلنا ذلك عبر ختمات زمنية بساعة الحائط منخفضة التقنية في رسائل البريد الإلكتروني الخاصة بسلّم تسليم واضح بين المجموعات، وعبر سلسلة من مقالات المدونة التي تشرح بساعة الحائط أين قضي الوقت.

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

إرساء تسليمات واضحة

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

إدارة تبدّل الموظفين

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

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

إدارة التغيير

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

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

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

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

2.10. للمزيد من المعلومات

نحن فخورون حقًا بالعمل الذي أُنجز حتى الآن، والقدرات التي جاء بها إلى Mozilla في سوق متصفّحات عالمية أشعلت حدّتها حديثًا.

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

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