إصداراتنا كانت كابوسًا: كيف أنقذتنا أنابيب CI/CD من جحيم ‘شغّال على جهازي’؟

السلام عليكم يا جماعة، معكم أبو عمر.

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

بكل ثقة، رفعنا الملفات على السيرفر عن طريق FTP (نعم، كنا نستخدم FTP في تلك الأيام الغابرة)، وعملنا كم تغيير يدوي على قاعدة البيانات، وأرسلنا إيميل للمدير: “تم التحديث بنجاح!”.

ما مرّت خمس دقايق إلا والتلفون برن. صوت المدير معصّب: “شو اللي عملتوه يا شباب؟ الموقع كله واقع! الشاشة بيضا!”. قلبي وقع في رجلي. كيف يعني واقع؟ قبل شوي كان شغال زي الحلاوة! فتحنا الموقع، وبالفعل، “Internal Server Error”.

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

في هذيك الليلة، وبعد ما حلينا المشكلة ورجع الموقع يشتغل، قعدت مع حالي وحكيت: “مستحيل نكمل هيك. لازم في طريقة أحسن”. ومن هنا بدأت رحلتي، ورحلة فريقي، مع عالم الـ CI/CD، اللي أنقذنا من جحيم “شغّال على جهازي”.

ما هي حكاية الـ CI/CD هذه يا أبو عمر؟

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

هذا بالضبط هو مبدأ الـ CI/CD في عالم البرمجة.

CI: التكامل المستمر (Continuous Integration)

هذا هو الجزء الأول من خط التجميع. بكل بساطة، هو عملية دمج التغييرات البرمجية اللي بيعملها كل مطور في الفريق على نسخة مركزية مشتركة من الكود (زي الـ main branch في Git) بشكل متكرر، ممكن عدة مرات في اليوم.

لكن السحر الحقيقي بصير بعد الدمج مباشرة. هنا، يتدخل “خادم الأتمتة” (زي Jenkins, GitLab CI, GitHub Actions) وبيعمل التالي بشكل آلي:

  • بناء المشروع (Build): بتأكد إنه الكود الجديد ما “كسر” عملية البناء الأساسية.
  • تشغيل الاختبارات (Test): بشغّل كل الاختبارات الآلية (Unit Tests, Integration Tests) عشان يتأكد إنه التغييرات الجديدة ما خربت إشي قديم كان شغال.

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

CD: التسليم أو النشر المستمر (Continuous Delivery/Deployment)

هذا هو الجزء الثاني من خط التجميع. بعد ما الكود ينجح في كل اختبارات الـ CI، بكون جاهز “للشحن”. وهنا في نكهتين من الـ CD:

  • التسليم المستمر (Continuous Delivery): النسخة الجديدة من البرنامج اللي نجحت في كل الاختبارات، يتم تجهيزها ونشرها على بيئة تجريبية (Staging) تشبه بيئة الإنتاج الحقيقية. الإصدار النهائي للعملاء بضل ينتظر “ضغطة زر” يدوية. هذا بيعطي الفريق تحكم نهائي في توقيت الإصدار.
  • النشر المستمر (Continuous Deployment): هاي هي المرحلة المتقدمة. إذا نجحت كل الاختبارات، يتم نشر التحديث تلقائيًا على بيئة الإن
    تاج (Production) بدون أي تدخل بشري. هذا الأسلوب يتطلب ثقة عالية جدًا في الاختبارات الآلية، لكنه بيسرّع عملية التطوير بشكل خيالي.

كيف أنقذتنا هذه “الأنابيب” من جحيم الفوضى؟

لما تبنينا الـ CI/CD، التغيير كان جذري. المشاكل اللي كانت تاخد ساعات وأيام صارت تنحل بدقائق. خليني أحكيلكم الفوائد العملية اللي لمسناها:

وداعًا لعبارة “بس هو شغّال على جهازي!”

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

الثقة والسرعة في الإصدار

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

أخطاء أقل في بيئة الإنتاج

بما إنه كل تغيير بتم اختباره بشكل شامل (وآلي!)، عدد الأخطاء اللي كانت توصل للمستخدمين قل بشكل كبير جدًا. صرنا نكتشف المشاكل في مرحلة التطوير، مش بعد ما العميل يتصل وهو معصّب.

نصيحة من أبو عمر: خط الأتمتة (Pipeline) تبعك قوي بقوة اختباراتك (Tests). إذا اختباراتك ضعيفة أو سطحية، كل اللي بتعمله هو “أتمتة نشر الأخطاء بسرعة”. استثمروا وقت في كتابة اختبارات جيدة وشاملة.

مثال عملي بسيط: أنبوب CI باستخدام GitHub Actions

حتى ما يكون الكلام نظري، تعالوا نشوف مثال بسيط جدًا لمشروع Node.js وكيف ممكن نعمله أنبوب CI أساسي يفحص الكود ويشغل الاختبارات كل ما نعمل `push` على الـ `main branch`.

في مشروعك، أنشئ مجلد اسمه `.github` وبداخله مجلد `workflows`. ثم أنشئ ملف `ci.yml` وضع فيه الكود التالي:


# اسم الأنبوب تبعنا
name: Node.js CI

# متى يتم تشغيل هذا الأنبوب؟
# هنا، عند أي عملية push على فرع main
on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

# المهام التي سيتم تنفيذها
jobs:
  build-and-test:
    # البيئة اللي رح تشتغل عليها المهمة (موحدة للجميع)
    runs-on: ubuntu-latest

    strategy:
      matrix:
        # ممكن نختبر على أكثر من إصدار Node.js للتأكد من التوافقية
        node-version: [16.x, 18.x]

    steps:
      # الخطوة الأولى: جيب الكود من الـ repository
      - name: Checkout repository
        uses: actions/checkout@v3

      # الخطوة الثانية: جهّز بيئة الـ Node.js بالإصدار المحدد
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm' # لتسريع عملية تنزيل المكتبات في المرات القادمة

      # الخطوة الثالثة: نزّل كل المكتبات اللي بيحتاجها المشروع
      - name: Install dependencies
        run: npm install

      # الخطوة الرابعة: شغّل الاختبارات الآلية
      - name: Run tests
        run: npm test

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

نصائح أبو عمر الذهبية للبدء مع CI/CD

  1. ابدأ صغيرًا: لا تحاول أتمتة كل شيء من أول يوم. ابدأ بخطوة بسيطة مثل المثال أعلاه: بناء المشروع وتشغيل الاختبارات الأساسية (Unit Tests). مع الوقت، أضف خطوات أخرى مثل تحليل الكود الثابت (Linting)، اختبارات التكامل، والنشر على بيئة تجريبية.
  2. اجعل الأنبوب سريعًا: هدف الـ CI هو الحصول على تغذية راجعة سريعة. إذا كان الأنبوب تبعك يأخذ ساعة كاملة ليعمل، سيفقد المطورون صبرهم ويتجاهلونه. اعمل على تحسين سرعة الاختبارات واستخدم الـ Caching بذكاء.
  3. عامل “كود الأنبوب” كأنه “كود المشروع”: ملفات الإعداد مثل `ci.yml` يجب أن تكون جزءًا من الـ repository، وتخضع لنفس عملية مراجعة الكود (Code Review) مثل أي كود آخر.
  4. احمِ أسرارك: إياك ثم إياك أن تضع كلمات المرور أو مفاتيح الـ API مباشرة في ملفات الإعداد. كل منصات الـ CI/CD توفر طريقة آمنة لتخزين هذه “الأسرار” (Secrets) واستخدامها في الأنبوب.

الخلاصة يا حبايب 🚀

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

الـ CI/CD ليس ترفًا أو موضة، بل هو ضرورة أساسية في تطوير البرمجيات الحديثة. هو خط الدفاع الأول ضد الأخطاء، وهو المحرك الذي يدفع عجلة التطوير للأمام بثقة وسرعة.

نصيحتي الأخيرة لكم: لا تنتظروا ليلة كارثية مثل ليلتي حتى تقتنعوا. ابدأوا اليوم، ولو بخطوة بسيطة. مستقبلكم كمطورين، ومستقبل مشاريعكم، يعتمد على ذلك. شدوا حيلكم!

أبو عمر

سجل دخولك لعمل نقاش تفاعلي

كافة المحادثات خاصة ولا يتم عرضها على الموقع نهائياً

آراء من النقاشات

لا توجد آراء منشورة بعد. كن أول من يشارك رأيه!

آخر المدونات

أتمتة العمليات

كانت أوامرنا حبيسة الطرفية (Terminal): كيف حررنا عملياتنا بـ ‘ChatOps’ وجعلناها في متناول الجميع؟

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

2 مايو، 2026 قراءة المزيد
​معمارية البرمجيات

كانت خدماتنا جزراً معزولة: كيف أنقذتنا ‘المعمارية القائمة على الأحداث’ من جحيم الاقتران المحكم؟

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

2 مايو، 2026 قراءة المزيد
ذكاء اصطناعي

كان بحثنا عن المعنى أعمى: كيف أنقذتنا ‘قواعد بيانات المتجهات’ من جحيم البحث بالكلمات المفتاحية؟

أنا أبو عمر، وفي هذه المقالة سأشارككم قصة حقيقية عن مشروع كاد أن يفشل بسبب البحث التقليدي، وكيف كانت قواعد بيانات المتجهات (Vector Databases) والبحث...

2 مايو، 2026 قراءة المزيد
تسويق رقمي

ميزانيتنا التسويقية كانت ثقباً أسود: كيف أنقذنا ‘نموذج الإحالة المبني على البيانات’ من جحيم إهدار المال؟

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

2 مايو، 2026 قراءة المزيد
البودكاست