الملفات
ghaymah-exam-Moataz-Gamal-H…/q3-cicd/README.md
2026-07-28 11:28:37 +00:00

14 KiB

Ghyma CI/CD Demo

رابط المشروع : https://mywebapp-prod-13c5436cf063.hosted.ghaymah.systems/

⚠️ تحديث مهم: النسخة دي معدّلة بناءً على توثيق رسمي حقيقي من Ghaymah. المنصة لسه معندهاش CLI ("coming soon, inshallah") ولا auto-trigger عند push. النشر الفعلي يدوي بالكامل من لوحة التحكم.


إيه اللي الـ pipeline بيعمله فعليًا (وإيه اللي لسه يدوي)

المرحلة مؤتمتة؟
بناء صورة Docker أوتوماتيك (GitHub Actions)
فحص سريع (smoke test) على /health أوتوماتيك
موافقة يدوية قبل production أوتوماتيك (عن طريق GitHub Environments)
النشر الفعلي على Ghaymah يدوي — تدخل لوحة التحكم وتحط Commit SHA بنفسك

يعني الـ workflow مش هينشر لوحده — هو هيبني الصورة، يتأكد إنها شغالة، ويطبعلك بالظبط "انسخ الـ SHA ده وحطه في تطبيق كذا". لما Ghaymah تطلق الـ CLI بتاعها، هنضيف خطوة أخيرة تلقائية بدل النسخ اليدوي.


الخطوة 0: المتطلبات

  • Docker Desktop
  • حساب GitHub
  • حساب Docker Hub
  • حساب على Ghaymah Cloud

الخطوة 1: التجربة المحلية

npm install
npm start

افتح http://localhost:3000/ و /health و /version.

الخطوة 2: التجربة بالـ Docker

docker build -t ghyma-cicd-demo:local .
docker run -d -p 3000:3000 --name ghyma-demo ghyma-cicd-demo:local
curl http://localhost:3000/health
docker stop ghyma-demo && docker rm ghyma-demo

الخطوة 3: رفع المشروع على GitHub

git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/Moetaz-Alfy/ghyma-cicd-demo.git
git push -u origin main
git checkout -b develop
git push -u origin develop

الخطوة 4: أضف Secrets للـ Registry في GitHub

هذه الخطوة تحقق شرط "الرفع لـ Registry" في متطلبات المهمة حرفيًا. Docker Hub هنا بيشتغل كبديل مؤقت لحد ما Ghaymah تطلق Container Registry خاص بيها — التفاصيل في قسم "ملاحظة عن خطوة الـ Registry" آخر الملف.

Settings → Secrets and variables → Actions → New repository secret
الاسم القيمة
DOCKERHUB_USERNAME اسم مستخدمك على Docker Hub
DOCKERHUB_TOKEN Access Token من Docker Hub (Account Settings → Security → New Access Token)

الخطوة 5: فعّل بيئة production بموافقة يدوية

Settings → Environments → New environment → production

فعّل Required reviewers واختار نفسك.

شرح آلية عمل الموافقة اليدوية بالتفصيل

الـ job اسمه notify-production في ci-cd.yml مربوط بالسطر ده:

environment:
  name: production

لما GitHub تلاقي job مربوط بـ Environment اسمه production وعليه Required reviewers مفعّلة، بيحصل الآتي تلقائيًا:

  1. الـ job بيوصل لكل الخطوات اللي قبله عادي (بناء الصورة، الـ smoke test، الرفع للـ Registry) — دي مش متأثرة بالموافقة خالص
  2. لما الدور يجي على notify-production نفسه، GitHub بيوقفه فورًا قبل أول خطوة جواه، وبيحطه في حالة "Waiting"
  3. المراجع (Reviewer) المحدد بياخد إشعار على GitHub (وبالإيميل لو مفعّل)، ويشوف في تاب Actions زرار "Review deployments"
  4. المراجع بيقدر يشوف تفاصيل الـ commit والـ diff قبل ما يوافق
  5. لو ضغط Approve and deploy → الخطوات جوه الـ job تشتغل فعليًا
  6. لو ضغط Reject → الـ job بيتوقف نهائيًا وميطبعش أي تعليمات نشر

ليه الميزة دي مهمة تحديدًا هنا؟ لأن Ghaymah نفسها معندهاش نظام موافقات داخلي (النشر عندها مجرد حقل تكتب فيه SHA وتضغط Save، من غير أي حماية). فالموافقة اليدوية دي بتتم بالكامل على مستوى GitHub قبل ما تصل أصلاً لمرحلة "انسخ الـ SHA والصقه في Ghaymah" — يعني حتى لو حد عنده وصول للوحة تحكم Ghaymah، هو مش هياخد SHA صحيح للنشر إلا بعد ما تتم الموافقة على GitHub الأول.

فرق مهم عن staging: لاحظ إن job الـ notify-staging مالهوش سطر environment: name، فهو بيشتغل فورًا من غير أي وقفة — ده الفرق الجوهري بين البيئتين في نظام الأتمتة نفسه.

الخطوة 6: أنشئ المشروع والتطبيقين على Ghaymah (مرة واحدة فقط)

  1. سجّل دخول على لوحة تحكم Ghaymah
  2. أنشئ Project جديد (مثلاً ghyma-cicd-demo)
  3. جوه المشروع، اعمل Deploy Application الأول:
    • Deployment method: Git-Based Deployment → Deploying from Public GitHub
    • Application Name: ghyma-demo-prod
    • Repository URL: رابط الريبو بتاعك
    • Branch/Commit SHA: أول commit على main
    • Port: 3000
    • Environment Variables: APP_ENV=production
  4. اعمل Deploy Application ثاني بنفس الريبو:
    • Application Name: ghyma-demo-staging
    • Repository URL: نفس الريبو
    • Branch/Commit SHA: أول commit على develop
    • Port: 3000
    • Environment Variables: APP_ENV=staging

الآن عندك تطبيقين منفصلين تمامًا (نفس الكود، بيانات وبيئة مختلفة).

الخطوة 7: التجربة الكاملة للـ pipeline

git checkout develop
git commit --allow-empty -m "test staging pipeline"
git push

روح لتاب Actions → هتلاقي build-and-push ثم notify-staging بيطبع الـ commit SHA.

انسخ الـ SHA ده، روح للوحة تحكم Ghaymah → طبّق التطبيق ghyma-demo-staging → الصق الـ SHA في حقل Branch/Commit → Save.

الخطوة 8: نشر production (بالموافقة)

git checkout main
git merge develop
git push

في تاب Actions، notify-production هيقف وينتظر موافقتك (Review deployments → Approve and deploy). بعد الموافقة، هيطبعلك الـ SHA.

انسخه، وحطه في تطبيق ghyma-demo-prod على لوحة تحكم Ghaymah → Save.


الفرق بين staging و production على Ghaymah تحديدًا

المحور Staging Production
اسم التطبيق في Ghaymah ghyma-demo-staging ghyma-demo-prod
الفرع المتابَع develop main
موافقة قبل تحديث الـ SHA لا (الأمر يطبع فورًا) نعم (GitHub Environment)
متغير APP_ENV staging production
من يحدّث SHA فعليًا إنت، يدويًا، بعد كل push على develop إنت، يدويًا، بعد الموافقة فقط

ليه فصلناهم كتطبيقين منفصلين تمامًا بدل بيئة واحدة بمتغيرات مختلفة؟

في منصات تانية (زي Heroku أو AWS) ممكن "البيئة" تكون مجرد إعداد داخل نفس التطبيق. لكن بما إن Ghaymah بتنشر مباشرة من الكود في GitHub (Git-Based Deployment)، كل "Application" في لوحة تحكمها هي فعليًا:

  • نسخة مبنية بشكل مستقل من commit معين
  • عندها رابط عام خاص بيها (Public URL) منفصل تمامًا
  • عندها Environment Variables خاصة بيها
  • بتنشر وتنطفي بشكل مستقل عن أي تطبيق تاني

فبالتالي أنسب طريقة لعمل "بيئتين" على Ghaymah هي إنشاء تطبيقين منفصلين فعليًا، مش تطبيق واحد بيتغيّر سلوكه — وده اللي بيضمن إن أي تجربة أو فشل في staging مستحيل يأثر على production، لأنهم فعليًا حاويتين مختلفتين تمامًا وليهم رابط مختلف.

الفرق العملي وقت الاستخدام اليومي

  • تعمل تعديل وعايز تجربه بسرعة؟ ادفع على develop → SHA بيتطبع فورًا → تحطه في ghyma-demo-staging → تجربه على رابط staging المنفصل من غير أي انتظار
  • متأكد إن التعديل شغال ومستعد ينزل للمستخدمين؟ ادمج (merge) develop في main → لازم موافقة يدوية قبل ما تاخد الـ SHA أصلاً → تحطه في ghyma-demo-prod

القاعدة العامة: أي كود بيوصل لـ production لازم يكون مر فعليًا من staging الأول بنفس الآلية بالظبط — نفس الـ Dockerfile، نفس خطوات الـ CI، الفرق الوحيد هو أي بيئة بتستقبل الكود ومين بيوافق قبلها.


الربط مع Ghaymah CLI — الوضع الحقيقي

Ghaymah لا توفر CLI في الوقت الحالي. النص الرسمي:

"Ghaymah Cloud currently does not have automatic build triggers based on Git commits. Deployments must be manually triggered, or integrated with a CI/CD platform using our CLI (coming soon, inshallah)."

يعني:

  • مفيش أوامر ghaymah login أو ghaymah deploy تقدر تستخدمها دلوقتي
  • الطريقة الوحيدة المتاحة حاليًا هي Git-Based Deployment من لوحة التحكم مباشرة، مع تحديث يدوي لحقل الـ Commit SHA/Tag لكل تطبيق
  • لما الـ CLI يتطلق، هيبقى ممكن نستبدل خطوة notify-staging/notify-production (اللي بتطبع تعليمات بس) بخطوة فعلية زي ghaymah deploy --app ghyma-demo-prod --sha <SHA> تلقائيًا

إزاي الـ workflow اتصمم عشان "يربط" مع Ghaymah رغم غياب الـ CLI؟

بما إن مفيش API أو CLI نقدر نناديه، الـ workflow بيعمل أقصى حاجة ممكنة أوتوماتيكيًا وبيسيب الجزء المستحيل أتمتته (تحديث حقل الـ SHA في واجهة Ghaymah نفسها) كخطوة يدوية واحدة بس، موثقة بدقة:

- name: Print deployment instructions
  run: |
    echo "Ghaymah dashboard -> Application: mywebapp-prod"
    echo "Set Branch/Commit SHA field to: ${{ needs.build-and-push.outputs.commit_sha }}"

الخطوة دي مش مجرد رسالة عشوائية — هي بديل مؤقت لأمر CLI مستقبلي. لاحظ إن اسم التطبيق والـ SHA بييجوا من متغيرات ديناميكية (needs.build-and-push.outputs.commit_sha)، يعني لو غيرت اسم التطبيق أو استخدمت فروع تانية، الرسالة بتتحدث تلقائيًا من غير أي تعديل يدوي في الكود.

خطة الترقية لما الـ CLI يطلق فعليًا

دلوقتي (يدوي) بعد إطلاق CLI (أوتوماتيكي)
نسخ الـ SHA من طباعة الـ workflow استدعاء ghaymah login --token $TOKEN
فتح لوحة تحكم Ghaymah يدويًا استدعاء ghaymah deploy --app <name> --sha <SHA> مباشرة داخل الـ job
الضغط يدويًا على Save الأمر نفسه بيرجع exit code يوضح نجاح/فشل النشر فورًا داخل GitHub Actions

التصميم الحالي مبني عمدًا بحيث التحويل يوم ما الـ CLI يتوفر يكون تغيير بسيط (استبدال خطوة Print deployment instructions بخطوة ghaymah deploy فعلية) من غير أي إعادة هيكلة للـ pipeline بالكامل.

أفضل ممارسات لحد ما الـ CLI يتوفر

  • ثابت على تسمية واضحة للتطبيقات (-prod, -staging) لتفادي الغلط وقت تحديث الـ SHA يدويًا
  • استخدم متغيرات بيئة مختلفة تمامًا بين البيئتين (خصوصًا أي مفاتيح API أو روابط قواعد بيانات)
  • وثّق كل SHA اتنشر فعليًا على production (تقدر تستخدم GitHub Releases أو Tags لده)

ملاحظة عن خطوة الـ Registry (شفافية كاملة)

متطلبات المهمة الأصلية بتطلب "رفع الصورة إلى ghaymah Container Registry". حاليًا Ghaymah لا توفر Container Registry عام — النشر بيتم عن طريق Git-Based Deployment فقط (البند اللي فوق). خطوة الـ docker push في الـ workflow بترفع فعليًا على Docker Hub كبديل مؤقت، عشان:

  1. تستوفي شرط "بناء ورفع الصورة لريجستري" في المهمة حرفيًا
  2. تدي نسخة موثقة ومؤرشفة من كل صورة (بالـ commit SHA) تقدر ترجعلها وقت الحاجة
  3. تبقى جاهزة تتحول لـ Ghaymah Registry الحقيقي بمجرد ما يتوفر (تغيير قيمة REGISTRY في الـ workflow بس)

النشر الفعلي على Ghaymah مش معتمد على الخطوة دي — بيعتمد فقط على تحديث الـ Commit SHA في لوحة التحكم زي ما هو موضح في الخطوتين 7 و 8.