مشكلة SFTP والنشر اليدوي
النشر بسحب الملفات عبر SFTP هو ما يجعل المواقع تنتهي معطوبة نصفيًا: يُنسى ملف، ولا يُشغَّل composer، ويُغفَل ترحيل، ويظل التخزين المؤقت يقدّم الحزمة القديمة. لا سجل لما نُشر ولا طريقة نظيفة لإعادة إنتاجه. يستبدل النشر عبر GitHub ذلك بخط أنابيب محدد مرتبط بمستودعك، فيصبح الإصدار نتيجة حتمية لالتزام (commit) مضافًا إليه مجموعة ثابتة من الخطوات — الشيء نفسه في كل مرة، ومن أي فرد في الفريق.
خطوات البناء لديك، تُشغَّل باتساق
النشر الحقيقي أكثر من نسخ ملفات: يجب تثبيت الاعتماديات، وترجمة الأصول، وتطبيق ترحيلات قاعدة البيانات بالترتيب الصحيح. تُعرّف تلك الخطوات مرة واحدة — مثل composer install، وبناء npm أو الأصول، وأمر ترحيل — وتُشغَّل في كل نشر مقابل الالتزام المحدد الذي يُطلق. يقضي هذا على صنف كامل من الأخطاء حيث يتصرف الإنتاج بشكل مختلف لأن أحدهم شغّل الخطوات بترتيب مختلف أو تخطّى إحداها تحت الضغط.
النشر اليدوي والنشر التلقائي عبر webhook
تريد الفرق المختلفة محفّزات مختلفة. يُبقي الفريق الحذِر النشر يدويًا، بالنقر على زر النشر في اللوحة بعد المراجعة، ليكون الإصدار فعلًا مقصودًا. أما الفريق سريع الحركة فيفعّل الـ webhook بحيث يُنشر كل دفع إلى فرع الإنتاج تلقائيًا، محوّلًا git push إلى نشر. كلاهما يشغّل خط الأنابيب نفسه؛ والفارق الوحيد هو ما يسحب الزناد، ويمكنك البدء يدويًا وتفعيل الـ webhook حالما تثق بالسير.
المستودعات الخاصة والرموز الآمنة
معظم الشيفرة الحقيقية في مستودعات خاصة، لذا تصادق المنصة برمز تقدّمه أنت بدلًا من اشتراط أن تكون الشيفرة عامة. يُخزَّن الرمز كسر ويُستخدم فقط للاستنساخ وقت النشر؛ ولا يظهر في السجلات أو الواجهة بعد حفظه، ولأنه منفصل عن شيفرتك يمكنك تدويره أو إبطاله باستقلالية. تُتحقَّق تسليمات الـ webhook بسر موقّع كي لا يستطيع طلب POST عشوائي إطلاق إصدار.
الـ purge التلقائي يسدّ الثغرة الأخيرة
أشيع خطأ بعد النشر هو إصدار جديد مخفي خلف تخزين مؤقت قديم على الحافة — CSS أو JS جديد نُشر، لكن الزوار لا يزالون يحمّلون الحزمة القديمة المخزّنة. ينفّذ النشر عبر GitHub عملية purge للتخزين المؤقت على الحافة كجزء من الإصدار، فلا يُعدّ النشر منتهيًا حتى يعكس التخزين المؤقت الملفات الجديدة. يزيل هذا خطوة المسح اليدوي التي ينساها الناس، ويعني أن ما نشرته هو ما يتلقاه الزوار فعلًا.
تسليم قابل للتكرار للفرق والوكالات
حين يُنشر كل مشروع بالطريقة نفسها، يكفّ الإعداد والتسليم عن كونه معرفة قبلية. تظهر حالة النشر ووقت آخر نشر والخطوات المُعدّة في اللوحة، فيستطيع أي شخص رؤية ما إذا كان آخر دفع قد وصل إلى الإنتاج وما الذي جرى. بالنسبة للوكالات يعني هذا نموذج تسليم قياسيًا عبر مشاريع العملاء، حيث لا يتطلب تسليم موقع لمطور آخر أن يعكس هندسة طقس نشر مخصص وغير موثّق.
كيفية النشر خطوة بخطوة
اربط المستودع والفرع
افتح تطبيقك في اللوحة، وانتقل إلى النشر عبر GitHub، وأدخل رابط المستودع والفرع الذي تنشر منه — عادةً main أو production. الفرع الذي تختاره هو الذي يصبح حيًّا، فلا تُنشر فروع الميزات بالخطأ أبدًا.
صرّح بالوصول إلى مستودع خاص
إن كان المستودع خاصًا، أضف رمز وصول شخصيًا أو رمز نشر لتتمكن المنصة من استنساخه. يُخزَّن الرمز كسر، ويُستخدم فقط لسحب الشيفرة وقت النشر، ويمكن إبطاله أو تدويره دون المساس بتطبيقك.
عرّف خطوات البناء والترحيل
اضبط الأوامر التي تحوّل نسخة مسحوبة إلى إصدار عامل — لتطبيق PHP يكون ذلك عادةً composer install --no-dev، وبناء أصول الواجهة الأمامية، وترحيل قاعدة البيانات. تُحفظ هذه الخطوات مع التطبيق بحيث يشغّل كل نشر خط الأنابيب نفسه، لا ما يتذكر أحدهم كتابته.
اختر النشر اليدوي أو التلقائي عبر webhook
انشر عند الطلب بزر في اللوحة، أو فعّل الـ webhook بحيث يُطلق أي دفع إلى الفرع المربوط عملية النشر تلقائيًا. يستخدم الـ webhook سرًا موقّعًا، فلا يستطيع بدء إصدار سوى عمليات الدفع الأصيلة من مستودعك.
أطلق ونفّذ purge وتأكّد
عند النشر تسحب المنصة الفرع، وتشغّل خطواتك، وتفعّل الإصدار الجديد؛ ويُنفَّذ purge تلقائيًا للتخزين المؤقت على الحافة للأصول المتغيّرة كي لا يُقدَّم للزوار ملفات قديمة. تعرض اللوحة حالة النشر ووقت آخر نشر لتتأكد أن الإصدار حيّ.
أمثلة على السيناريوهات
يُطلق دفع إلى main تشغيل composer install وبناء الأصول والترحيلات، ثم يُنشر الإصدار ويُنفَّذ purge للتخزين المؤقت على الحافة تلقائيًا.
تربط وكالة مستودع GitHub خاصًا برمز نشر محدد النطاق، فتبقي الشيفرة مغلقة بينما تسحبها المنصة وتنشرها.
يُبقي فريق النشر التلقائي معطّلًا وينقر على النشر في اللوحة بعد مراجعة الشيفرة، فيكون كل إصدار إنتاج فعلًا مقصودًا ومسجّلًا.
الأسئلة الشائعة
هل يبني النشر عبر GitHub صورة Docker أم ينشر شيفرة المصدر؟
إنه ينشر شيفرة مصدر التطبيق على بيئة تشغيل المنصة — يسحب فرعك ويشغّل خطوات البناء والترحيل على الشيفرة نفسها. وهذا الملاءمة الطبيعية لتطبيقات PHP وأطر العمل. إن أردت تحديدًا بناء صورة حاوية وتشغيلها، استخدم تطبيقات الحاويات بصورة جاهزة أو النشر الفوري عبر Docker Compose بدلًا من ذلك.
ماذا يحدث بالضبط عند دفع عبر webhook؟
يرسل الدفع إلى الفرع المربوط webhook موقّعًا إلى المنصة، التي تتحقق من التوقيع، وتستنسخ ذلك الالتزام أو تجلبه، وتشغّل خطوات البناء والترحيل المحددة، وتفعّل الإصدار الجديد، وتنفّذ purge للتخزين المؤقت على الحافة. ثم تحدّث اللوحة حالة النشر ووقت آخر نشر لتتأكد أنه هبط بنجاح.
كيف يُحمى رمز الوصول لديّ؟
يُخزَّن الرمز كسر ويُستخدم فقط لاستنساخ المستودع وقت النشر. لا يُعرض بعد الحفظ ولا يظهر في سجلات البناء، ولأنه يعيش منفصلًا عن شيفرتك يمكنك تدويره أو إبطاله في GitHub دون تغيير أي شيء في التطبيق.
هل يمكنني التراجع (rollback) إن ساء النشر؟
لأن عمليات النشر مرتبطة بالالتزامات وبخطوات محددة، فإن التعافي مسألة نشر التزام معروف بصلاحه — توجّه النشر إلى الالتزام العامل السابق أو تُرجِع على الفرع وتدع خط الأنابيب ينشره. إبقاء عمليات النشر قابلة للتكرار هو تحديدًا ما يجعل العودة موثوقة بدلًا من أن تكون فوضى.
أي فرع يصبح حيًّا، وهل يمكنني النشر من أكثر من واحد؟
تختار الفرع الذي تنشر منه، عادةً main أو فرع إنتاج مخصص، ويُنشر ذلك الفرع فقط — لا تُنشر عمليات الدفع إلى فروع الميزات. يبقي هذا العمل قيد التطوير خارج الإنتاج مع إتاحة النشر لحظة الدمج إلى فرع الإصدار.
هل يعمل مع GitLab أو مضيفات Git أخرى، أم مع GitHub فقط؟
بُني سير العمل حول رابط مستودع Git وفرع ورمز، فهو ليس مقتصرًا على GitHub تحديدًا — أي مستودع يمكنك الوصول إليه برابط ورمز وصول يلائم النموذج نفسه. GitHub هو الحالة الشائعة، ولذلك سُمّي باسمه، لكن الآلية هي Git قياسي.