المقدمة
تدفع تغييرًا صغيرًا إلى وحدتك في Odoo على Odoo.sh. وترفع رقم الإصدار في __manifest__.py من 0.5 إلى 0.6 — تحديث روتيني. وبعد دقائق، يفشل بناء بيئة الاختبار. والخطأ؟ تحذير في وحدة أخرى تمامًا لم تمسّها أصلًا.
إن بدا هذا مألوفًا، فقد واجهتَ واحدًا من أدقّ سلوكيات Odoo.sh: الترقيات المتتالية التي يُطلقها رفع رقم الإصدار. وتشرح هذه المقالة بدقة ما الذي يحدث، ولماذا يحدث، وكيف تتجنّبه.
المشكلة: تغيير بسيط في الإصدار يُعطّل كل شيء
تخيّل أن لديك وحدة اسمها document_manager تتولّى إصدار الشهادات وقوالب الخطابات. ولها سلسلة تبعيات كهذه:
document_manager
└── hr_connector (depends on document_manager)
├── hr_connector_charts (depends on hr_connector)
└── attendance_tracker (depends on hr_connector)تُجري تغييرًا برمجيًا في document_manager — ربما أعدت هيكلة دالة أو أضفت حقلًا جديدًا. وترفع رقم الإصدار في ملف الـ manifest. وتدفع التغييرات إلى بيئة الاختبار.
فيفشل البناء.
ويشير سجل الأخطاء إلى hr_connector، لا إلى document_manager. ويُظهر تحذيرات إهمال موجودة في الشيفرة منذ شهور. فماذا جرى؟
كيف يقرّر Odoo.sh ما الذي يُرقّيه
إليك الفكرة المحورية التي تغيب عن معظم المطوّرين:
يعتمد Odoo.sh على أرقام الإصدارات — لا على فروق الملفات — في تحديد الترقيات المتتالية.
حين تدفع إلى Odoo.sh، فإنه يقارن حقل version في ملف __manifest__.py لكل وحدة بما هو مثبَّت حاليًا. فإذا تغيّر الإصدار، تُرقّى تلك الوحدة. والأهم أن كل الوحدات التي تعتمد عليها تُرقّى أيضًا — على نحو تعاودي.
ويختلف هذا عن طريقة التعامل مع تغييرات الشيفرة. فإذا عدّلت ملفات داخل وحدة من دون تغيير إصدارها، يظل Odoo.sh يكتشف تغييرات الملفات ويحدّث تلك الوحدة تحديدًا. لكنه لا يمتدّ بالترقية إلى الوحدات التابعة.
ما الذي رصدناه
| نوع التغيير | هل حُدِّثت الوحدة؟ | هل امتدّت الترقية إلى التابعات؟ | نتيجة البناء |
|---|---|---|---|
| لا تغييرات | لا | لا | نجاح |
| تغيير في الشيفرة دون رفع الإصدار | نعم | لا | نجاح |
| رفع الإصدار فقط | نعم | نعم | فشل |
| تغيير في الشيفرة + رفع الإصدار | نعم | نعم | فشل |
كان رفع الإصدار هو المُطلِق. لا الشيفرة.
لماذا تُعطّل الترقية المتتالية الأمور
الترقية المتتالية بحدّ ذاتها ليست المشكلة — المشكلة في ما تكشفه.
فحين تُحمَّل hr_connector عند إقلاع الخادم (وهو ما يحدث في كل مرة)، يقرأ Odoo نماذجها وواجهاتها لكنه لا يُشغّل مسار الترقية الكامل. فتبقى مشكلات مثل تحذيرات الإهمال، أو عدم تطابق المخطّط، أو أخطاء التحقّق من الواجهات، ساكنة.
لكن حين تدفع ترقيةٌ متتالية hr_connector عبر عملية -u (الترقية) الفعلية، يُشغّل Odoo ما يلي:
- مطابقة حقول النماذج مع مخطّط قاعدة البيانات
- التحقّق من XML الواجهات وإعادة توليدها
- إعادة معالجة ملفات البيانات
- إعادة تقييم شيفرة Python بفحوص أكثر صرامة
عندها تستيقظ تلك المشكلات النائمة. فالتحذيرات التي تُتجاهَل بصمت أثناء الإقلاع تتحوّل إلى إخفاقات اختبار أثناء الترقية.
5 مشكلات شائعة تظهر أثناء الترقيات المتتالية
1. مُزخرِفات API مُهمَلة
# This works at startup but generates DeprecationWarning during upgrade
@api.model
def create(self, vals):
...
# The correct decorator since Odoo 14+
@api.model_create_multi
def create(self, vals_list):
...2. خصائص حقول مُهمَلة
# Old syntax — triggers deprecation warning
name = fields.Char(track_visibility='onchange')
# Modern syntax
name = fields.Char(tracking=True)3. عناصر واجهة مُهمَلة
<!-- Old Kanban syntax -->
<t t-name="kanban-box">
<!-- Modern syntax -->
<t t-name="card">4. سمات نماذج مفقودة
# Missing _description triggers a warning during upgrade
class CustomModel(models.Model):
_name = 'custom.model'
# Should have: _description = 'Custom Model'5. مخالفات NOT NULL في المخطّط
الحقول التي أُضيفت بوصفها required=True بينما توجد سجلات قائمة بقيم NULL ستفشل أثناء مطابقة الترقية.
حلّ سريع: تجاوَز رفع الإصدار
الحلّ الالتفافي المباشر بسيط: لا ترفع رقم الإصدار.
ادفع تغييرات شيفرتك من دون تعديل حقل version في ملف __manifest__.py. وسيظل Odoo.sh يكتشف تغييرات الملفات ويطبّقها على وحدتك. وبما أن الإصدار لم يتغيّر، لا تُطلَق أي ترقية متتالية، وتبقى الوحدات التابعة كما هي.
وهذه استراتيجية صالحة على المدى القصير، خصوصًا حين تحتاج إلى نشر عاجل. لكنها غير مستدامة — فأنت تفقد تتبّع الإصدارات، وستضطر في النهاية إلى رفع الرقم.
الحلّ الدائم: نظِّف سلسلة التبعيات
الحلّ الحقيقي هو إصلاح كل تحذير في كل وحدة ضمن سلسلة التبعيات. وإليك المقاربة المنهجية.
الخطوة 1: اختبر الترقية محليًا
شغّل أمر الترقية محليًا على نسخة من قاعدة بيانات الإنتاج لديك:
odoo -d your_database -u hr_connector --stop-after-init --log-level=warningالتقِط كل التحذيرات والأخطاء. فهذا يمنحك القائمة الدقيقة للمشكلات التي سيصادفها Odoo.sh.
الخطوة 2: أصلِح تحذيرات الإهمال
راجِع كل وحدة في سلسلة التبعيات وأصلِح ما يلي:
@api.modelعلى دوالcreate()— غيّرها إلى@api.model_create_multi- خصائص
track_visibility— غيّرها إلىtracking=True readonly=1في المعالِجات — غيّرها إلىreadonly=True- غياب
_descriptionفي النماذج - عناصر الواجهات المُهمَلة مثل
kanban-box— غيّرها إلىcard
الخطوة 3: أصلِح مشكلات المخطّط
تحقّق من مخالفات قيد NOT NULL:
SELECT column_name, is_nullable
FROM information_schema.columns
WHERE table_name = 'your_table'
AND is_nullable = 'NO';وتأكّد من أن كل الحقول المطلوبة لها قيم افتراضية أو نصوص ترحيل برمجية.
الخطوة 4: اختبر الترقية المتتالية الكاملة
بعد اكتمال كل الإصلاحات، ارفع الإصدار على الوحدة الجذر وادفع إلى فرع اختباري. وتحقّق من أن الترقية المتتالية الكاملة تنتهي بسلام.
إضافة: انتبه للملفات الشبحية
أثناء تتبّع هذه المشكلة، اكتشفنا مشكلة دقيقة أخرى. فعند محاولة العودة إلى إيداع معروف بسلامته باستخدام:
git checkout <good-commit> -- .يستعيد هذا كل الملفات المتتبَّعة إلى حالتها في ذلك الإيداع. لكنه لا يحذف الملفات التي أُضيفت في إيداعات لاحقة. وقد وجدنا أكثر من اثني عشر «ملفًا شبحيًا» — نماذج ومعالِجات وملفات بيانات لم تكن موجودة في الإيداع السليم لكنها ظلّت موجودة في دليل العمل.
وقد تُدخِل هذه الملفات الشبحية أخطاء استيراد، أو تسجيلات نماذج مكرّرة، أو بيانات غير متوقّعة أثناء ترقية الوحدة.
الطريقة الآمنة للتحقّق من التراجع:
# Check for files that exist now but didn't in the target commit
git diff <good-commit> HEAD --name-only --diff-filter=A
# These files need to be explicitly removedالخلاصة
إليك أهم ما ينبغي أخذه من هذا:
- رفع الإصدار يُطلق ترقيات متتالية — يُرقّي Odoo.sh كل الوحدات التابعة حين يتغيّر إصدار تبعيةٍ ما.
- تغييرات الشيفرة من دون رفع الإصدار آمنة — يظل Odoo.sh يطبّق تغييرات الملفات لكنه لا يمتدّ بالترقية.
- المشكلات الساكنة تظهر أثناء الترقيات — فتحذيرات الإهمال ومشكلات المخطّط الصامتة أثناء الإقلاع تتحوّل إلى إخفاقات أثناء الترقية.
- أصلِح السلسلة كاملة قبل رفع الإصدار — نظِّف كل الوحدات التابعة قبل تغيير أي رقم إصدار.
- تحقّق من التراجعات بالكامل — فأمر
git checkout -- .لا يحذف الملفات المضافة؛ تحقّق دائمًا من الملفات الشبحية.
وفهم كيفية تعامل Odoo.sh مع ترقيات الوحدات يوفّر ساعات من تتبّع الأخطاء. وسلوك الترقية المتتالية موثَّق، لكن تبعاته — خصوصًا ما يتعلّق بالتحذيرات الساكنة — تُباغت حتى المطوّرين المخضرمين.
وفي المرة القادمة التي يفشل فيها بناء بيئة الاختبار بعد رفع «بسيط» لرقم الإصدار، ستعرف تمامًا أين تبحث.
اقرأ أيضًا: ترحيل قاعدة بيانات Odoo على Odoo.sh: دليل عملي — سير العمل من التطوير إلى بيئة الاختبار إلى الإنتاج، وهو ما يمنع معظم متاعب الترقيات المتتالية من الأساس.
