Як ви працюєте з файлами конфігурації в системі керування джерелами?


96

Скажімо, у вас типовий веб-додаток із конфігурацією файлу. Як завгодно. Кожен розробник, який працює над проектом, матиме одну версію для своїх блоків розробників, існуватимуть версії для розробників, продюсерів та версій. Як ви працюєте з цим у контролі джерел? Не перевіряти цей файл взагалі, перевіряти його з різними іменами чи взагалі робити щось фантазійне?

Відповіді:


69

Що я робив у минулому, це мати конфігураційний файл за замовчуванням, який реєструється в джерелі керування. Потім кожен розробник має власний конфігураційний файл перевизначення, який виключається з контролю джерела. Додаток спочатку завантажує за замовчуванням, а потім, якщо присутній файл заміни, завантажує та використовує будь-які налаштування із заміщення, а не файлу за замовчуванням.

Загалом, чим менше файл заміни, тим краще, але він завжди може містити більше налаштувань для розробника з дуже нестандартним середовищем.


24

Конфігурація - це код, і ви повинні її оформити. В основі наших конфігураційних файлів лежать імена користувачів; як в UNIX / Mac, так і в Windows ви можете отримати ім'я користувача для входу, і поки вони унікальні для проекту, ви в порядку. Ви можете навіть замінити це в середовищі, але ви повинні контролювати все.

Це також дозволяє вивчити конфігурації інших користувачів, які можуть допомогти діагностувати проблеми зі збіркою та платформою.


10
+1 абсолютно для того, щоб наголосити на тому, що конфігурація все-таки повинна бути версій
Alexander Bird

І якщо ім’я користувача з будь-якої причини не є надійним, тоді у вас може бути один файл із лише одним рядком, що вказує ім’я файлу конфігурації заміни. Таким чином, є дуже мало (наприклад, приблизно 10 символів), які не контролюються версіями. І файл README може пояснити, що вам потрібно створити цей файл.
Alexander Bird

Я завжди думаю, що конфігурації слід тримати окремо від коду. Я працював у місцях, які вимагають стільки конфігурацій для одного репо, що Git просто перевантажується конфігураційними файлами. Не кажучи про те, що конфігури не повинні бути версіями, вони належать деінде, як менеджер артефактів. Config - це не код, це налаштування коду.
Томас

Файли конфігурації можуть містити конфіденційну інформацію, таку як паролі, які не слід версувати. Або ви хочете надати кожному розробнику доступ до вашого виробничого середовища? Я думаю, що краще просто встановити версію "master config" і замінити її в конкретних середовищах.
Крістоф Вайс

19

Не встановлюйте версію цього файлу. Версія шаблону або щось інше.


2
Я використовую цей підхід, у мене просто є main.php.tmpl, і коли я отримую нову копію, просто скопіюйте її в main, php. Я додаю файл main.php до списку ігнорувань, щоб уникнути випадкового його здійснення.
levhita

10

Моя команда зберігає окремі версії конфігураційних файлів для кожного середовища (web.config.dev, web.config.test, web.config.prod). Наші сценарії розгортання копіюють правильну версію, перейменовуючи її у web.config. Таким чином, ми маємо повний контроль версій файлів конфігурації для кожного середовища, можемо легко виконувати різницю тощо.


6

На даний момент у мене є конфігураційний файл "шаблон" із доданим розширенням, наприклад:

web.config.rename

Однак я бачу проблему з цим методом, якщо змінилися критичні зміни.


6

+1 на підході до шаблону.

Але оскільки це запитання має тег Git, на думку спадає розподілена альтернатива, в якій налаштування зберігаються у приватній гілці тестування:

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

У цій схемі основна лінія містить загальний конфігураційний файл "шаблон", який вимагає мінімальної кількості коригувань, щоб стати функціональним.

Тепер розробники / тестувальники можуть налаштувати файл конфігурації на власний розсуд, і здійснювати ці зміни локально лише в одній приватній гілці тестування (наприклад, B '= B + налаштування). Щоразу, коли основна лінія просувається, вони без зусиль об’єднують її в тестування, що призводить до комітів об’єднання, таких як D '(= D + об’єднана версія налаштувань B).

Ця схема справді світить, коли конфігураційний файл "шаблону" оновлюється: зміни з обох сторін об'єднуються, і вкрай ймовірно можуть призвести до конфліктів (або невдалих тестів), якщо вони несумісні!


Але коли розробники-тестери натиснуть на основну лінію, їх зміни до файлу шаблону будуть також введені. Немає?
Нік Залуцький

Якщо не буде вирішено коментар Ніка, це не спрацює з того, що я бачу. Або, можливо, поясніть, яку модель потоку ви використовуєте, яка б вирішила проблему.
Олександр Птах

Я погоджуюся з підходом шаблону з будь-якими необхідними коригуваннями, внесені під час збірки. Однак щодо теми розгалуження ... Що, якби було декілька шаблонів (розробник, тест тощо), а розробники просто опускали б зміни зі своїх комітів. Не надійний, але може працювати разом.
NickSuperb

5

Рішення, яке ми використовуємо, полягає в тому, щоб мати лише один файл конфігурації (web.config / app.config), але ми додаємо до файлу спеціальний розділ, який містить налаштування для всіх середовищ.

У наших файлах конфігурації є розділи LOCAL, DEV, QA, PRODUCTION, кожен з яких містить ключі конфігурації, що мають відношення до цього середовища.

Все, що змушує цю роботу працювати, - це збірка з іменем xxx.Environment, на яку посилаються всі наші програми (winforms та webforms), яка повідомляє програмі, в якому середовищі вона працює.

Збірка xxx.Environment зчитує один рядок інформації з machine.config даної машини, який повідомляє їй, що вона знаходиться на DEV, QA тощо. Цей запис є на всіх наших робочих станціях і серверах.

Сподіваюся, це допомагає.


1
Це працює надзвичайно добре, якщо між середовищем існує лише невелика різниця (тобто рядки з'єднань)
Ерік Лабашоський,

і припускаючи, що розробників не всі сотні розробників також розміщують там свої власні налаштування (це все одно буде працювати, але буде дуже громіздким)
Олександр Берд,

5

Я завжди зберігав усі версії конфігураційних файлів у контролі джерела, в тій же папці, що і файл web.config.

Наприклад

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

Я віддаю перевагу цій конвенції іменування (на відміну від web.config.production або production.web.config), оскільки

  • Він зберігає файли разом, коли ви сортуєте за назвою файлу
  • Він зберігає файли разом при сортуванні за розширенням файлу
  • Якщо файл випадково потрапить до робочої версії, ви не зможете побачити вміст через http, оскільки IIS запобігає обслуговуванню файлів * .config

Файл конфігурації за замовчуванням повинен бути налаштований таким чином, щоб ви могли запускати програму локально на власній машині.

Найголовніше, що ці файли повинні бути майже на 100% однакові в усіх аспектах, навіть у форматуванні. Не слід використовувати відступи в одній версії, а пробіли в іншій для відступу. Ви повинні мати можливість запустити інструмент diff проти файлів, щоб точно побачити, що між ними різниться. Я вважаю за краще використовувати WinMerge для розробки файлів.

Коли ваш процес побудови створює двійкові файли, має бути завдання, яке замінює web.config файлом конфігурації, відповідним для цього середовища. Якщо файли заархівовані, тоді невідповідні файли слід видалити з цієї збірки.


4

Я використовував шаблон раніше, тобто web.dev.config, web.prod.config тощо, але зараз віддаю перевагу техніці "перевизначення файлу". Файл web.config містить більшість налаштувань, але зовнішній файл містить значення, специфічні для оточення, такі як з'єднання db. Гарне пояснення в блозі Пола Вільсона .

Я думаю, це зменшує кількість копій між конфігураційними файлами, що може спричинити біль при додаванні нових значень / атрибутів.


3

@Grant має рацію.

Я працюю в команді, де працює близько 100 інших розробників, і наші конфігураційні файли не перевіряються у джерелі керування. У нас є версії файлів у сховищі, які витягуються під час кожного виписки, але вони не змінюються.

У нас це вийшло досить добре.


2

Я керую версією, але ніколи не надсилаю її на інші сервери. Якщо робочий сервер вимагає змін, я вношу ці зміни безпосередньо у файл конфігурації.

Це може бути не красиво, але працює чудово.


2

Зареєстрована, проста ванільна версія app / web.config повинна бути загальною, щоб працювати на всіх машинах розробників, і бути в курсі будь-яких нових змін налаштувань тощо. Якщо вам потрібен певний набір налаштувань для dev / test / production налаштування, перевіряйте окремі файли з цими налаштуваннями, як зазначив GateKiller, з певними правилами іменування, хоча я зазвичай йду з "web.prod.config", щоб не змінювати розширення файлу.


2

Ми використовуємо файл конфігурації шаблону, який перевіряється на контроль версій, а потім крок у нашій автоматизованій збірці, щоб замінити певні записи у файлі шаблону на налаштування, що стосуються оточення. Налаштування середовища зберігаються в окремому файлі XML, який також контролюється версіями.

Ми використовуємо MSBuild у нашій автоматизованій збірці, тому для оновлення значень використовуємо завдання XmlUpdate від MSBuild Community Tasks .


2

Довгий час я робив саме те, що робив bcwood. Я зберігаю копії web.dev.config, web.test.config, web.prod.config тощо під контролем джерела, а потім моя система побудови / розгортання перейменовує їх автоматично, коли розгортається в різних середовищах. Ви отримуєте певну кількість надмірностей між файлами (особливо з усіма матеріалами asp.net), але загалом це працює дуже добре. Ви також повинні переконатися, що всі учасники команди пам’ятають про оновлення всіх файлів, коли вносять зміни.

До речі, я люблю зберігати ".config" наприкінці як розширення, щоб асоціації файлів не порушувались.

Що стосується версій конфігураційного файлу для місцевих розробників, я завжди з усіх сил намагаюся заохотити людей використовувати ті самі локальні налаштування, наскільки це можливо, щоб не було необхідності мати власну версію. Це не завжди працює для всіх, і в цьому випадку люди, як правило, просто замінюють його локально, якщо потрібно, і переходять звідти. Це не надто боляче або що-небудь.


1

У нашому проекті ми маємо конфігурацію, що зберігається у файлах із префіксом, тоді наша система збірки втягує відповідну конфігурацію на основі поточного імені хосту системи. Це добре працює для нас порівняно невеликою командою, що дозволяє застосовувати зміни конфігурації до файлів інших людей, якщо / коли ми додаємо новий елемент конфігурації. Очевидно, що це однозначно не стосується проектів з відкритим кодом з необмеженою кількістю розробників.


1

У нас тут дві проблеми.

  • По-перше, ми повинні контролювати файл конфігурації, який постачається разом із програмним забезпеченням.

    Розробнику дуже легко перевірити небажаний перехід на головний конфігураційний файл, якщо він використовує один і той же файл у середовищі розробки.

    З іншого боку, якщо у вас є окремий файл конфігурації, який включений програмою встановлення, дуже легко забути додати до нього нове налаштування або дозволити коментарям у ньому не синхронізуватися з коментарями у розробці. налаштування файлу.

  • Тоді у нас проблема, що розробники повинні постійно оновлювати копію файлу конфігурації, оскільки інші розробники додають нові параметри конфігурації. Однак деякі параметри, такі як рядки підключення до бази даних, різні для кожного розробника.

  • Існує 3-та проблема, яку питання / відповіді не охоплюють. Як ви об’єднуєте зміни, внесені клієнтом у ваш файл конфігурації під час встановлення нової версії програмного забезпечення?

Я ще не побачив хороших рішень, які добре працюють у всіх випадках, проте я бачив деякі часткові рішення (які за необхідності можна комбінувати в різних комбінаціях), що значно зменшує проблему.

  • По-перше, зменште кількість елементів конфігурації у вашому основному файлі конфігурації.

    Якщо вам не потрібно дозволяти своїм клієнтам змінювати ваші зіставлення, використовуйте Fluent NHibernate (або іншим чином), щоб перенести конфігурацію в код.

    Аналогічно для налаштування ін'єкції надійності.

  • Розділіть файл конфігурації, коли це можливо, наприклад, використовуйте окремий файл, щоб налаштувати журнали Log4Net.

  • Не повторюйте елементи між безліччю файлів конфігурації, наприклад, якщо у вас 4 веб-програми, які всі встановлені на одній машині, майте загальний файл конфігурації, на який вказує файл web.config у кожному додатку.

    (Використовуйте відносний шлях за замовчуванням, тому рідко доводиться змінювати файл web.config)

  • Обробіть файл конфігурації розробки, щоб отримати файл конфігурації доставки.

    Це може бути зроблено, якщо в коментарях Xml є значення за замовчуванням, які потім встановлюються у файлі конфігурації після завершення збірки. Або мати розділи, які видаляються як частина процесу створення інсталятора.

  • Замість того, щоб мати лише один рядок підключення до бази даних, укажіть по одному на кожного розробника.

    Наприклад, спочатку шукайте “database_ianr” (де ianr - це моє ім’я користувача чи ім’я машини) у файлі конфігурації під час запуску, якщо його не знайти, то шукайте “база даних”

    Майте 2-й рівень "наприклад -oracle або -sqlserver", щоб розробники швидше дісталися до обох систем баз даних.

    Звичайно, це можна зробити і для будь-якого іншого значення конфігурації.

    Тоді всі значення, які закінчуються на "_userName", можна видалити перед доставкою файлу конфігурації.

Однак в кінцевому підсумку ви є "власником конфігураційного файлу", який відповідально відповідає за управління конфігураційним файлом (файлами), як зазначено вище або іншим чином. Він / вона також повинен робити різницю щодо файлу конфігурації облицювання клієнта перед кожною відправкою.

Ви не можете усунути потребу в турботливій людині, яка вирішує цю проблему.


1

Я не думаю, що існує єдине рішення, яке працює для всіх випадків, оскільки воно може залежати від чутливості даних у конфігураційних файлах, або мови програмування, яку ви використовуєте, та багатьох інших факторів. Але я думаю, що важливо тримати конфігураційні файли для всіх середовищ під контролем джерела, щоб ви завжди могли знати, коли вони були змінені, і ким, і, що більш важливо, мати можливість відновити його, якщо щось піде не так. І вони будуть.

Тож ось як я це роблю. Зазвичай це для проектів nodejs, але я думаю, що це працює і для інших фреймворків та мов.

Що я роблю, це створюю configsкаталог в корені проекту, і в цьому каталозі зберігаю декілька файлів для всіх середовищ (а іноді і окремі файли для середовища кожного розробника), які всі відстежуються в контролі джерела. І є власне файл, який код використовує, названий configу корені проекту. Це єдиний файл, який не відстежується. Тож виглядає так

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

Коли хтось перевіряє проект, він копіює файл конфігурації, який він хоче використати у невідстежуваному configфайлі, і він може вільно редагувати його, як хоче, але також відповідає за копіювання цих змін до того, як він зафіксує інші файли середовища за необхідності.

А на серверах відстежуваний файл може бути просто копією (або посиланням) відстежуваного файлу, що відповідає цьому середовищу. У JS ви можете просто мати 1 рядок, щоб вимагати цей файл.

Спочатку цей потік може бути дещо складним, але він має великі переваги: ​​1. Вам ніколи не доведеться турбуватися про те, що конфігураційний файл буде видалений або змінений на сервері, не маючи резервної копії. Те саме, якщо розробник має власну конфігурацію на своєму машина та його машина перестають працювати з будь-якої причини 3. Перед будь-яким розгортанням ви можете розробити конфігураційні файли development і, stagingнаприклад, і перевірити, чи немає чого-небудь відсутнього чи зламаного.


0

Ми просто перевіряємо робочий конфігураційний файл. Розробник несе відповідальність за зміну файлу, коли він витягує його з безпечного джерела для постановки або розробки. Це нас згоріло в минулому, тому я б не пропонував цього.


0

Я зіткнувся з цією ж проблемою і знайшов її рішення. Спочатку я додав усі файли до центрального сховища (також для розробників).

Отже, якщо розробник виймає файли зі сховища, конфігурація розробника також там. Змінюючи зроблений файл, Git не повинен знати про ці зміни. Таким чином, зміни не можна надсилати / фіксувати у сховищі, але залишатися локально.

Я вирішив цю проблему за допомогою Git команди: update-index --assume-unchanged. Я створив файл bat, який виконується у попередній збірці проектів, що містять файл, зміни якого Git повинен ігнорувати. Ось код, який я помістив у файл bat:

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

У своїй попередній збірці я зробив би виклик файлу bat, наприклад:

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

Я знайшов у SO файл bat, який копіює правильний конфігураційний файл у web.config / app.config. Я також називаю цей файл bat у попередній збірці. Код цього файлу летючої миші:

@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.

У своїй попередній збірці я зробив би виклик файлу bat, наприклад:

call "$(ProjectDir)\..\..\copyifnewer.bat" "$(ProjectDir)web.config.$(ConfigurationName)" "$(ProjectDir)web.config
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.