لماذا يحتاج خط أنابيب CI/CD الخاص بك إلى استراتيجية تخزين مناسبة للقطع الأثرية

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

هذا السيناريو أكثر شيوعًا مما يعترف به معظم الفرق. البناء يعمل، لكن القطعة الأثرية تختفي. أو الأسوأ من ذلك، أن خط أنابيب النشر يعيد بناء القطعة الأثرية من الصفر في بيئة الإنتاج، مستخدمًا إصدارًا مختلفًا من تابع (dependency)، منتجًا شيئًا لم يتم اختباره مطلقًا.

المشكلة ليست في البناء. المشكلة هي أن القطعة الأثرية تم التعامل معها كملف مؤقت، وليس كنتيجة تسليمية مُتحقق منها تحتاج إلى تخزين وتوسيم وتتبع.

ماذا يعني التعبئة (Packaging) والنشر (Publishing) بالضبط

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

التعبئة (Packaging) هي عملية تحويل الكود المُتحقق منه إلى تنسيق يمكن تشغيله في بيئتك المستهدفة. يعتمد التنسيق على ما تقوم ببنائه:

  • للتطبيقات القائمة على الحاويات، التعبئة تعني إنشاء صورة حاوية.
  • لتطبيقات Java، تعني إنتاج ملف JAR أو WAR.
  • لمكتبات JavaScript أو Python، تعني إنشاء حزمة يمكن لـ npm أو pip تثبيتها.
  • للبنية التحتية، قد تعني توليد وحدة Terraform مُتحقق منها أو قالب CloudFormation.

النشر (Publishing) هو فعل إرسال تلك القطعة الأثرية المُعبأة إلى سجل (registry) أو مستودع حيث يمكن الوصول إليها لاحقًا بواسطة خطوط أنابيب النشر. السجل ليس مجرد مخزن تخزين. إنه نظام منظم يحافظ على تنظيم القطع الأثرية الخاصة بك وإصدارها وقابليتها للاكتشاف.

فيما يلي مقتطف YAML بسيط يوضح كيف يقوم خط أنابيب CI بتعبئة صورة حاوية ونشرها مع علامة إصدار فريدة:

- name: Build and tag Docker image
  run: |
    docker build -t myregistry.com/myapp:1.0.0-b20240315-a1b2c3d .

- name: Push image to registry
  run: |
    docker push myregistry.com/myapp:1.0.0-b20240315-a1b2c3d

تذهب صور الحاويات إلى سجلات الحاويات مثل Docker Hub أو Amazon ECR أو Harbor. تذهب حزم التطبيقات إلى مستودعات القطع الأثرية مثل Nexus أو Artifactory أو GitHub Packages. تذهب وحدات البنية التحتية إلى سجلات الوحدات أو مستودعات Git مع توسيم مناسب.

الشيء الوحيد الذي يحدد نجاح أو فشل هذه المرحلة

الإصدار (Versioning) ليس اختياريًا. يجب أن يكون لكل قطعة أثرية تنشرها إصدار فريد وقابل للتتبع. لا يتعلق الأمر باتباع الإصدار الدلالي (Semantic Versioning) لأنه يبدو احترافيًا. إنه يتعلق بالقدرة على الإجابة على سؤال واحد: "ما الذي يعمل بالضبط في بيئة الإنتاج الآن؟"

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

سلسلة إصدار جيدة تجمع بين إصدار دلالي وبيانات وصفية للبناء. شيء مثل 1.2.3-b20240315-a1b2c3d يخبرك برقم الإصدار وتاريخ البناء وhash الـ commit. هذا كافٍ لتتبع القطعة الأثرية إلى الكود المصدري الدقيق، ووظيفة البناء الدقيقة، ونتائج الاختبار الدقيقة.

البيانات الوصفية (Metadata) هي شبكة الأمان الخاصة بك

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

  • hash الـ commit الذي أطلق البناء
  • اسم الفرع (branch)
  • رقم البناء
  • ملخص نتائج الاختبار
  • من قام بتشغيل البناء

بالنسبة لصور الحاويات، تذهب هذه البيانات الوصفية إلى التسميات (labels). بالنسبة لملفات الحزم، تذهب إلى البيان (manifest) أو ملف بيانات وصفية مصاحب. هذه البيانات الوصفية تحول القطعة الأثرية الخاصة بك من صندوق أسود إلى أصل موثق. عندما يسأل شخص ما "هل اجتازت هذه القطعة الأثرية جميع الاختبارات المطلوبة؟"، يمكنك الإشارة إلى البيانات الوصفية وإثبات أنها فعلت.

لماذا هذا مهم لثقة النشر

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

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

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

خيارات السجلات الشائعة

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

  • صور الحاويات: Docker Hub، Amazon ECR، Google Artifact Registry، Harbor، أو أي سجل متوافق مع OCI.
  • حزم التطبيقات: Nexus، Artifactory، GitHub Packages، GitLab Package Registry، أو سجلات خاصة بلغة برمجة مثل npm أو PyPI.
  • وحدات البنية التحتية: Terraform Cloud، Git مع وسوم دلالية، أو سجل وحدات مخصص.

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

قائمة مراجعة سريعة لخط الأنابيب الخاص بك

إذا كنت تقوم بإعداد أو مراجعة مرحلة التعبئة والنشر لديك، فراجع هذه النقاط:

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

ماذا بعد ذلك

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

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