موثّق من الكود · 2026-06-17 · شرح + اقتراحات
base_path() للـ BE + مجلد الفرونت المبني)، بيتوقّع، وبيتنشر في versions.json. العميل بينزّل الباكدج الموقّع ويطبّقه.
main (شوف قسم 2.5) — بس انتبه: main فيه السورس بس (مفيش vendor ولا الفرونت المبني public/app)، فبيحتاج خطوة بناء (composer + ng build) — وده بيخلّيه قابل لإعادة الإنتاج.
PackageBuilder::build() بياخد المصدر من $source = base_path() ويحزم:
config('moonstack.package.include')): app, bootstrap, config, database, Modules, routes + vendor.MOONSTACK_FRONTEND_DIST (مجلد Angular المبني، فيه index.html) → بينزل في الباكدج تحت public/app.versions.json (المانيفست اللي العميل بيـpoll عليه). ship = build + publish في خطوة، وكمان بينشر ملف الـ updater نفسه موقّع (للـ self-heal).
moonstack-update.php (ملف مستقل) بيعمل بالترتيب:
updater أحدث موقّعة → يستبدل نفسه ويطلب إعادة المحاولة (يمنع updater باظ من تعطيل الأسطول).versions.json ويختار أصغر تنزيل: delta (الملفات المتغيّرة بس) لو متاح، وإلا full.lock فيه نقطة الرجوع.composer.lock اتغيّر (تجنّب نسخ 15k ملف vendor).timeout فمفيش خطوة تعلّق للأبد.main مباشرة — للعمل بكذا ديفلوبر موصى بهmain (اللي كله بيعمله merge عليه أصلًا).
main في الريبوهين فيه السورس بس — مفيش vendor ومفيش الفرونت المبني (public/app = 0 ملفات). الفرونت المبني موجود حاليًا في public_html اللي ملوش remote — يعني مش متبوش على GitHub. فالبِلد-من-git لازم يعمل خطوة بناء (composer + ng build)، وده ميزة: ريليس قابل لإعادة الإنتاج 100%.
main (BE + FE) → نعمل tag للنسخة (v2.3.0) على الاتنين.git checkout v2.3.0 → composer install --no-dev --optimize-autoloader (ينتج vendor).git checkout v2.3.0 → npm ci && ng build --base-href /app/ (ينتج dist).php artisan moonstack:build v2.3.0 --source=<be-checkout> --frontend=<fe-dist> --sign → باكدج موقّع.moonstack:release / ship → versions.json → العملاء ينزّلوا.PackageBuilder::build() بيقبل opts['source'] أصلًا، لكن أمر moonstack:build مفيهوش --source دلوقتي. نضيف اختيار --source (تعديل بسيط) → نقدر نبني من أي checkout نظيف من غير ما نلمس moonui. (بديل من غير تعديل: نشغّل الأمر من جوه الـ checkout نفسه بعد composer install + .env مؤقت.)composer install + ng build لكل ريليس — جهة البِلد بس، مش بتأثر على سرعة تحديث العميل ولا دقته إطلاقًا.main بعد ما نخلّص شغل MoonStack — وده بالظبط نقطة بداية الريليس في الـ pipeline ده.كلها بتزوّد الاستقرار من غير ما تخل بالسرعة ولا الدقة — التأثير موضّح في الجدول.
| # | التحسين | المكسب (استقرار) | السرعة | الدقة | الجهد |
|---|---|---|---|---|---|
| 1 | Health-check بعد الأبديت + rollback تلقائي بعد up وقبل فك الـ lock: نضرب endpoint صحة (مثلًا /up + لوجين/داشبورد). لو رجع خطأ → rollback تلقائي للـ backup. | عالي — بيمسك "migrate نجح بس الأبليكيشن باظ" (اللي دلوقتي بيعدّي) | +ريكوست واحد (مهمل) | محايد | صغير |
| 2 | Canary / إطلاق متدرّج (channels) الريليس يروح لعميل تجربة (moontest) الأول؛ بعد ما يثبت سليم نرقّيه لـ stable لباقي الأسطول. | عالي — ريليس باظ مايضربش كل العملاء مرة واحدة | محايد (تحديث كل عميل زيه زيه) | محايد | متوسط |
| 3 | بِلد قابل لإعادة الإنتاج (من tag نظيف) أو حارس "dirty tree" نبني من git archive <tag> في مجلد مؤقت، أو على الأقل نحذّر/نمنع الـ build لو base_path فيه تعديلات غير متكوميتة مقابل تاج الريليس. | دقة عالية — مستحيل نشحن ملفات قديمة/غير متكوميتة بالغلط | محايد على العميل (جهة البِلد فقط) | +++ | صغير (حارس) / متوسط (archive) |
| 4 | تنظيف الـ backups (retention) نحتفظ بآخر N باك أب ونمسح الأقدم — القرص المليان نفسه ممكن يفشّل تحديث. | متوسط — يمنع فشل بسبب امتلاء القرص | محايد | محايد | صغير |
| 5 | تحقق سلامة بعد الـ apply بعد النسخ، نطابق checksums الملفات المشحونة من الـ manifest — نكتشف apply ناقص/تالف ونعمل rollback. | متوسط — يمسك تطبيق جزئي/تالف | +هاش للملفات المتغيّرة (بسيط) | + | صغير |
| 6 | اختبار idempotency لـ updater.seedersاختبار CI يتأكد إن كل seeder في القايمة updateOrCreate ومن غير side-effects (يحمي خطوة الـ seed الجديدة وهي بتكبر). | متوسط — يحافظ على أمان خطوة 8b | محايد (CI بس) | + | صغير |
السياق الكامل في الـ KB: knowledge-base/topics/moonstack-update.md · مرتبط بـ middleware.md.