مرحبًا بالجميع ، لقد دمجتُ ميزة جديدة ستساعد الإضافات (plugins) والمظاهر (themes) في تثبيت إصدارات معينة عند تثبيتها على نسخ أقدم من Discourse.
يمكنك الآن تضمين ملف .discourse-compatibility في الجذر (root) لمستودع إضافة أو مظهر، يحدد الإصدار الذي يجب استرداده (checkout) عند التثبيت على نسخ أقدم من Discourse.
المبررات
من المحبط تذكر أي الإضافات والمظاهر متوافقة مع أي إصدار من Discourse. بصفتك مسؤولًا (admin)، يجب أن يكون من الممكن مسح هذه التغييرات بسهولة وإيجاد الإصدار المناسب لنسختك من Discourse دون الاضطرار لقراءة سجل الالتزامات (commit history) للإضافة. وبصفتك كاتبًا لإضافة أو مظهر، يجب أن تتمكن من إدارة إصدارات التثبيت مع إجراء تغييرات غير متوافقة مع الإصدارات الأقدم، حتى لا تكسر التثبيتات القديمة.
تتسارع تحديثات برنامج Discourse بشكل كبير، وهو أمر رائع بلا شك، لكنه يجعل صيانة نسخ Discourse التي تحتوي على العديد من الإضافات أمرًا صعبًا جدًا في بعض الأحيان، خاصة إذا كنت تتبع إيقاعات إصدارات/نسخ أخرى مثل النسخة المستقرة الحالية. خطتي هنا هي تمكين نظام بيئي يخفف عملية التحديث لأولئك الذين يتبعون النسخة المستقرة أو أي إيقاع إصدار آخر، وتزويد مسؤولي المواقع بطريقة لاستعادة أي إصدار من الإضافة متوافق مع إصدار Discourse المستهدف بسرعة وبشكل تلقائي.
الإعلان الأصلي (تم استبداله الآن بالوثائق المرتبطة أعلاه)
التنفيذ
أول ما يجب ملاحظته: نحن نعتمد هنا على الوسوم (tags) في نواة Discourse، حيث أن نسخ بيتا (betas) من Discourse تُصدر بشكل متكرر بما يكفي لتمكيننا من تثبيت إصدارات الإضافات مقابلها. تثبيت الإصدارات مقابل تجزئات Git (git hashes) هو كابوس لعدة أسباب، لذا يمكننا استخدام git describe للحصول على أقرب وسم بيتا/مستقر.
في إضافة أو مظهر، ندعم الآن ملف توافق الإصدارات باسم .discourse-compatibility في الجذر. هذا الملف هو قائمة مرتبة تنازليًا (تبدأ بإصدارات Discourse الأحدث) تحدد خريطة توافق.
بالنسبة لكل إضافة/مظهر، سيستمر التحديث أو إعادة البناء في استرداد التزام/فرع/وسم لاحق حتى يجد واحدًا يساوي الإصدار الحالي من Discourse أو يتجاوزه.
على سبيل المثال، بالنسبة لملف الإصدار أعلاه، إذا كان إصدار Discourse الحالي هو 2.4.6.beta12، فسيقوم بفحص الملف واختيار الإدخال الخاص بـ 2.5.0.beta2.
إذا كان إصدار Discourse الحالي هو 2.4.4.beta6، فسيقوم باختيار الإدخال المطابق لـ 2.4.4.beta6.
إذا لم يكن هناك إصدار لاحق، يبقى على الإصدار الحالي المسترد.
على سبيل المثال، بالنسبة لـ 2.5.0.beta3، لن يحدث أي تثبيت.
إذا لم يكن هناك إصدار سابق، يتم استرداد الأقدم المذكور في ملف الإصدار.
على سبيل المثال، بالنسبة لـ 2.2.1.beta22، سيتم استرداد أقدم إصدار ممكن بناءً على “الإصدار”، وهو الإدخال الخاص بـ 2.4.2.beta1.
الهدف هنا هو تخفيف عبء صيانة النشر البديل الذي لا يلتزم بدقة بـ “tests-passed” في المستقبل، ومنح المرونة للمسؤولين بشأن متى وأين يقومون بالترقية. نقوم بذلك من خلال منح كتاب الإضافات والمظاهر طريقة لتطوير تغييرات غير متوافقة مع الإصدارات الأقدم دون التأثير على التثبيتات على الإصدارات الأقدم من Discourse.
أعجبني اتجاهها، أي أنها تتيح إدارة هذه المشكلة من داخل الإضافة نفسها، دون الحاجة إلى أن يقوم مسؤول الموقع بأي إجراء بحد ذاته.
لدي بعض الأسئلة الأولية:
هل ستبقى قائمة فحص بيانات تعريف الإضافة الحالية required_version عند تفعيل الإضافة؟ وكيف تتصور تفاعلها مع هذه الميزة (إن وجدت)؟
أرى أن هذا تمت إضافته حاليًا في شكل مهمة Rake. كيف يرتبط ذلك، وما هو الاستخدام المقصود له، مع discourse_docker (أي أداة التشغيل) وdocker_manager؟ أرى أنك أجريت إضافات على كلا المستودعين، لكن هل يمكنك شرح كيفية عملها المقصود في كلا البيئتين؟
نعم، هذه هي الفكرة: تمكين مؤلفي الإضافات من إضافة توافق مع الإصدارات السابقة، حتى لا يضطر المسؤولون إلى القلق!
لا توجد حالياً خطط لتغيير أو إزالة بيانات التعريف الخاصة بالإضافة required_version. فهما مرتبطان، لكنهما يظلان منفصلين في ذهني: يحدّ required_version (الحد الأدنى/الأقصى) من تثبيت الإضافة عن طريق إلقاء خطأ، ويتم تحميله بعد سحب التوافق هذا. إذا كنت ترغب في منع نسخ Discourse القديمة جداً من استخدام إضافتك، فإنني أقول إنه لا يزال من الجيد تضمين required_version للإصدار الأدنى الأول؛ فليس هناك قدر من البحث عن التوافق قادر على إصلاح ذلك
لا ينبغي أن تكون هناك حاجة لأي تغييرات في الإعدادات في الاستخدام العادي، حيث سيتم التقاط التغييرات تلقائياً. تُستدعى مهمة Rake في discourse_docker بعد استنساخ الإضافات، لذا فإن الترتيب في المشغّل هو:
استنساخ الإضافات
التحقق من التوافق والتحقق منه (إذا كان ذلك ينطبق)
الترحيل
في docker_manager، ستتمكن نسخ Discourse الأقدم من تحديث الإضافات إلى إصدار متوافق. يظل واجهة المستخدم هنا كما هي، لكن الإضافة “المحدثة” الآن تُحدد وفقاً لملف التوافق.
باختصار، لا يلزم أي تغييرات لأي من الحالتين للاستفادة من هذا، إذا كان هذا ما تتساءل عنه.
تحت الغطاء، يستخدم الأمر git show HEAD@{upstream}:.discourse-compatibility لقراءة أحدث ملف، و git reset --hard #{checkout_version} للتحقق من الإصدار الصحيح. بهذه الطريقة، يمكننا استخدام أحدث ملف للتوافق، ولن تعلق نسخ Discourse الأقدم في ملف توافق قديم (ربما غير صالح).
فحصتُ كل علامة (tag) على حدة بالترتيب العكسي بدءًا من v2.6.0.beta1. وجدتُ أن أوامر git التالية مفيدة:
git tag --list \\ مثال: git tag --list 'v2.5.0*'
git checkout tags/tag \\ مثال: git checkout tags/v2.5.0.beta7
لم يستغرق الأمر وقتًا طويلاً لإيجاد علامة لا تعمل مع الإصدار الحالي من الإضافة: v2.5.0.beta7 لا يتضمن discourse/app/components/d-textarea الذي تحاول إضافة السحر المخصص استيراده.
لذا، وجدتُ الالتزام (commit) في الإضافة الذي أضاف هذا الاستيراد، وأخذتُ قيمة sha1 من الالتزام السابق، وقمتُ بالتحقق منه واختباريه (عمل بشكل جيد)، وأضفتُ هذا إلى .discourse-compatibility:
ثم دفعتُ ذلك إلى فرع يحتوي على أحدث كود للإضافة (فرع للاختبار، غير ضروري عادةً)، وأعدتُ بناء خادم اختبار معزول بـ docker باستخدام فرع الإضافة هذا مع تعيين version إلى v2.5.0.beta7.
لم ينجح ذلك، ثم خطرت لي فكرة، بالطبع، أن مهمة rake plugin:pull_compatible_all غير موجودة في v2.5.0.beta7، لذا لن يعمل هذا بشكل رجعي (ألوم ). كما هو متوقع، أرى في سجلات المشغل (launcher logs):
Don't know how to build task 'plugin:pull_compatible_all' (See the list of available tasks with `rake --tasks`)
هل هذه هي الفكرة العامة لكيفية تخيلك لاستخدام هذا؟
أما فيما يتعلق بـ required_version، فقد واجهتُ ذلك هنا لأن خادم الاختبار كان يحتوي على إضافة discourse-legal-tools المثبتة، والتي تحتوي على required_version يساوي v2.5.0، لذا فشلت في البداية عند v2.5.0.beta7. أعتقد أنني سأقوم بنقل هذه الإضافة إلى النظام الجديد. لا يزال بإمكانني رؤية فائدة required_version في تحديد حد أدنى مطلق كما ذكرت.
نعم، هذا صحيح - نظرًا لأن هذه الميزة لم تُدمج في نواة Discourse حتى الآن، فلن تعمل على أي إصدار أقدم من 2.6.0.beta1 (حاليًا). لا يزال يتعين علي نقلها إلى الإصدار المستقر وآخر إصدار تجريبي، حتى نتمكن من استخدامها مع الإصدار 2.5.0، لكننا لا نخطط لنقلها إلى إصدارات أقدم من ذلك.
متابعة فقط هنا، لقد أضفت الآن ملف توافق إلى Custom Wizard الرئيسي وسأستخدمه لتثبيت الإضافة، بما في ذلك v2.6.0.beta1 (الإصدار التجريبي الحالي) و v2.5.0 (الإصدار المستقر الحالي) عند نقلها. راجع المزيد:
أولاً، مجرد ملاحظة أن بناء الجملة لوسوم إصدار discourse في ملف .discourse-compatibility هو 2.5.0 (كما في مثال @featheredtoast)، وليس v2.5.0. إذا كان لديك v، فستحصل على هذا الخطأ:
Malformed version number string v2.6.0.beta1
ثانياً، أشار @featheredtoastإلى ذلك أن نظام التثبيت (pinning) تم إرجاعه الآن إلى الفرع stable. لقد فاتني هذا لأنني كنت أنظر إلى وسم v2.5.0.
هذا يثير سؤالاً بسيطاً لدي. ففروع discourse لا تتطابق مباشرة مع وسوم إصدار discourse. فمعظم المواقع التي تشغل إصدارات أقدم من discourse تعمل على فرع، أي stable، وليس على إصدار، أي v2.5.0.
إذا تم إضافة تغيير كاسر (لإضافة) أيضاً إلى فرع “أقدم”، أي stable، فماذا يعني ذلك بالنسبة للوسوم (pins)؟ ربما أنا لا أفهم تماماً كيف يعمل نظام إصدار الإصدارات.
تتوافق الإصدارات مع إصدار discourse المحدد في التطبيق، وليس مع وسم git.
لذا، فإن “2.5.0” في هذا السياق تعني أي إصدار مُعلَن عنه كـ 2.5.0، وصولاً إلى التحديث الجديد إلى 2.5.1 (أو 2.6.0.beta1).
إذا تم إضافة تغيير كاسر (لإضافة) أيضًا إلى الفرع المستقر، فسيؤدي ذلك فعليًا إلى تعطيل الإضافة أيضًا. الهدف الكامل من الترقيم الإصداري هو أن نكون واثقين نسبيًا من أننا لا نُدخل تغييرات كاسرة لتلك الإصدار، لذا فإن هذا أمر يستدعي الشكوى منه بشكل منفصل. نيتنا للإصدار المستقر هي نقل فقط إصلاحات الأمان والإصلاحات الحرجة (والميزات الصغيرة، عند الاقتضاء).
الهدف من ذلك هو تمكيننا من حساب إصدارات الإضافات العاملة الأقدم مقابل إصدارات Discourse العاملة الأقدم. هذا ليس حلاً سحريًا بأي حال من الأحوال، لكنه يمنحنا منصة للقيام بذلك، إذا كنا حريصين فعليًا على اختيار ما نُنقله.
هذا يعمل إلى حد كبير، إلا إذا كنت تقوم بالاستنساخ باستخدام --depth=1.
سأقوم بتنفيذ خطاف (hook) لاستدعاء أمر git fetch --depth 1 {upstream} commit قريبًا إذا لم يتم العثور على الهدف في البداية، وإلا سنكون عالقين في إجراء استنساخ جزئي/كامل وهو أمر غير مثالي. يجب أن نكون قادرين على جلب ما نحتاجه.
تعديل: تم التحديث هنا:
لقد قمت بإعادة تطبيق هذا التعديل على إصداري Beta و Stable أيضًا - لذا يجب أن نكون قادرين على تثبيت الإصدار حتى مع الاستنساخ السطحي الآن.
أعتذر مقدماً، فأنا غالباً ما أعود إلى هذا في وقت متأخر من الليل، لذا لا أستطيع الجزم بنسبة 100% من دقة ما أقوله، وقد يكون هذا أمراً تدركونه بالفعل. أوثق ذلك هنا جزئياً من أجل هدوئي النفسي، إذ أنه أوقعني في حيرة عدة مرات حتى الآن.
أعتقد أن هذه الآلية غير قابلة للتطبيق فعلياً على فرع beta إذا كان الإضافة (plugin) يُستخدم على مثابة (instance) لا تملكها (أي أنها مفتوحة المصدر) ويتم تحديثها بالطريقة المعتادة. والطريقة المعتادة للتحديث هي أن يقوم مسؤول الموقع بذلك عند ظهور التنبيه في واجهة المسؤول.
وبالنظر إلى ما يلي:
وهذا أيضاً:
وأن tests-passed و beta لديهما نفس إصدار Discourse ولكن ليس نفس الكود، فمثلاً كلاهما حالياً 2.6.0.beta2:
لدعم فرع beta، يجب تثبيت (pin) تعهد (commit) مرتبط بأحدث إصدار تجريبي، لأن هذا هو الإصدار الذي ستستخدمه المواقع على فرع beta.
ومع ذلك، إذا كان أحدث إصدار تجريبي موجوداً في ملف التوافق، فإن المثيلات التي تعمل على tests-passed ستستخدم أيضاً التعهد المثبت.
وهذا يعني أنه لا يمكن دعم الاستخدام القياسي لكل من tests-passed و beta في وقت واحد في إضافة مفتوحة المصدر. وبما أن الغالبية العظمى من الأشخاص الذين يثبتون الإضافات يستخدمون tests-passed، فإنك عملياً لا تستطيع دعم beta عبر هذه الطريقة.
لاحظ أن هذا يعمل عملياً مع فرع stable، لأن stable لديه إصدار Discourse مختلف عن beta و tests-passed.
أجل، أنا على دراية بهذا الأمر، ولن يُحلّ بشكل حقيقي إلا مع إصدار النسخة التجريبية التالية. يجب أن نجد بالتأكيد طريقة للتمييز بين النسخ التجريبية والنسخ التي اجتازت الاختبارات في هذا الصدد.
عندما كنت أقوم بإعداد الميزة، كنت أفكر في الشوك المستقرة والغريبة، ولم ألاحظ إلا لاحقًا أن أحدث إصدار والإصدار المستقر يشاركان نفس الأرقام.
يبدو أن النتيجة الفعالة هي أنه لا ينبغي تشغيل العملية إذا كانت النسخة قيد التشغيل هي tests-passed. لا يمكنك تضمين إصدار tests-passed في الملف للأسباب الموضحة أعلاه، لذا فإن استبعاد العملية في حالة tests-passed لن يغير سلوكها الحالي.
إحدى الطرق لتنفيذ ذلك هي:
def self.find_compatible_resource(version_list, version = ::Discourse::VERSION::STRING)
return if Discourse.git_branch === 'tests-passed'
...
end
هذا سيمكن من استخدام أحدث إصدار beta في الملف لغرض تثبيت الإضافات للمواقع التي تعمل على beta. ويمكنك الاستمرار في دعم tests-passed في أحدث التزام في الإضافة، أي دون استخدام هذا الملف. إذا كنت موافقًا على ذلك، يمكنني تقديم طلب سحب (PR).
بديلًا عن ذلك، أشعر أن المشكلة الجذرية هنا هي:
أنا متأكد من أنكم ناقشتم هذا من قبل، لكن هل من الممكن فعل شيء مثل:
tests-passed: 2.6.0.tests-passed، أي تعيين PRE إلى tests-passed في فرع tests-passed.
نعم، أنا مؤيد لإضافة علامة إضافية للإصدار ما قبل الاختبار (pre-beta) مقارنة بالإصدار الاختباري الفعلي (beta)، شريطة أن يكون ذلك سهلاً بما يكفي. سيساعد ذلك في حل المشكلة الأساسية هنا. لقد رأيت مشاريع برمجية أخرى ترقّي الإصدار إلى الإصدار التالي قبل إصداره (على سبيل المثال، بعد إصدار beta1، يتم ترقية “الإصدار” إلى beta2).
ومع ذلك، تقليدياً، لم يفعل Discourse ذلك، لذا يعتمد الأمر على أي طريقة أسهل للمشروع لاعتمادها.
هذا يسبب مشكلة في Discourse 2.5.1. وبما أن هذا التغيير لن يتم نقله إلى الإصدارات المستقرة أبدًا، فسيكون من الضروري تحديث ملف discourse-compatibility مع كل إصدار مستقر جديد من 2.5.x.
سيكون من الضروري تحديث ملف discourse-compatibility الخاص بكل إضافة مع كل إصدار مستقر جديد من 2.5.x.
بدلاً من ذلك، يمكن أن يشير ملف التوافق إلى الإصدار 2.5.999، مما يبقي الإضافة فعليًا عند الإصدار 1f86468b2c81b40e97f1bcd16ea4bb780634e2c7 طوال عمر الإصدار 2.5.x. لكن هذا يبدو لي حلًا غير أنيق جدًا.
يبدو أنه سيكون من الآمن تثبيت الإصدار على 2.6.0beta1، وهو ما سيكون أكثر دقة أيضًا نظرًا لأن المشكلة ظهرت في النسخة التجريبية الثانية (beta2)، هل هذا منطقي؟ سيغطي هذا أيضًا جميع إصدارات 2.5.
يبدو أن “الحل” غير التقليدي الخاص بك المتمثل في 2.5.999 هو حل بديل أنيق (رغم أنه غير مرتب كما ذكرت). حاولت جعل عملية التثبيت هنا بسيطة قدر الإمكان، لكنك محق في أننا لا نزال نفتقر إلى طريقة حقيقية لتحديد 2.5.x كإصدار مثبت صالح.
حل بديل آخر لهذه الحالة المحددة لتثبيت آخر إصدار مستقر، مع الإبقاء على نسخ بيتا للإصدار التالي غير مثبتة، قد يكون أكثر دقة قليلاً لكنه يبدو أقل اعتمادًا على الحلول غير التقليدية بالنسبة لي لتثبيت فرع 2.5.x بأكمله هو تحديد الإصدار عند 2.6.0.beta0 أو 2.6.0.alpha1، وهو ما يعني من الناحية الدلالية تثبيت كل شيء قبل الإصدار ما بين 2.5.x و 2.6.0.beta1 وحتى ذلك الإصدار. وهذا يعني:
يتم تغطية كل شيء في 2.5.x بواسطة التثبيت.
يبقى كل شيء في 2.6.0.beta(1+) غير مثبت.
نعم، يمكنك تعديل أوامر git clone في ملف app.yml لاستنساخ الإصدار الذي تريده. لاحظ أنك بحاجة إلى التأكد من أن Discourse مثبت أيضًا على الإصدار الذي تريده. وقد تحتاج أيضًا إلى تثبيت discourse_docker على إصدار متوافق مع إصدار Discourse الذي تقوم بتشغيله. إذا كنت تقوم بكل ذلك، فمن الأسهل عدم الترقية.