CI/CD: كيف انتقلنا من “إن شاء الله يشتغل” إلى النشر الآلي الموثوق؟

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

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

عملية النشر وقتها كانت “يدوية” بحتة. يعني بفتح الـ terminal، بعمل SSH على السيرفر، بسحب آخر التعديلات من Git بـ git pull، بشغل أمر الـ build يدوي، وبعدين بعمل restart للسيرفر وبقعد أدعي… آه والله، حرفيًا كنت أدعي: “يا رب يشتغل”، “يا رب ما يضرب إشي”، “يا رب ما يرن تلفوني بعد دقيقتين”. كان كل نشر للكود دعاءً وصلاة، وشعور بالقلق كأنه أول يوم امتحان بالجامعة.

في هذيك الليلة المشؤومة، بعد ما ضغطت Enter على أمر الـ restart… الموقع وقع. شاشة بيضاء. العميل بلش يرن، والرسائل على جروب الشغل صارت زي المطر. قضينا الساعتين اللي بعدهم في جحيم حقيقي، بنحاول نكتشف شو المشكلة، ونرجع النسخة القديمة يدويًا. المشكلة طلعت بسيطة جدًا: متغير بيئة (environment variable) ناقص على سيرفر الإنتاج. خطأ بشري بحت، كلفنا سمعتنا، ووقتنا، وأعصابنا.

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

ما هو جحيم “إن شاء الله يشتغل”؟

قبل ما ندخل بالحلول، خلينا نوصف المشكلة اللي كلنا عشناها أو سمعنا عنها. هذا “الجحيم” إله أعراض واضحة:

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

المنقذ: خط أنابيب CI/CD

الـ CI/CD هو اختصار لمصطلحين أساسيين، هما حجر الزاوية في ممارسات الـ DevOps الحديثة. خلونا نبسطهم.

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

ببساطة، هاي الفكرة بتقول إنه كل مطور في الفريق لازم يدمج شغله مع الكود الرئيسي بشكل متكرر، عالأقل مرة باليوم. طيب شو الفائدة؟

الفائدة إنه مع كل عملية دمج، في نظام آلي (سيرفر الـ CI) بيقوم بالتالي:

  1. سحب الكود الجديد: أول ما تعمل push على الـ repository.
  2. بناء المشروع (Build): يتأكد إنه الكود الجديد ما كسر عملية البناء الأساسية.
  3. تشغيل الاختبارات الآلية (Automated Tests): هاي هي النقطة الأهم. بيشغل كل أنواع الاختبارات (Unit, Integration) ليتأكد إنه التغيير الجديد ما خرب إشي قديم.

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

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

هاي هي المرحلة اللي بتيجي بعد الـ CI. بعد ما نتأكد إنه الكود سليم ونجح في كل الاختبارات، شو بيصير؟

  • التسليم المستمر (Continuous Delivery): الكود اللي نجح في كل الاختبارات يتم تجهيزه وتغليفه (كـ Docker image مثلاً) ووضعه في مكان جاهز للنشر على بيئة الإنتاج (Production). عملية النشر نفسها بتضل تحتاج ضغطة زر يدوية. هاي بتعطينا تحكم إضافي، ومناسبة في كثير من الحالات.
  • النشر المستمر (Continuous Deployment): هاي هي الدرجة الأعلى من الأتمتة. إذا نجح الكود في كل مراحل الـ CI، يتم نشره تلقائيًا على بيئة الإنتاج بدون أي تدخل بشري. هاي الطريقة بتحتاج ثقة عالية جدًا في اختباراتك الآلية.

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

رحلتنا العملية لبناء خط الأنابيب: من الفوضى إلى الأتمتة

طيب يا أبو عمر، حكيك حلو، بس كيف أطبق هالكلام؟ خليني أعطيكم خريطة طريق عملية بناءً على تجربتنا.

الخطوة 1: الأساس – Git Flow والانضباط

قبل أي أداة، لازم يكون عندك نظام في الشغل. اتفقنا على استراتيجية بسيطة في Git:

  • main: هذا الفرع يمثل دائمًا الكود الموجود على سيرفر الإنتاج. ممنوع الـ push عليه مباشرة.
  • develop: هذا فرع التطوير الرئيسي.
  • Feature Branches: أي ميزة جديدة أو إصلاح لعلة، بنعمله فرع جديد من develop (مثلاً: feature/user-login). بس يخلص الشغل، بنعمل Pull Request لـ develop.

هذا التنظيم أساسي عشان أدوات الـ CI/CD تعرف متى تشتغل وعلى أي كود.

الخطوة 2: اختيار الأداة المناسبة

في أدوات كثيرة مثل Jenkins, GitLab CI, CircleCI. لكن نصيحتي، إذا كنت بتستخدم GitHub، فابدأ بـ GitHub Actions. ليش؟

  • مدمجة مباشرة في GitHub.
  • سهلة التعلم والبدء.
  • مجانية لحد كبير للمشاريع الخاصة والعامة.

كل اللي بتحتاجه هو إنشاء ملف بامتداد .yml داخل مجلد .github/workflows في مشروعك.

الخطوة 3: أول خط أنابيب (CI)

كان هدفنا الأول بسيط: مع كل push على فرع develop، بدنا نتأكد إنه الكود سليم وبيجتاز الاختبارات. عملنا ملف اسمه ci.yml بهذا الشكل لمشروع Node.js:


# .github/workflows/ci.yml

name: CI Pipeline

# متى يتم تشغيل هذا الـ workflow
on:
  push:
    branches: [ develop ] # يشتغل عند أي push على فرع develop
  pull_request:
    branches: [ develop ] # ويشتغل عند فتح أي pull request على develop

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

    steps:
      # الخطوة 1: سحب الكود من الـ repository
      - name: Checkout code
        uses: actions/checkout@v3

      # الخطوة 2: إعداد بيئة Node.js
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18' # تحديد إصدار Node.js لضمان تطابق البيئات
          cache: 'npm' # لتسريع عملية تنزيل الـ packages في المرات القادمة

      # الخطوة 3: تنزيل الاعتماديات (Dependencies)
      - name: Install dependencies
        run: npm install

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

هذا الملف البسيط كان ثورة بالنسبة لنا. صرنا نعرف فورًا إذا كان الكود الجديد فيه مشكلة، قبل حتى ما يتم دمجه في develop. صار الـ Pull Request هو حارس البوابة.

الخطوة 4: مرحلة التسليم (CD)

بعد ما صار عنا ثقة في مرحلة الـ CI، قررنا نأتمت عملية النشر على السيرفر التجريبي (Staging). الفكرة كانت إنه أي كود يتم دمجه في فرع develop، يتم نشره تلقائيًا على بيئة الـ Staging.

أضفنا job جديد في ملف الـ workflow تبعنا. هذا مثال مبسط جدًا لاستخدام SSH و SCP (في الواقع، هناك طرق أكثر أمانًا مثل استخدام Docker أو actions مخصصة لمزود الخدمة السحابية الخاص بك، لكن هذا المثال يوضح الفكرة):


# ... نفس ملف الـ ci.yml السابق ...

jobs:
  build-and-test:
    # ... نفس الـ job السابق ...

  deploy-to-staging:
    # هذا الـ job لن يعمل إلا بعد نجاح الـ job السابق
    needs: build-and-test
    runs-on: ubuntu-latest
    
    # لا يعمل إلا عند الدمج في فرع develop
    if: github.ref == 'refs/heads/develop' && github.event_name == 'push'

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
          cache: 'npm'

      - name: Install dependencies
        run: npm install

      # خطوة جديدة: بناء المشروع للإنتاج
      - name: Build project
        run: npm run build

      # خطوة جديدة: نشر الملفات على السيرفر
      - name: Deploy to staging server
        uses: appleboy/scp-action@master
        with:
          host: ${{ secrets.STAGING_HOST }}
          username: ${{ secrets.STAGING_USERNAME }}
          key: ${{ secrets.STAGING_SSH_KEY }}
          source: "build/" # المجلد الذي يحتوي على الملفات المبنية
          target: "/var/www/staging-app" # المسار على السيرفر

      # خطوة أخيرة: عمل restart للسيرفر على بيئة الـ staging
      - name: Restart server
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.STAGING_HOST }}
          username: ${{ secrets.STAGING_USERNAME }}
          key: ${{ secrets.STAGING_SSH_KEY }}
          script: 'pm2 restart staging-app' # مثال باستخدام PM2

ملاحظة مهمة: قيم مثل STAGING_HOST و STAGING_SSH_KEY هي معلومات حساسة. لا نكتبها مباشرة في الملف، بل نستخدم ما يسمى بـ GitHub Secrets لتخزينها بشكل آمن.

النتيجة: من الدعاء إلى الثقة

بعد تطبيق هذه المنظومة، تغيرت طريقة عملنا جذريًا:

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

الخلاصة ونصيحة أخيرة 👍

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

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

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

بالتوفيق في رحلتكم من الدعاء إلى الثقة!

أبو عمر

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

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

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

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

آخر المدونات

نصائح برمجية

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

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

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

تحديث المونوليث كجراحة قلب مفتوح: كيف أنقذنا نمط الخانق (Strangler Fig) من جحيم “إياك أن تلمس هذا الكود”؟

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

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

ما وراء الكلمات المفتاحية: كيف حولنا بيانات Schema.org إلى أسلحة سرية في حرب نتائج البحث؟

أنا أبو عمر، مبرمج فلسطيني، وفي هذه المقالة سأشارككم قصة حقيقية حول كيف أنقذنا مشروعًا من الضياع في صفحات جوجل الخلفية باستخدام البيانات المنظمة (Schema.org)....

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

كانت شاشاتنا الفارغة مقبرة للتفاعل: كيف أنقذتنا ‘الحالات الفارغة الذكية’ من جحيم ‘وماذا الآن؟’

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

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

كانت استعلاماتنا تزحف: كيف أنقذتنا فهارس قواعد البيانات من جحيم البحث البطيء؟

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

25 مايو، 2026 قراءة المزيد
الشبكات والـ APIs

من جحيم الـ Polling إلى نعيم الـ Webhooks: كيف أنقذت “خطافات الويب” تطبيقاتنا من السؤال المستمر “هل من جديد؟”

أروي لكم قصة من واقع تجربتي كمبرمج، كيف انتقلنا من طريقة الاستطلاع المستمر (Polling) المرهقة للخوادم، إلى الاعتماد على "خطافات الويب" (Webhooks) الذكية. مقالة عملية...

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