Как вы работаете с файлами конфигурации в системе контроля версий?


97

Допустим, у вас есть типичное веб-приложение с файлом configuration.w независимо. У каждого разработчика, работающего над проектом, будет одна версия для своих боксов разработчика, это будут версии dev, prod и stage. Как вы справляетесь с этим в системе контроля версий? Не проверять этот файл вообще, проверять его с другими именами или вообще делать что-то необычное?

Ответы:


70

Раньше я создавал конфигурационный файл по умолчанию, который зарегистрирован в системе управления версиями. Затем у каждого разработчика есть собственный файл конфигурации переопределения, который исключается из системы управления версиями. Приложение сначала загружает значение по умолчанию, а затем, если присутствует файл переопределения, загружает его и использует любые настройки из переопределения в предпочтении к файлу по умолчанию.

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


24

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

Это также позволяет вам проверять конфигурации других пользователей, что может помочь в диагностике проблем сборки и платформы.


10
+1 абсолютно за то, что подчеркиваю, что конфигурация все еще должна быть версией
Александр Берд

И если имя пользователя по какой-либо причине ненадежно, тогда у вас может быть один файл только с одной строкой, в которой указано имя файла конфигурации переопределения. Таким образом, очень мало (например, около 10 символов) не контролируется версией. И файл README может объяснить, что вам нужно создать этот файл.
Александр Бёрд

Я всегда считаю, что конфигурации следует хранить отдельно от кода. Я работал в местах, где требуется так много конфигураций для одного репо, что Git просто завален конфигурационными файлами. Не говоря уже о том, что конфиги не должны версироваться, они принадлежат другому месту, как менеджер артефактов. Конфиг - это не код, это настройки кода.
Thomas

Файлы конфигурации могут содержать конфиденциальную информацию, например пароли, для которых не требуется версионирование. Или вы хотите предоставить каждому разработчику доступ к вашей производственной среде? Я думаю, что лучше просто создать версию «основной конфигурации» и переопределить ее в определенных средах.
Christophe Weis

19

Не редактируйте этот файл. Версия шаблона или что-то в этом роде.


2
Я использую этот подход, у меня есть только main.php.tmpl, и когда я оформляю новую копию, просто копирую ее в main, php. Я добавляю файл main.php в список игнорирования, чтобы случайно не зафиксировать его.
левхита

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

Эта схема действительно проявляется при обновлении конфигурационного файла "шаблона": изменения с обеих сторон объединяются и с большой вероятностью могут привести к конфликтам (или ошибкам тестирования), если они несовместимы!


Но когда разработчики-тестеры переходят в основную ветку, их изменения в файл шаблона также будут перенесены. Нет?
Ник Залуцкий

Если нет решения для комментария Ника, это не сработает, исходя из того, что я вижу. Или, может быть, объясните, какую модель потока вы используете, чтобы решить проблему.
Александр Бёрд

Я согласен с шаблонным подходом с любыми необходимыми корректировками, внесенными во время сборки. Однако по теме ветвления ... Что, если бы было несколько шаблонов (dev, test и т. Д.), И разработчики просто опускали изменения в своих коммитах. Не надежен, но может работать при сотрудничестве.
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% идентичными во всех аспектах, даже в форматировании. Вы не должны использовать табуляцию в одной версии и пробелы в другой для отступов. У вас должна быть возможность запустить инструмент сравнения файлов, чтобы точно увидеть, что между ними различается. Я предпочитаю использовать WinMerge для просмотра файлов.

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


4

Раньше я использовал этот шаблон, то есть web.dev.config, web.prod.config и т.д., но теперь предпочитаю технику «переопределения файла». Файл web.config содержит большинство настроек, но внешний файл содержит значения, зависящие от среды, такие как подключения к базе данных. Хорошее объяснение в блоге Пола Уилсона .

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


3

@ Грант прав.

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

У нас все получилось очень хорошо.


2

Я контролирую его версии, но никогда не передаю его другим серверам. Если производственный сервер требует изменения, я вношу это изменение непосредственно в файл конфигурации.

Это может быть некрасиво, но работает отлично.


2

Зарегистрированная, простая ванильная версия app / web.config должна быть достаточно общей, чтобы работать на всех машинах разработчика, и постоянно обновляться при любых новых изменениях настроек и т. Д. Если вам требуется определенный набор настроек для разработчика / test / production settings, проверьте отдельные файлы с этими настройками, как заявил GateKiller, с каким-то соглашением об именах, хотя я обычно использую «web.prod.config», чтобы не изменять расширение файла.


2

Мы используем файл конфигурации шаблона, который регистрируется для контроля версий, а затем шаг в нашей автоматической сборке для замены определенных записей в файле шаблона настройками, зависящими от среды. Параметры среды хранятся в отдельном XML-файле, который также находится под контролем версий.

Мы используем MSBuild в нашей автоматической сборке, поэтому мы используем задачу XmlUpdate из задач сообщества MSBuild для обновления значений.


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 - мое имя пользователя или имя компьютера) в файле конфигурации во время выполнения, если он не найден, затем найдите «базу данных».

    Наличие второго уровня «например -oracle или -sqlserver» позволит разработчикам быстрее добраться до обеих систем баз данных.

    Конечно, это также можно сделать для любого другого значения конфигурации.

    Затем все значения, оканчивающиеся на «_userName», могут быть удалены перед отправкой файла конфигурации.

Однако, в конце концов, вы являетесь «владельцем файла конфигурации», который несет ответственность за управление файлом (ами) конфигурации, как указано выше, или иным образом. Он / она также должен делать различие в файле конфигурации клиентского интерфейса перед каждой отправкой.

Невозможно избавиться от потребности в заботливом человеке, если не считать проблем.


1

Я не думаю, что существует единое решение, которое работает для всех случаев, так как оно может зависеть от чувствительности данных в файлах конфигурации, используемого вами языка программирования и многих других факторов. Но я думаю, что важно держать файлы конфигурации для всех сред под контролем источника, чтобы вы всегда могли знать, когда они были изменены и кем, и, что более важно, иметь возможность восстановить их, если что-то пойдет не так. И они это сделают.

Итак, вот как я это делаю. Обычно это для проектов nodejs, но я думаю, что это работает и для других фреймворков и языков.

Что я делаю, так это создаю configsкаталог в корне проекта и в этом каталоге храню несколько файлов для всех сред (а иногда и отдельные файлы для каждой среды разработчика), которые все отслеживаются в системе контроля версий. И есть фактический файл, который использует код, названный configв корне проекта. Это единственный файл, который не отслеживается. Так это выглядит так

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

Когда кто-то проверяет проект, он копирует файл конфигурации, который хочет использовать в неотслеживаемом config файле, и может редактировать его желанию, но также несет ответственность за копирование этих изменений, прежде чем он изменения в другие файлы среды.

А на серверах неотслеживаемый файл может быть просто копией (или ссылкой) отслеживаемого файла, соответствующего этой среде. В JS у вас может быть всего одна строка для запроса этого файла.

Поначалу этот процесс может быть немного сложным, но он имеет большие преимущества: 1. Вам никогда не придется беспокоиться о том, что файл конфигурации будет удален или изменен на сервере без резервной копии 2. То же самое, если у разработчика есть некоторая настраиваемая конфигурация на своем машина и его машина перестает работать по какой - либо причине 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 в предварительной сборке. Код этого файла 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.