إصداراتنا كانت كابوسًا: كيف أنقذتنا أنابيب 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 ليس ترفًا أو موضة، بل هو ضرورة أساسية في تطوير البرمجيات الحديثة. هو خط الدفاع الأول ضد الأخطاء، وهو المحرك الذي يدفع عجلة التطوير للأمام بثقة وسرعة.

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

أبو عمر

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

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

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

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

آخر المدونات

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

إشعاراتنا كانت ضجيجاً والمهام تتطلب التنقل بين ألف شاشة: كيف أنقذنا ChatOps من جحيم الفوضى التشغيلية؟

أشارككم تجربتي كـ"أبو عمر"، مبرمج فلسطيني، في تحويل فوضى الإشعارات والتنقل بين الأنظمة إلى بيئة عمل منظمة وفعالة باستخدام ChatOps. اكتشفوا كيف أتمتنا عملياتنا، ووفرنا...

12 أبريل، 2026 قراءة المزيد
نصائح برمجية

شروطنا المتشعبة كانت متاهة: كيف أنقذتنا ‘شروط الحماية’ (Guard Clauses) من جحيم الـ if-else المتداخل؟

هل تعاني من تداخل الشروط في الكود؟ أشاركك قصة حقيقية وكيف غيّرت 'شروط الحماية' (Guard Clauses) طريقة كتابتي للكود، محولةً المتاهات المعقدة إلى مسارات واضحة...

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

خدماتنا كانت متشابكة كخيوط العنكبوت: كيف أنقذتنا ‘المعمارية الموجهة بالأحداث’ (EDA) من جحيم الاعتمادية المباشرة؟

أشارككم قصة حقيقية من تجربتي كـ "أبو عمر" المبرمج، وكيف كانت خدماتنا على وشك الانهيار بسبب التشابك والاعتمادية. اكتشفوا معنا كيف كانت "المعمارية الموجهة بالأحداث"...

12 أبريل، 2026 قراءة المزيد
ذكاء اصطناعي

قرارات نموذجنا كانت صندوقاً أسود: كيف أنقذتنا تقنيات التفسير (XAI) من جحيم التنبؤات الغامضة؟

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

12 أبريل، 2026 قراءة المزيد
خوارزميات

قاعدة بياناتنا كانت تستغيث: كيف أنقذنا ‘فلتر بلوم’ من جحيم التحقق المكلف من وجود العناصر؟

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

12 أبريل، 2026 قراءة المزيد
تجربة المستخدم والابداع البصري

تطبيقنا كان حصناً منيعاً: كيف أنقذتنا ‘معايير الوصول الرقمي (WCAG)’ من جحيم الإقصاء الرقمي؟

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

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