كيف تتعامل مع ملفات التكوين في التحكم بالمصادر؟

StackOverflow https://stackoverflow.com/questions/6009

  •  08-06-2019
  •  | 
  •  

سؤال

لنفترض أن لديك تطبيق ويب نموذجيًا وبه تكوين ملف مهما كان.سيكون لكل مطور يعمل في المشروع إصدار واحد لصناديق التطوير الخاصة به، وسيكون هناك إصدارات تطوير وإصدارات إنتاجية وإصدارات مسرحية.كيف تتعامل مع هذا في التحكم بالمصادر؟ألا تقوم بالتحقق من هذا الملف على الإطلاق، أو التحقق منه بأسماء مختلفة، أو القيام بشيء رائع تمامًا؟

هل كانت مفيدة؟

المحلول

ما قمت به في الماضي هو الحصول على ملف تكوين افتراضي تم تسجيل وصوله للتحكم بالمصدر.بعد ذلك، يكون لكل مطور ملف تكوين التجاوز الخاص به والذي يتم استبعاده من التحكم بالمصادر.يقوم التطبيق أولاً بتحميل الملف الافتراضي، ثم في حالة وجود ملف التجاوز، يقوم بتحميله ويستخدم أي إعدادات من التجاوز بدلاً من الملف الافتراضي.

بشكل عام، كلما كان ملف التجاوز أصغر كلما كان ذلك أفضل، لكنه يمكن أن يحتوي دائمًا على المزيد من الإعدادات لمطور لديه بيئة غير قياسية على الإطلاق.

نصائح أخرى

لا تقم بإصدار هذا الملف.إصدار قالب أو شيء من هذا.

إعدادات يكون الكود، ويجب عليك إصداره.نحن نبني ملفات التكوين الخاصة بنا على أسماء المستخدمين؛في كل من UNIX/Mac وWindows، يمكنك الوصول إلى اسم تسجيل الدخول الخاص بالمستخدم، وطالما أنها فريدة للمشروع، فلا بأس.يمكنك حتى تجاوز هذا في البيئة، لكنك يجب الإصدار يتحكم في كل شيء.

ويتيح لك هذا أيضًا فحص تكوينات الآخرين، مما قد يساعد في تشخيص مشكلات البناء والنظام الأساسي.

يحتفظ فريقي بإصدارات منفصلة من ملفات التكوين لكل بيئة (web.config.dev، web.config.test، web.config.prod).تقوم برامج النشر النصية الخاصة بنا بنسخ الإصدار الصحيح، وإعادة تسميته إلى web.config.بهذه الطريقة، لدينا تحكم كامل في الإصدار على ملفات التكوين لكل بيئة، ويمكننا بسهولة إجراء فرق، وما إلى ذلك.

لدي حاليًا ملف التكوين "القالب" مع ملحق مضاف على سبيل المثال:

web.config.rename

ومع ذلك، يمكنني رؤية مشكلة في هذه الطريقة إذا تغيرت التغييرات المهمة.

الحل الذي نستخدمه هو الحصول على ملف تكوين واحد فقط (web.config/app.config)، لكننا نضيف قسمًا خاصًا إلى الملف الذي يحتوي على الإعدادات لجميع البيئات.

هناك محلي، تطوير، ضمان الجودة، الإنتاج أقسام تحتوي كل منها على مفاتيح التكوين ذات الصلة بتلك البيئة في ملف (ملفات) التكوين الخاصة بنا.

ما يجعل كل هذا يعمل هو التجميع المسمى xxx.البيئة والتي يتم الرجوع إليها في جميع تطبيقاتنا (winforms وwebforms) والتي تخبر التطبيق بالبيئة التي يعمل عليها.

يقرأ تجميع xxx.Environment سطرًا واحدًا من المعلومات من ملف Machine.config للجهاز المحدد الذي يخبره أنه في وضع DEV و QA وما إلى ذلك.هذا الإدخال موجود على كافة محطات العمل والخوادم لدينا.

أتمنى أن يساعدك هذا.

+1 على نهج القالب.

ولكن نظرًا لأن هذا السؤال له علامة GIT ، فإن الينابيع البديلة الموزعة إلى الذهن ، حيث يتم الاحتفاظ بالتخصيصات على فرع اختبار خاص:

A---B---C---D---           <- mainline (public)
     \       \
      B'------D'---        <- testing (private)

في هذا المخطط ، يحتوي الخط الرئيسي على ملف تكوين "قالب" عام يتطلب الحد الأدنى من التعديلات ليصبح وظيفيًا.

الآن ، يمكن للمطورين/المختبرين تعديل ملف التكوين إلى محتوى قلبهم ، ويرتكبون هذه التغييرات محليًا فقط على فرع اختبار خاص (على سبيل المثالB' = B + التخصيصات).في كل مرة يتقدم فيها الخط الرئيسي ، يقومون بدمجها دون عناء في الاختبار ، مما يؤدي إلى اندماج ارتباط مثل D '(= D + نسخة مدمجة من التخصيصات B).

يتألق هذا المخطط حقًا عند تحديث ملف التكوين "القالب":يتم دمج التغييرات من كلا الجانبين ، ومن المحتمل جدًا أن تؤدي إلى تعارضات (أو فشل اختبار) إذا كانت غير متوافقة!

لقد استخدمت القالب من قبل، أي.web.dev.config وweb.prod.config وما إلى ذلك، ولكنك تفضل الآن تقنية "تجاوز الملف".يحتوي ملف web.config على غالبية الإعدادات، لكن الملف الخارجي يحتوي على قيم خاصة بالبيئة مثل اتصالات قاعدة البيانات.شرح جيد على مدونة بول ويلسون.

أعتقد أن هذا يقلل من مقدار الازدواجية بين ملفات التكوين التي يمكن أن تسبب الألم عند إضافة قيم/سمات جديدة.

لقد احتفظت دائمًا بجميع إصدارات ملفات التكوين في التحكم بالمصادر، في نفس المجلد مثل ملف web.config.

على سبيل المثال

web.config
web.qa.config
web.staging.config
web.production.config

أفضل اصطلاح التسمية هذا (على عكس web.config.production أو production.web.config) لأنه

  • فهو يحتفظ بالملفات معًا عند الفرز حسب اسم الملف
  • فهو يحتفظ بالملفات معًا عند الفرز حسب امتداد الملف
  • إذا تم دفع الملف عن طريق الخطأ إلى الإنتاج، فلن تتمكن من رؤية المحتويات عبر http لأن IIS سيمنع عرض ملفات *.config

يجب تكوين ملف التكوين الافتراضي بحيث يمكنك تشغيل التطبيق محليًا على جهازك الخاص.

والأهم من ذلك، أن هذه الملفات يجب أن تكون متطابقة بنسبة 100% تقريبًا في كل الجوانب، حتى التنسيق.يجب ألا تستخدم علامات التبويب في إصدار واحد والمسافات في إصدار آخر لوضع مسافة بادئة.يجب أن تكون قادرًا على تشغيل أداة الفرق على الملفات لمعرفة الفرق بينها بالضبط.أفضّل استخدام WinMerge لتمييز الملفات.

عندما تقوم عملية الإنشاء الخاصة بك بإنشاء الثنائيات، يجب أن تكون هناك مهمة تقوم بالكتابة فوق web.config بملف التكوين المناسب لتلك البيئة.إذا كانت الملفات مضغوطة، فيجب حذف الملفات غير ذات الصلة من هذا الإصدار.

@غرانت على حق.

أنا عضو في فريق يضم ما يقرب من 100 مطور آخر، ولا يتم فحص ملفات التكوين الخاصة بنا في التحكم بالمصادر.لدينا إصدارات من الملفات الموجودة في المستودع والتي يتم سحبها مع كل عملية سحب ولكنها لا تتغير.

لقد سار الأمر بشكل جيد بالنسبة لنا.

أنا أتحكم في الإصدار، لكن لا أدفعه أبدًا إلى الخوادم الأخرى.إذا كان خادم الإنتاج يتطلب تغييرًا، فأنا أقوم بإجراء هذا التغيير مباشرةً على ملف التكوين.

قد لا تكون جميلة، لكنها تعمل بشكل جيد.

يجب أن يكون الإصدار البسيط المسجل من app/web.config عامًا بما يكفي للعمل على جميع أجهزة المطورين، وأن يتم تحديثه بأي تغييرات جديدة في الإعدادات، وما إلى ذلك.إذا كنت تحتاج إلى مجموعة محددة من الإعدادات لإعدادات التطوير/الاختبار/الإنتاج، فتحقق من ملفات منفصلة بهذه الإعدادات، كما ذكر GateKiller، مع نوع من اصطلاح التسمية، على الرغم من أنني عادةً ما أستخدم "web.prod.config"، لأنه ليس كذلك. لتغيير امتداد الملف.

نحن نستخدم ملف تكوين القالب الذي تم تسجيله للتحكم في الإصدار ثم خطوة في البناء الآلي الخاص بنا لاستبدال إدخالات محددة في ملف القالب بإعدادات خاصة بالبيئة.يتم تخزين الإعدادات الخاصة بالبيئة في ملف XML منفصل يخضع أيضًا للتحكم في الإصدار.

نحن نستخدم MSBuild في نسختنا الآلية، لذلك نستخدم مهمة XmlUpdate من مهام المجتمع MSBuild لتحديث القيم.

لقد فعلت بالضبط ما فعلته شركة bcwood لفترة طويلة.أحتفظ بنسخ من web.dev.config، وweb.test.config، وweb.prod.config، وما إلى ذلك.تحت التحكم بالمصادر، ثم يقوم نظام الإنشاء/النشر الخاص بي بإعادة تسميتها تلقائيًا أثناء نشره في بيئات مختلفة.تحصل على قدر معين من التكرار بين الملفات (خاصة مع جميع عناصر asp.net الموجودة هناك)، ولكنها تعمل بشكل جيد بشكل عام.عليك أيضًا التأكد من أن كل فرد في الفريق يتذكر التحديث الجميع الملفات عندما يقومون بإجراء تغيير.

بالمناسبة، أحب الاحتفاظ بـ ".config" في النهاية كامتداد حتى لا تتعطل ارتباطات الملفات.

فيما يتعلق بإصدارات المطورين المحليين من ملف التكوين، فأنا دائمًا أبذل قصارى جهدي لتشجيع الأشخاص على استخدام نفس الإعدادات المحلية قدر الإمكان حتى لا تكون هناك حاجة لامتلاك إصدار خاص بك.لا يعمل هذا دائمًا مع الجميع، وفي هذه الحالة عادةً ما يقوم الأشخاص باستبداله محليًا حسب الحاجة والبدء من هناك.انها ليست مؤلمة جدا أو أي شيء.

في مشروعنا، لدينا تكوين مخزن في ملفات ذات بادئة، ثم يقوم نظام البناء الخاص بنا بسحب التكوين المناسب بناءً على اسم مضيف النظام الحالي.يعمل هذا بشكل جيد بالنسبة لنا في فريق صغير نسبيًا، مما يسمح لنا بتطبيق تغييرات التكوين على ملفات الأشخاص الآخرين إذا/عندما أضفنا عنصر تكوين جديدًا.من الواضح أن هذا بالتأكيد لا يتناسب مع المشاريع مفتوحة المصدر مع عدد غير محدود من المطورين.

لدينا مشكلتان هنا.

  • علينا أولاً التحكم في ملف التكوين الذي يتم شحنه مع البرنامج.

    من السهل على المطور التحقق من التغيير غير المرغوب فيه إلى ملف التكوين الرئيسي، إذا كان يستخدم نفس الملف في بيئة التطوير.

    على الجانب الآخر، إذا كان لديك ملف تكوين منفصل تم تضمينه بواسطة المثبت، فمن السهل جدًا أن تنسى إضافة إعداد جديد إليه، أو السماح للتعليقات الموجودة فيه بالخروج عن المزامنة مع التعليقات أثناء عملية التطوير ملف التكوين.

  • ثم نواجه مشكلة أنه يتعين على المطورين الاحتفاظ بنسخة من ملف التكوين محدثة حيث يقوم المطورون الآخرون بإضافة إعدادات تكوين جديدة.ومع ذلك، تختلف بعض الإعدادات مثل سلاسل اتصال قاعدة البيانات لكل مطور.

  • هناك مشكلة ثالثة لا يغطيها السؤال/الإجابات. كيف يمكنك دمج التغييرات التي أجراها العميل على ملف التكوين الخاص بك عند تثبيت إصدار جديد من برنامجك؟

لا يزال يتعين علي رؤية حلول جيدة تعمل بشكل جيد في جميع الحالات ، لكنني رأيت البعض حلول جزئية(يمكن دمجها في مجموعات مختلفة حسب الحاجة) التي تقلل من المشكلة كثيرًا.

  • قم أولاً بتقليل عدد عناصر التكوين الموجودة في ملف التكوين الرئيسي الخاص بك.

    إذا لم تكن بحاجة إلى السماح لعملائك بتغيير تعييناتك، فاستخدم Fluent NHibernate (أو غير ذلك) لنقل التكوين إلى التعليمات البرمجية.

    وبالمثل بالنسبة لإعداد حقن التبعية.

  • قم بتقسيم ملف التكوين عندما يكون ذلك ممكنًا، على سبيل المثال.استخدم ملفًا منفصلاً لتكوين ما تسجله Log4Net.

  • لا تكرر العناصر بين الكثير من ملفات التكوين، على سبيل المثال.إذا كان لديك 4 تطبيقات ويب مثبتة جميعها على نفس الجهاز، فامتلك ملف تكوين شامل يشير إليه ملف web.config في كل تطبيق.

    (استخدم مسارًا نسبيًا بشكل افتراضي، لذلك من النادر أن تضطر إلى تغيير ملف web.config)

  • قم بمعالجة ملف تكوين التطوير للحصول على ملف تكوين الشحن.

    يمكن إجراء ذلك من خلال وجود قيم افتراضية في تعليقات Xml التي يتم تعيينها بعد ذلك في ملف التكوين عند الانتهاء من الإنشاء.أو وجود أقسام محذوفة كجزء من عملية إنشاء المثبت.

  • بدلاً من وجود سلسلة اتصال واحدة بقاعدة البيانات، قم بإنشاء سلسلة واحدة لكل مطور.

    على سبيل المثال، ابحث أولاً عن "database_ianr" (حيث ianr هو اسم المستخدم أو اسم الجهاز الخاص بي) في ملف التكوين في وقت التشغيل، إذا لم يتم العثور عليه، فابحث عن "قاعدة البيانات"

    احصل على المستوى الثاني "على سبيل المثال.-Oracle أو -sqlserver" يجعل الأمر أسرع للمطورين للوصول إلى نظامي قاعدة البيانات.

    ويمكن بالطبع القيام بذلك أيضًا لأي قيمة تكوين أخرى.

    بعد ذلك يمكن حذف كافة القيم التي تنتهي بـ "_userName" قبل شحن ملف التكوين.

ومع ذلك ، في النهاية ، ما هو "مالك ملف التكوين" يأخذ بمسؤولية إدارة ملف (ملفات) التكوين على النحو الوارد أعلاه أو غير ذلك.يجب عليه/لها أيضًا القيام بفرق على ملف تكوين واجهات العملاء قبل كل شحنة.

لا يمكنك إلغاء الحاجة إلى شخص يعتني ببعض هذه المشاكل.

لا أعتقد أن هناك حلًا واحدًا يصلح لجميع الحالات لأنه قد يعتمد على حساسية البيانات في ملفات التكوين، أو لغة البرمجة التي تستخدمها، والعديد من العوامل الأخرى.لكنني أعتقد أنه من المهم الاحتفاظ بملفات التكوين لجميع البيئات تحت التحكم بالمصادر، حتى تتمكن دائمًا من معرفة متى تم تغييرها ومن قام بتغييرها، والأهم من ذلك، أن تكون قادرًا على استعادتها إذا ساءت الأمور.وسوف يفعلون.

إذن هذه هي الطريقة التي أفعل بها ذلك.هذا مخصص لمشاريع العقدة عادةً ولكن أعتقد أنه يعمل مع الأطر واللغات الأخرى أيضًا.

ما أفعله هو إنشاء ملف configs الدليل في جذر المشروع، وتحت هذا الدليل احتفظ بملفات متعددة لجميع البيئات (وفي بعض الأحيان ملفات منفصلة لكل بيئة مطور أيضًا) والتي يتم تعقبها جميعًا في التحكم بالمصادر.وهناك الملف الفعلي الذي يستخدمه الكود المسمى config في جذر المشروع.هذا هو الملف الوحيد الذي لم يتم تعقبه.لذلك يبدو مثل هذا

root
|
|- config (not tracked)
|
|- configs/ (all tracked)
    |- development
    |- staging
    |- live
    |- James

عندما يقوم شخص ما بفحص المشروع، يقوم بنسخ ملف التكوين الذي يريد استخدامه في الملف غير المتعقب config وهو حر في تعديله كما يشاء ولكنه مسؤول أيضًا عن نسخ هذه التغييرات قبل أن يلتزم بملفات البيئة الأخرى حسب الحاجة.

وعلى الخوادم، يمكن أن يكون الملف الذي لم يتم تعقبه ببساطة نسخة (أو مرجعًا) من الملف الذي تم تعقبه والذي يتوافق مع تلك البيئة.في JS، يمكنك ببساطة الحصول على سطر واحد لطلب هذا الملف.

قد يكون هذا التدفق معقدًا بعض الشيء في البداية ولكن له مزايا رائعة:1.لا داعي للقلق أبدًا بشأن حذف ملف التكوين أو تعديله على الخادم دون الحصول على نسخة احتياطية 2.الشيء نفسه إذا كان لدى المطور بعض التكوين المخصص على جهازه ويتوقف جهازه عن العمل لأي سبب من الأسباب 3.قبل أي عملية نشر، يمكنك تغيير ملفات التكوين الخاصة بها development و staging على سبيل المثال ومعرفة ما إذا كان هناك أي شيء مفقود أو مكسور.

نحن فقط نحتفظ بملف تكوين الإنتاج محددًا.تقع على عاتق المطور مسؤولية تغيير الملف عند سحبه من المصدر الآمن للتدريج أو التطوير.لقد أحرقنا هذا في الماضي لذا لا أقترح ذلك.

لقد واجهت نفس المشكلة ووجدت حلاً لها.لقد قمت أولاً بإضافة جميع الملفات إلى المستودع المركزي (أيضًا ملفات المطورين).

لذا، إذا قام أحد المطورين بإحضار الملفات من المستودع، فإن تكوين المطور موجود أيضًا هناك.عند إجراء تغيير على هذا الملف، يجب ألا يكون Git على علم بهذه التغييرات.بهذه الطريقة لا يمكن دفع/إلزام التغييرات بالمستودع ولكنها تظل محلية.

لقد قمت بحل هذه المشكلة باستخدام الأمر git: update-index --assume-unchanged.لقد قمت بإنشاء ملف بات يتم تنفيذه في الإنشاء المسبق للمشاريع التي تحتوي على ملف يجب أن يتجاهل Git تغييراته.هذا هو الكود الذي وضعته في ملف الخفافيش:

IF NOT EXIST %2%\.git GOTO NOGIT
set fileName=%1
set fileName=%fileName:\=/%
for /f "useback tokens=*" %%a in ('%fileName%') do set fileName=%%~a
set "gitUpdate=git update-index --assume-unchanged"
set parameter= "%gitUpdate% %fileName%"
echo %parameter% as parameter for git
"C:\Program Files (x86)\Git\bin\sh.exe" --login -i -c %parameter%
echo Make FIleBehaveLikeUnchangedForGit Done.
GOTO END
:NOGIT
echo no git here.
echo %2%
:END

في البناء المسبق الخاص بي، كنت سأقوم باستدعاء ملف الخفافيش، على سبيل المثال:

call "$(ProjectDir)\..\..\MakeFileBehaveLikeUnchangedForGit.bat" "$(ProjectDir)Web.config.developer" "$(SolutionDir)"

لقد وجدت في SO ملف الخفافيش الذي ينسخ ملف التكوين الصحيح إلى web.config/app.config.أقوم أيضًا باستدعاء ملف الخفافيش هذا في مرحلة ما قبل البناء.رمز ملف الخفافيش هذا هو:

@echo off
echo Comparing two files: %1 with %2
if not exist %1 goto File1NotFound
if not exist %2 goto File2NotFound
fc %1 %2 
if %ERRORLEVEL%==0 GOTO NoCopy
echo Files are not the same.  Copying %1 over %2
copy %1 %2 /y & goto END
:NoCopy
echo Files are the same.  Did nothing
goto END
:File1NotFound
echo %1 not found.
goto END
:File2NotFound
copy %1 %2 /y
goto END
:END
echo Done.

في البناء المسبق الخاص بي، كنت سأقوم باستدعاء ملف الخفافيش، على سبيل المثال:

call "$(ProjectDir)\..\..\copyifnewer.bat" "$(ProjectDir)web.config.$(ConfigurationName)" "$(ProjectDir)web.config
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top