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

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

Ответов (19)

Решение

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

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

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

Но поскольку в этом вопросе есть тег Git, на ум приходит распределенная альтернатива, в которой настройки хранятся в частной тестовой ветке:

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

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

Теперь разработчики / тестировщики могут настраивать файл конфигурации по своему усмотрению и фиксировать эти изменения только локально в одной частной ветке тестирования (например, B '= B + настройки). Каждый раз, когда основная ветка продвигается вперед, они без особых усилий объединяют ее с тестированием, что приводит к коммитам слияния, таким как D '(= D + объединенная версия настроек B).

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

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

В наших конфигурационных файлах есть разделы LOCAL, DEV, QA, PRODUCTION, каждый из которых содержит ключи конфигурации, относящиеся к этой среде.

Что заставляет все это работать, так это сборка с именем xxx.Environment, на которую есть ссылки во всех наших приложениях (winforms и webforms), которая сообщает приложению, в какой среде оно работает.

Сборка xxx.Environment считывает одну строку информации из machine.config данной машины, которая сообщает ей, что она находится на DEV, QA и т. Д. Эта запись присутствует на всех наших рабочих станциях и серверах.

Надеюсь это поможет.

Я столкнулся с той же проблемой и нашел для нее решение. Сначала я добавил все файлы в центральный репозиторий (в том числе и файлы разработчика).

Поэтому, если разработчик извлекает файлы из репозитория, конфигурация разработчика также присутствует. При внесении изменений в этот файл 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

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

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

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

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

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

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

Поначалу этот процесс может быть немного сложным, но он имеет большие преимущества: 1. Вам никогда не придется беспокоиться о том, что файл конфигурации будет удален или изменен на сервере без резервной копии 2. То же самое, если у разработчика есть некоторая настраиваемая конфигурация на своем сервере. машина и его машина перестает работать по какой - либо причине 3. До любого развертывания вы можете дифф конфигурационных файлов development и staging, например , и посмотреть , если есть что - то отсутствует или сломана.

В настоящее время у меня есть файл конфигурации "шаблона" с добавленным расширением, например:

web.config.rename

Однако я могу увидеть проблему с этим методом, если изменились критические изменения.

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

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

@ Грант прав.

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

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

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

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

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

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

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

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

Кстати, я предпочитаю оставлять ".config" в конце в качестве расширения, чтобы ассоциации файлов не нарушались.

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

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

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

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

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

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

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

Здесь у нас две проблемы.

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

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

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

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

  • Есть 3-я проблема, на которую не распространяется вопрос / ответы. Как вы объединяете изменения, внесенные клиентом в ваш файл конфигурации, при установке новой версии вашего программного обеспечения?

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

  • Во-первых, уменьшите количество элементов конфигурации в основном файле конфигурации.

    Если вам не нужно позволять клиентам изменять ваши сопоставления, используйте Fluent NHibernate (или иначе), чтобы переместить конфигурацию в код.

    То же самое и для настройки внедрения зависимостей.

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

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

    (По умолчанию используйте относительный путь, поэтому редко приходится изменять файл web.config)

  • Обработайте файл конфигурации разработки, чтобы получить файл конфигурации доставки.

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

  • Вместо одной строки подключения к базе данных создайте по одной для каждого разработчика.

    Например, сначала найдите «database_ianr» (где ianr - мое имя пользователя или имя компьютера) в файле конфигурации во время выполнения, если он не найден, затем найдите «базу данных».

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

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

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

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

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

Я всегда хранил все версии файлов конфигурации в системе контроля версий в той же папке, что и файл 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 файлом конфигурации, подходящим для этой среды. Если файлы заархивированы, то ненужные файлы следует удалить из этой сборки.