Andrew Hanna

Andrew Hanna

كيف تضع Salesforce Flows تحت إدارة الإصدارات دون معاناة الدمج

كيف تضع Salesforce Flows تحت إدارة الإصدارات دون معاناة الدمج

الإجابة باختصار: احفظ كل Flow كملف .flow-meta.xml واحد بلا رقم إصدار، واجعل لكل Flow مالكًا واحدًا في كل تغيير، وامنع Git من دمج XML الخاص بالـ Flow تلقائيًا. وإذا عدّل فرعان الـ Flow نفسه، فاحتفظ بجانب واحد وأعد بناء التغيير الآخر في Flow Builder بدل تعديل XML يدويًا. معظم معاناة الدمج مع الـ Flows سببها التعديلات المتوازية وضوضاء التخطيط، لا Git نفسه.

لماذا يصعب وضع Salesforce Flows تحت إدارة الإصدارات؟

الـ Flow ليس كودًا تكتبه سطرًا بسطر، بل XML يولّده Flow Builder، وفيه بعض الفخاخ:

  • ملف واحد يحمل كل شيء. العناصر والـ connectors والمتغيرات والمعادلات كلها في ملف واحد، وقد يتجاوز Flow كبير 1,000 سطر من XML.
  • التخطيط محفوظ كبيانات. لكل عنصر إحداثيات locationX وlocationY، فسحب مربع واحد ينتج diff بلا أي تغيير في المنطق. وتحويل الـ Flow بين free-form وauto-layout يعيد كتابة مواضع كل العناصر.
  • لا يعود إلا أحدث إصدار. منذ Metadata API v44 لم تعد أسماء ملفات الـ Flow تحمل أرقام إصدارات، والـ retrieve يعيد أحدث إصدار، سواء كان نشطًا أو مسودة. وهكذا قد تدخل مسودة غير مكتملة إلى الـ repo دون أن ينتبه أحد.
  • أرقام الإصدارات تختلف بين الـ orgs. نشر Flow ينشئ إصدارًا جديدًا في الـ org المستهدفة، فالإصدار 7 في الـ sandbox قد يكون الإصدار 3 في الإنتاج.
  • عدد الإصدارات محدود. تسمح Salesforce بـ 50 إصدارًا لكل Flow، لذلك لا يغني سجل الـ org عن سجل Git.

كيف تجهّز repository للـ Flows يبقى نظيفًا؟

  1. استخدم source format. ملف واحد لكل Flow تحت force-app/main/default/flows/، باسم الـ API الخاص بالـ Flow دون لاحقة إصدار.
  2. توقف عن حفظ FlowDefinition. منذ تغيير v44 أصبح حقل status في الـ Flow نفسه هو ما يحدد إن كان نشطًا، ولم تعد Salesforce توصي باستخدام Flow Definitions للتفعيل.
  3. اعمل retrieve بالاسم، ومن الـ org التي تم فيها العمل. مثلًا sf project retrieve start --metadata Flow:Case_Escalation. راجع قيمة status قبل الـ commit حتى لا تُشحن مسودة بالخطأ.
  4. امنع Git من الدمج التلقائي للـ Flows. أضف force-app/**/flows/*.flow-meta.xml -merge إلى .gitattributes. وبحسب توثيق gitattributes، فإن إلغاء merge يحتفظ بنسخة فرعك ويعلن وجود تعارض. وتجنّب اختصار binary هنا، لأنه يوقف الـ diffs أيضًا، وأنت ما زلت تريد مراجعة تغييرات الـ Flow.

هذه الخطوة الأخيرة هي الأهم. الدمج القائم على الأسطر قد ينتج XML صالحًا تمامًا لكنه خاطئ منطقيًا، مثل connector يشير إلى عنصر حذفه الفرع الآخر. والتعارض المفروض أرخص من تعارض صامت. ولهذا يُبقي دليلنا لإعداد merge driver يفهم Salesforce الـ Flows خارج أنماط الـ driver: الـ profiles والـ permission sets تندمج جيدًا على مستوى العُقد، أما منطق الـ Flow فلا.

كيف تمنع شخصين من تعديل الـ Flow نفسه؟

  • مالك واحد لكل Flow في كل تغيير. احجز الـ Flow على عنصر العمل قبل أن يفتح أي شخص Flow Builder.
  • قسّم الـ Flows الكبيرة إلى subflows. فيذهب العمل المتوازي إلى ملفات مختلفة بدل ملف واحد مشترك.
  • اجعل الفروع قصيرة العمر. ادمج الفرع الأساسي كثيرًا حتى تظهر التعارضات وهي ما زالت صغيرة.
  • اختر وضع canvas واحدًا لكل Flow. التبديل بين free-form وauto-layout يغيّر كل إحداثية في الملف.

ماذا تفعل عندما يغيّر فرعان الـ Flow نفسه؟

  1. لا تدمج XML يدويًا. تعامل مع التعارض كقرار يخص المنطق، لا النص.
  2. احتفظ بالجانب صاحب التغيير الأكبر باستخدام git checkout --ours أو --theirs على ملف الـ Flow.
  3. انشر هذه النسخة إلى sandbox وأعد تطبيق التغيير الأصغر في Flow Builder.
  4. تحقق من النتيجة بمقارنة الإصدارات. أضاف Flow Builder أداة لمقارنة الإصدارات في Winter '26، ثم أضاف Summer '26 وضعًا مرئيًا يلوّن العناصر المضافة والمعدّلة والمحذوفة على الـ canvas.
  5. اعمل retrieve وcommit ودع الـ CI يتحقق من الـ Flow المدموج قبل المراجعة.

ولتعارضات أنواع الـ metadata الأخرى، راجع كيف تحل تعارضات metadata في Salesforce أثناء الدمج.

كيف تنشر الـ Flows من Git بأمان؟

  • توقّع أن تصل غير نشطة افتراضيًا. الـ Flows النشطة في الـ sandbox تُنشر إلى الإنتاج غير نشطة، إلا إذا فعّلت Deploy processes and flows as active في Process Automation Settings، وهذا الإعداد يتطلب تغطية اختبارات Apex ويشمل الـ processes والـ autolaunched Flows، لا الـ screen Flows.
  • اجعل التفعيل خطوة صريحة في الإصدار، لا شيئًا يتذكره أحد المسؤولين لاحقًا.
  • شغّل نشرًا من نوع check-only على كل pull request، حتى يفشل الـ Flow الذي يشير إلى حقل غير موجود في الـ CI، لا في نافذة الإصدار.

ما زلت تنشر الـ Flows عبر change sets؟ ابدأ بـ الانتقال من change sets إلى source control، ثم طبّق الخطوات السابقة.

أين تساعد الأدوات؟

منصات DevOps مثل Gearset وFlosum تضيف مقارنة ونشرًا يفهمان الـ Flows فوق Git، كما يقدّم Lifecycle Center من Salesforce (المعروف سابقًا باسم DevOps Center) توصيات بالذكاء الاصطناعي لحل التعارضات عبر أدوات MCP الخاصة به. أما Serpent فيحل التعارضات داخل الـ pull request نفسه: يقترح Serpent AI حلًا وينتظر مراجعتك قبل تطبيقه، ومراجعة الكود بالذكاء الاصطناعي متاحة في كل الخطط. اطّلع على خطط Serpent، أو تصفّح المزيد من أدلة Salesforce DevOps.

FAQ

هل يجب أن أحفظ ملفات FlowDefinition في Git؟

لا. منذ Metadata API v44 أصبح حقل status في الـ Flow نفسه هو ما يتحكم في التفعيل، ولم تعد Salesforce توصي بـ Flow Definitions لهذه المهمة.

هل يستطيع Git دمج إصدارين من الـ Flow نفسه تلقائيًا؟

قد ينتج دمجًا نظيفًا نصيًا، لكن Git لا يفهم منطق الـ Flow. افرض تعارضًا باستخدام -merge وأعد تطبيق أحد التغييرين في Flow Builder.

لماذا وصلت مسودة Flow إلى الـ repository عندي؟

الـ retrieve يعيد أحدث إصدار من الـ Flow، نشطًا كان أو مسودة. راجع قيمة status قبل الـ commit.

هل تهم تغييرات locationX وlocationY؟

هي تغيّر التخطيط فقط لا السلوك. راجعها كضوضاء، وتجنّب تبديل وضع الـ canvas حتى تبقى ثابتة.

مقالات ذات صلة

هل تريد معرفة كيف يمكنكم الشحن أسرع قبل البدء؟ لنتحدث

بدون التزام.