بناء CI/CD Pipeline على غيمة (GitHub Actions + Ghaymah Container Registry)
محتويات
.github/workflows/workflow.yml # الـ workflow الكامل
README.md # هذا التوثيق
1) نظرة عامة على الـ Pipeline
3 مراحل متسلسلة (jobs)، كل مرحلة تعتمد على نجاح ما قبلها:
build-and-push ──▶ deploy-staging ──▶ deploy-production
(بناء + فحص (نشر تلقائي، (⏸ موافقة يدوية
+ رفع للسجل) بدون موافقة) مطلوبة قبل التنفيذ)
- build-and-push: يبني صورة Docker، يشغّلها محليًا داخل الـ runner ويتحقق من
/health(بوابة جودة أساسية) قبل رفعها فعليًا إلى Ghaymah Container Registry. - deploy-staging: ينشر الصورة تلقائيًا على بيئة
stagingفور نجاح البناء — بدون تدخل بشري، لأن الهدف من staging هو تحقق سريع ومستمر. - deploy-production: نفس صورة staging (بدون إعادة بناء) تُنشر على
production، لكن الوظيفة لا تبدأ التنفيذ إلا بعد موافقة يدوية (تفاصيل القسم التالي).
2) الموافقة اليدوية (Manual Approval) قبل الإنتاج
الطريقة المعتمدة في الـ workflow هي GitHub Environments — وهي الآلية الرسمية والموصى بها من GitHub لهذا الغرض (وليس كودًا مخصصًا يفتح "تذكرة" أو ينتظر تعليقًا).
كيفية الإعداد (مرة واحدة فقط، من واجهة المستودع):
- اذهب إلى Settings → Environments في مستودع GitHub.
- أنشئ بيئة باسم
production(يجب أن يطابق الاسم بالضبط ما هو مكتوب فيenvironment: name: productionداخل الـ workflow). - فعّل Required reviewers وأضف الأشخاص أو الفريق المخوّل بالموافقة على نشر الإنتاج (مثال: قائد الفريق التقني أو مسؤول SRE).
- (اختياري لكن موصى به) فعّل Wait timer (مثلاً 0-5 دقائق) كطبقة أمان إضافية، وDeployment branches لتقييد النشر على فرع
mainفقط. - أضف أسرار الإنتاج (Secrets) الخاصة بهذه البيئة تحديدًا (
GHAYMAH_API_TOKENلبيئة production منفصل عن نفس المتغير في staging) — هذا يمنع تسريب صلاحيات الإنتاج حتى لو تم تشغيل job آخر بالخطأ.
كيف يعمل عمليًا
عندما يصل تنفيذ الـ workflow إلى job deploy-production، يتوقف تلقائيًا في حالة "Waiting" ولا تُنفَّذ أي خطوة داخله (بما فيها تسجيل الدخول لـ Ghaymah CLI) حتى يوافق أحد المراجعين المخوّلين من تبويب Actions في GitHub. هذا يضمن أن الكود الذي وصل فعليًا إلى staging وتحقق من صحته هو نفسه الذي يُنشر للإنتاج — دون إعادة بناء، ودون فجوة زمنية تسمح بتغييرات غير مراجعة.
3) الفرق بين بيئة Staging وبيئة Production
| الجانب | Staging | Production |
|---|---|---|
| الغرض | تحقق نهائي قبل الإنتاج: هل يعمل الكود على بنية تحتية شبيهة بالإنتاج؟ | خدمة المستخدمين الفعليين مباشرة |
| آلية النشر | تلقائي بالكامل فور نجاح البناء (CD حقيقي) | يدوي الموافقة، تلقائي التنفيذ بعدها |
| حجم الموارد | أصغر (نسخة واحدة أو نسختان، موارد أقل) لتقليل التكلفة | مطابق للحمل الحقيقي المتوقع، مع auto-scaling فعّال |
| البيانات | بيانات وهمية/مقنّعة (synthetic/masked data)، لا تُستخدم بيانات مستخدمين حقيقية أبدًا | بيانات حقيقية حساسة، تخضع لسياسات الخصوصية والنسخ الاحتياطي |
| حساسية الأسرار (Secrets) | مفاتيح API تجريبية/محدودة الصلاحية | مفاتيح إنتاج كاملة الصلاحية، معزولة تمامًا في GitHub Environment منفصل |
| المراقبة والتنبيهات | مراقبة أساسية (health checks) دون تنبيهات استدعاء (paging) | مراقبة كاملة + تنبيهات فورية (Slack/Page) عند أي شذوذ، حسب سياسات الحادثة الموثقة سابقًا |
| النطاق (Domain) | *-staging.ghaymah.systems أو نطاق فرعي داخلي |
النطاق العام الفعلي للخدمة |
| قابلية إعادة الإنشاء | يمكن إعادة تدميرها وإنشاؤها في أي وقت دون قلق | تغييرات البنية تمر عبر مراجعة/موافقة، أي تعديل مباشر عليها له أثر تشغيلي |
| من يوافق على النشر إليها | لا أحد — تلقائي بالكامل | مراجع مخوّل محدد مسبقًا (Required Reviewer) |
الخلاصة العملية: staging هي "بروفة" مطابقة قدر الإمكان للإنتاج تُستخدم لاكتشاف الأخطاء قبل وصولها للمستخدمين، بينما production هي البيئة الوحيدة التي يُسمح فيها بموافقة بشرية صريحة كحاجز أخير قبل التأثير على المستخدمين الحقيقيين.
4) الربط مع Ghaymah CLI
أ) التثبيت (داخل الـ workflow أو محليًا)
curl -fsSL https://cli.ghaymah.systems/install.sh | sh
ghaymah --version
ملاحظة: عنوان التثبيت وأسماء الأوامر أعلاه مبنية على النمط القياسي لأدوات CLI الخاصة بمنصات الحاويات (deploy/login/logs). يُرجى التأكد من الأمر الدقيق ورابط التثبيت من
docs.ghaymah.cloudأو console الحساب، حيث إن تفاصيل الواجهة قد تختلف عن الأمثلة هنا.
ب) المصادقة (Authentication)
لا تُستخدم بيانات اعتماد شخصية داخل الـ pipeline أبدًا. بدلًا من ذلك:
- يُنشأ API Token مخصص لبيئة CI/CD من لوحة تحكم غيمة (Settings → API Tokens أو ما يعادلها)، بصلاحيات محدودة (نشر/سحب صور فقط، وليس صلاحيات إدارية كاملة).
- يُخزَّن هذا التوكن كسر (Secret) في GitHub:
GHAYMAH_REGISTRY_TOKEN— لتسجيل الدخول لسجل الحاويات (docker/login-action).GHAYMAH_API_TOKEN— لتنفيذ أوامرghaymah deployعبر الـ CLI.
- تسجيل الدخول داخل الـ workflow:
ghaymah auth login --token "$GHAYMAH_API_TOKEN"
ج) الربط مع سجل الحاويات (Container Registry)
تسجيل الدخول لسجل الحاويات يتم عبر الأمر القياسي لـ Docker (متوافق مع أي سجل OCI، بما فيه سجل غيمة):
echo "$GHAYMAH_REGISTRY_TOKEN" | docker login registry.ghaymah.systems \
--username "$GHAYMAH_REGISTRY_USER" --password-stdin
وهذا بالضبط ما يقوم به docker/login-action@v3 المستخدم في الـ workflow، مع الاستفادة من إدارة GitHub الآمنة للأسرار بدل كتابتها في نص الأوامر.
د) أوامر النشر الأساسية
# نشر صورة على خدمة معيّنة (staging أو production حسب --env)
ghaymah deploy --service <service-name> --image <registry>/<namespace>/<image>:<tag> --env <staging|production> --wait
# متابعة سجلات الخدمة بعد النشر
ghaymah logs --service <service-name> --follow
# التحقق من حالة الخدمة والنسخ الحالية
ghaymah status --service <service-name>
# التراجع عن نشر فاشل (Rollback) إلى آخر نسخة مستقرة
ghaymah rollback --service <service-name>
هـ) أفضل الممارسات المطبّقة في هذا الـ Pipeline
- صورة واحدة تنتقل عبر كل البيئات: تُبنى مرة واحدة في
build-and-pushوتُنشر بنفس الوسم (tag) على staging ثم production — لا إعادة بناء بين البيئتين، لضمان أن ما يُختبر هو نفسه ما يُنشر. - فصل الأسرار حسب البيئة: أسرار
stagingمنفصلة تمامًا عن أسرارproductionعبر GitHub Environments، فحتى لو تم اختراق بيئة staging لا يتأثر الإنتاج. - بوابة جودة قبل الرفع: فحص
/healthيتم داخل الـ runner قبل دفع الصورة فعليًا إلى السجل، لتفادي رفع صور معطوبة. - موافقة يدوية = حاجز بشري واحد واضح: بدل انتشار موافقات متفرقة في أدوات متعددة، الموافقة مركزية في نفس واجهة GitHub Actions التي يراقبها الفريق أصلًا.