من الفكرة إلى الكود: الخطوة الأولى في توصيل البرمجيات

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

يكتب المطور، يختبر، يعدل، ويشاهد المخرجات على شاشته الخاصة. كل شيء يعمل. يظهر الزر في المكان المفترض. يتم تحميل البيانات بشكل صحيح. الميزة تؤدي ما هو مطلوب منها.

هذا يبدو تقدماً. وهو كذلك بالفعل. لكن الكود الذي يعمل على لابتوب ليس جاهزاً بعد للنشر.

فخ البيئة المحلية

عندما يعيش الكود فقط على جهاز المطور، فإنه يعمل في فقاعة. المكتبات المثبتة، إصدار نظام التشغيل، إعدادات قاعدة البيانات، وحتى أرقام المنافذ — كل هذه خاصة بذلك اللابتوب الواحد. مطور آخر في نفس الفريق قد يكون لديه Python 3.11 بينما لديك 3.10. قد يستخدم PostgreSQL 15 بينما تستخدم 14. إصدار Node الخاص به قد يكون مختلفاً. مسارات ملفاته مختلفة بالتأكيد.

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

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

كتابة كود يسافر

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

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

على سبيل المثال، مشروع Node.js يعلن تبعياته في ملف package.json كالتالي:

{
  "name": "my-app",
  "version": "1.0.0",
  "dependencies": {
    "express": "4.18.2",
    "pg": "8.11.3",
    "lodash": "4.17.21"
  },
  "devDependencies": {
    "jest": "29.7.0",
    "eslint": "8.56.0"
  }
}

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

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

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

من المحلي إلى المشترك

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

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

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

الفجوة بين الكود العامل والكود القابل للنشر

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

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

قائمة تحقق عملية قبل دفع الكود

قبل أن تدفع تغييرك التالي إلى المستودع المشترك، قم بهذا الفحص السريع:

  • هل جميع التبعيات مسجلة في ملف إعدادات يمكن تثبيته تلقائياً؟
  • هل القيم الخاصة بالبيئة (عناوين قواعد البيانات، مفاتيح API، المسارات) منفصلة عن الكود؟
  • هل يحتوي الـ commit على تغيير منطقي واحد، مع تضمين جميع الملفات ذات الصلة؟
  • هل تشرح رسالة الـ commit ما الذي تغير ولماذا؟
  • هل قمت بتشغيل الكود في بيئة نظيفة تطابق ما سيستخدمه الخادم؟

إذا كان بإمكانك الإجابة بنعم على جميع الخمسة، فإن الكود جاهز لمغادرة لابتوبك.

ما يأتي بعد ذلك

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

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