من النشر اليدوي إلى التسليم المستمر: دليلك العملي لبناء أول خط أنابيب CI/CD باستخدام GitHub Actions

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

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

العملية كانت يدوية بحتة: نضغط الملفات، نرفعها على السيرفر عن طريق الـ FTP، وبعدين نفك الضغط، ونعمل نسخة احتياطية من قاعدة البيانات يدوياً، وبعدها ندعي ربنا إنه كل شي يشتغل تمام. وفي مرة من المرات، بعد سهرة طويلة من الشغل، رفعنا كل شي… إلا ملف واحد! ملف JavaScript صغير بس مهم. طبعاً الموقع “ضرب” وما اشتغل. تخيلوا الموقف الساعة 3 الفجر، والزبون بده يفتح الموقع الصبح. يا زلمة، كانت أيام بتجيب الجلطة. قعدنا ندور زي المجانين على المشكلة، وكمية التوتر والقلق اللي عشناها بهذيك الليلة ما بنساها.

هذيك الأيام ولّت وراحت، والحمد لله. اليوم، بفضل الله ثم بفضل أدوات مثل الـ CI/CD، صارت عملية النشر بكبسة زر، وإنت متطمن ومرتاح. في هاي المقالة، بدي آخذ بإيدكم، خطوة بخطوة، ونبني مع بعض أول خط أنابيب (Pipeline) خاص فيكم باستخدام GitHub Actions، عشان ترتاحوا من وجع الراس اللي عشناه زمان.

ما هو الـ CI/CD؟ مصطلحات لا بد من فهمها

قبل ما نخوض في التفاصيل التقنية، خلينا نفهم شو يعني CI/CD. هاي مش مجرد كلمة طنانة بنسمعها في عالم البرمجة، هاي منهجية عمل بتغير طريقة تفكيرك وشغلك تماماً.

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

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

  • بناء المشروع (Build): التأكد من أن الكود يمكن تجميعه بدون أخطاء.
  • تشغيل الاختبارات (Testing): تنفيذ اختبارات الوحدة (Unit Tests) واختبارات التكامل (Integration Tests) للتأكد من أن التغييرات الجديدة ما كسرت أي شي في النظام.

الهدف الأساسي من الـ CI هو اكتشاف المشاكل والأخطاء في مرحلة مبكرة جداً. بدل ما تستنى لآخر المشروع عشان تكتشف إنه كود فلان ما بيشتغل مع كود علان، بتكتشف المشكلة فوراً بعد دمج الكود. “مشاكل أولها، حلها أسهل”.

التسليم المستمر (Continuous Delivery – CD)

هنا بننتقل للمرحلة التالية. بعد ما نتأكد من خلال الـ CI إن الكود سليم وجاهز، بيجي دور التسليم المستمر. في هاي المرحلة، بيتم تجهيز الكود تلقائياً ليكون جاهزاً للنشر في أي لحظة.

العملية تتضمن بناء حزمة النشر (Release Artifact)، ونقلها إلى بيئة اختبار شبيهة بالبيئة الحقيقية (Staging Environment)، وإجراء اختبارات قبول (Acceptance Tests) عليها. النتيجة النهائية هي حزمة برمجية تم اختبارها وجاهزة للنشر على البيئة الحقيقية (Production) بضغطة زر واحدة.

نقطة مهمة: في التسليم المستمر، النشر على البيئة الحقيقية لا يزال يتطلب تدخلاً يدوياً (كبسة زر)، لكن كل الخطوات التي تسبقه مؤتمتة بالكامل.

النشر المستمر (Continuous Deployment – CD)

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

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

لماذا GitHub Actions؟

هناك أدوات كثيرة للـ CI/CD مثل Jenkins, GitLab CI, CircleCI. لكن ليش أنا شخصياً بفضل وأنصح بـ GitHub Actions، خصوصاً للمبتدئين والمشاريع الجديدة؟

  • متكاملة مع GitHub: الأداة موجودة في قلب GitHub. ما في داعي تروح على منصة ثانية أو تعمل تكاملات معقدة. كل شي بصير في مكان واحد.
  • مجتمع ضخم وسوق (Marketplace): هناك آلاف الإجراءات (Actions) الجاهزة اللي عملها المجتمع، واللي بتقدر تستخدمها عشان تنفذ أي مهمة ممكن تخطر في بالك، من نشر موقع على سيرفر، إلى إرسال إشعار على Slack.
  • سخاء في الخطة المجانية: الخطة المجانية لـ GitHub بتعطيك 2000 دقيقة شهرياً من وقت التشغيل، وهذا أكثر من كافٍ للمشاريع الشخصية والفرق الصغيرة.
  • سهولة الإعداد: كل ما تحتاجه هو ملف بصيغة YAML تضيفه لمشروعك. هاي الصيغة سهلة القراءة والكتابة، والملف نفسه بيكون جزء من مستودع الكود، يعني بتقدر تتبع التغييرات اللي بتصير عليه.

بناء أول خط أنابيب CI/CD: دليل عملي

يلا نشتغل! خلينا نبني مع بعض خط أنابيب بسيط لمشروع Node.js. هذا الخط سيقوم بالتالي:

  1. عند كل عملية `push` لفرع `main`، سيعمل تلقائياً.
  2. سيقوم بتثبيت الاعتماديات (Dependencies).
  3. سيقوم بتشغيل الاختبارات (Tests).
  4. إذا نجحت الاختبارات، سيقوم بنشر الموقع (كمثال، سننشر صفحة بسيطة على GitHub Pages).

الخطوة الأولى: فهم مصطلحات GitHub Actions

قبل ما نكتب الكود، خلينا نتعرف على شوية مصطلحات:

  • Workflow (سير العمل): هو العملية المؤتمتة بأكملها. يتم تعريفها في ملف YAML واحد.
  • Event (حدث): هو الشيء الذي ي déclenche (يشغّل) الـ workflow. ممكن يكون `push`، `pull_request`، أو حتى جدول زمني.
  • Job (مهمة): هو مجموعة من الخطوات (Steps) التي تعمل على نفس الخادم (Runner). يمكن أن يكون لديك عدة مهام تعمل بالتوازي أو بالتسلسل.
  • Step (خطوة): هي أصغر وحدة في الـ Job. يمكن أن تكون أمرًا في سطر الأوامر (مثل `npm install`) أو إجراءً جاهزًا (Action).
  • Action (إجراء): هو كود جاهز قابل لإعادة الاستخدام لتنفيذ مهمة معينة (مثل `actions/checkout` لجلب الكود).
  • Runner (مشغّل): هو الخادم الذي سيقوم بتشغيل الـ workflow الخاص بك. GitHub يوفر مشغّلات جاهزة (Ubuntu, Windows, macOS).

الخطوة الثانية: إنشاء ملف الـ Workflow

في مستودع الكود الخاص بك على GitHub، قم بإنشاء مجلد جديد اسمه `.github` وبداخله مجلد آخر اسمه `workflows`. داخل هذا المجلد، أنشئ ملفًا جديدًا وسمّه `main.yml` (أو أي اسم آخر ينتهي بـ `.yml`).

هذا هو الهيكل الأساسي لملفنا:


# اسم الـ Workflow اللي بيظهر في واجهة GitHub
name: CI/CD Pipeline for Node.js App

# الأحداث اللي بتشغل الـ Workflow
on:
  # شغّل الـ Workflow عند أي push على فرع main
  push:
    branches: [ main ]
  # وشغّله أيضاً عند فتح Pull Request على فرع main
  pull_request:
    branches: [ main ]

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

    # الخطوات (Steps) اللي راح تتنفذ في هاي المهمة
    steps:
      # الخطوة الأولى: جلب الكود من المستودع
      # هاي Action جاهزة من GitHub
      - name: Checkout repository
        uses: actions/checkout@v3

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

      # الخطوة الثالثة: تثبيت الاعتماديات
      - name: Install dependencies
        run: npm install

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

بمجرد حفظ هذا الملف وعمل `push` له، اذهب إلى تبويب “Actions” في مستودعك على GitHub، وستجد أن الـ workflow قد بدأ بالعمل تلقائياً. مبروك، لقد أنجزت جزء الـ CI بنجاح!

الخطوة الثالثة: إضافة النشر التلقائي (CD)

الآن، بعد أن تأكدنا من أن الكود سليم ويعمل، نريد نشره. سنضيف مهمة (Job) جديدة اسمها `deploy` لنشر موقعنا على GitHub Pages.

أولاً، تأكد من إعداد GitHub Pages لمستودعك من خلال الإعدادات (Settings -> Pages -> Source -> GitHub Actions).

الآن، سنقوم بتعديل ملف `main.yml` ليبدو كالتالي:


name: CI/CD Pipeline for Node.js App

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        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

      # خطوة وهمية لبناء الموقع، استبدلها بأمر البناء الحقيقي لمشروعك
      # مثلاً: npm run build
      - name: Build static site
        run: |
          mkdir public
          echo "

Hello from Abu Omar's CI/CD!

Deployed at $(date)

" > public/index.html # رفع ملفات البناء كـ Artifact لتستخدمها مهمة النشر - name: Upload build artifact uses: actions/upload-artifact@v3 with: name: github-pages path: ./public # المهمة الثانية: النشر deploy: # تحديد أن هذه المهمة تعتمد على نجاح المهمة السابقة needs: build-and-test # إعدادات خاصة بالنشر على GitHub Pages permissions: pages: write id-token: write environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest # شرط: لا تقم بالنشر إلا إذا كان التغيير على فرع main مباشرة if: github.ref == 'refs/heads/main' steps: - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v2

شرح التغييرات:

  1. أضفنا خطوة `Build static site` التي تقوم بإنشاء ملفات الموقع. في مشروع حقيقي، ستكون هذه `npm run build` أو ما شابه.
  2. استخدمنا `actions/upload-artifact` لحفظ مخرجات البناء (ملفات الموقع) مؤقتاً.
  3. أضفنا مهمة جديدة `deploy`.
  4. باستخدام `needs: build-and-test`، أخبرنا GitHub بأن لا يبدأ مهمة النشر إلا بعد نجاح مهمة البناء والاختبار.
  5. أضفنا `permissions` و `environment` وهي إعدادات ضرورية للنشر الآمن على GitHub Pages.
  6. استخدمنا `if: github.ref == ‘refs/heads/main’` كشرط أمان مهم، وهو يعني: “لا تقم بتنفيذ هذه المهمة إلا إذا كان الـ `push` قد تم على فرع `main` مباشرة”. هذا يمنع النشر عند العمل على فروع أخرى.
  7. استخدمنا `actions/deploy-pages@v2` وهو الإجراء الرسمي والحديث من GitHub لنشر المحتوى الذي تم رفعه كـ Artifact.

الآن، في كل مرة تقوم بعمل `push` لفرع `main`، سيتم بناء الكود، اختباره، ثم نشره تلقائياً على GitHub Pages. كل هذا وأنت تشرب فنجان قهوتك!

نصائح من خبرة أبو عمر

  • ابدأ بسيطًا، ثم تعقّد: لا تحاول أتمتة كل شيء من اليوم الأول. ابدأ بخط أنابيب بسيط يقوم بالبناء والاختبار فقط. عندما تشعر بالراحة، أضف خطوات أخرى مثل النشر، إرسال الإشعارات، إلخ.
  • الأسرار (Secrets) هي صديقك: إياك ثم إياك أن تضع أي مفاتيح API أو كلمات مرور أو أي معلومات حساسة مباشرة في ملف الـ YAML. استخدم دائمًا “GitHub Secrets” (موجودة في Settings -> Secrets and variables -> Actions). يمكنك الوصول إليها في الـ workflow بهذا الشكل: `${{ secrets.YOUR_SECRET_NAME }}`.
  • استخدم الكاش (Cache) بذكاء: عمليات مثل `npm install` يمكن أن تكون بطيئة. استخدم `actions/cache` أو الخيار المدمج في `actions/setup-node` لتخزين الاعتماديات. هذا سيسرع من عمل الـ workflow بشكل ملحوظ في المرات القادمة.
  • اجعل مهامك مستقلة: حاول تصميم كل مهمة (Job) لتقوم بشيء واحد ومحدد. هذا يسهل عملية تصحيح الأخطاء ويسمح لك بتشغيل المهام بالتوازي لتسريع العملية الكلية.
  • لا تخف من الفشل: أول خط أنابيب ستكتبه سيفشل، والثاني أيضاً، وربما الثالث. هذا طبيعي جداً. اقرأ سجلات الأخطاء (Logs) التي يوفرها GitHub بعناية، فهي مفصلة جداً وستدلك على مكان المشكلة.

الخلاصة: ارتقِ بعملك، وليس بضغطك 🧘‍♂️

الانتقال من النشر اليدوي إلى الأتمتة الكاملة مع CI/CD ليس مجرد ترف تقني، بل هو استثمار في راحة بالك، وفي جودة منتجك، وفي سرعة فريقك. لقد رأينا كيف يمكن باستخدام أداة مجانية وقوية مثل GitHub Actions تحويل عملية النشر من كابوس مليء بالتوتر إلى عملية تلقائية، موثوقة، ومملة (بالمعنى الإيجابي!).

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

أتمنى لكم كل التوفيق في رحلتكم مع الأتمتة. بالتوفيق يا شباب! 🚀

أبو عمر

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

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

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

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

آخر المدونات

نصائح برمجية

كانت بياناتنا مجرد أرقام ونصوص: كيف أنقذتنا الكائنات القيمية (Value Objects) من جحيم الأخطاء الصامتة؟

أشارككم قصة من قلب المعركة البرمجية، كيف كاد خطأ بسيط بسبب البيانات العشوائية أن يكلفنا الكثير. سنتعلم معًا كيف تنقذنا "الكائنات القيمية" (Value Objects) من...

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

كان كل زر في تطبيقنا قصة مختلفة: كيف أنقذنا ‘نظام التصميم’ (Design System) من جحيم الفوضى البصرية؟

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

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

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

أشارككم قصة حقيقية عن كارثة بيانات كادت أن تدمر مشروعنا، وكيف كانت 'معاملات قاعدة البيانات' (Transactions) ومبادئ ACID هي طوق النجاة. تعلم كيف تحمي تطبيقاتك...

16 مايو، 2026 قراءة المزيد
الحوسبة السحابية

كانت فاتورة السحابة تلتهم ميزانيتنا: كيف أنقذتنا استراتيجيات FinOps من جحيم الإنفاق الضائع؟

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

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