Версионирование - это то, чем я очень увлечен и потратил много времени, пытаясь придумать простую в использовании систему управления версиями. Из того, что вы уже сказали в своем вопросе, ясно, что вы поняли один важный момент: номера версий сборки не являются синонимами версии продукта. Один - технически, а другой - бизнес.
Далее предполагается, что вы используете некоторую форму контроля версий и сервер сборки. Для контекста мы используем TeamCity и Subversion / Git. TeamCity бесплатен для небольшого (10) числа проектов и является очень хорошим сервером сборки, но есть и другие, некоторые из которых полностью бесплатны.
Что означает номер версии
То, что версия означает для одного человека, может означать что-то отличное от другого, общая структура мажорная, минорная, макро, микро. То, как я смотрю на номер версии, состоит в том, чтобы разбить его на две части. Первая половина описывает основную версию (Major) и любые ключевые обновления (Minor). Вторая половина указывает, когда это было построено и какова версия исходного кода. Номера версий также означают разные вещи в зависимости от контекста, это API, веб-приложение и т. Д.
Major
, Minor
, Build
,Revision
Revision
Это число, взятое из системы контроля версий для определения того, что на самом деле было построено.
Build
Это постоянно увеличивающееся число, которое можно использовать для поиска конкретной сборки на сервере сборки. Это важное число, потому что сервер сборки мог создать один и тот же источник дважды с другим набором параметров. Использование номера сборки в сочетании с номером источника позволяет определить, что и как было построено.
Minor
Это должно измениться только в случае значительных изменений в общедоступном интерфейсе. Например, если это API, будет ли компилироваться потребляющий код? Этот номер должен быть сброшен на ноль при изменении основного номера.
Major
указывает, на какой версии продукта вы находитесь. Например, основной из всех сборок VisualStudio 2008 - 9, а VisualStudio 2010 - 10.
Исключение из правила
Из этого правила всегда есть исключения, и вам придется приспосабливаться, когда вы сталкиваетесь с ними. Мой оригинальный подход был основан на использовании Subversion, но недавно я перешел на Git. Управление исходным кодом, такое как Subversion и Safe Source, которые используют центральный репозиторий, имеют номер, который можно использовать для идентификации определенного набора источников в данный момент времени. Это не относится к распределенному управлению источниками, такому как Git. Поскольку Git использует распределенные репозитории, которые есть на каждом компьютере разработчика, нет никакого автоматического увеличения числа, которое вы можете использовать, есть взлом, который использует количество проверок, но это уродливо. Из-за этого мне пришлось развивать свой подход.
Major
, Minor
, Macro
,Build
Теперь номер редакции исчез, сборка сместилась туда, где была ревизия, и был вставлен макрос. Вы можете использовать макрос так, как считаете нужным, но большую часть времени я оставляю его в покое. Поскольку мы используем TeamCity, информация, потерянная из номера ревизии, может быть найдена в сборке, это означает, что существует двухэтапный процесс, но мы ничего не потеряли и это приемлемый компромисс.
Что установить
Первое, что нужно понять, это то, что версия сборки, версия файла и версия продукта не должны совпадать. Я не выступаю за использование разных наборов чисел, но это значительно облегчает жизнь, если вносить небольшие изменения в сборку, которая не влияет на общедоступные интерфейсы, для которых вы не обязаны перекомпилировать зависимые сборки. Способ, которым я справляюсь с этим, состоит в том, чтобы установить только основные и второстепенные номера в версии сборки, но установить все значения в версии файла. Например:
- 1.2.0.0 (AssemblyVersion)
- 1.2.3.4 (FileVersion)
Это дает вам возможность развертывать оперативные исправления, которые не повредят существующий код, потому что версии сборок не совпадают, но позволяют вам увидеть ревизию / сборку сборки, посмотрев на номер версии ее файла. Это общий подход, который можно увидеть на некоторых сборках с открытым исходным кодом, когда вы смотрите на детали сборки.
Вы, как руководитель группы, должны будете нести ответственность за увеличение младшего номера, если когда-либо требуется срочное изменение. Одним из решений для внедрения необходимого изменения интерфейса, но без нарушения предыдущего кода, является пометка текущего как устаревшего и создание нового интерфейса. Это означает, что существующий код предупрежден о том, что метод устарел и может быть удален в любое время, но не требует, чтобы вы все сразу ломали. Затем вы можете удалить устаревший метод, когда все было перенесено.
Как связать это вместе
Вы можете сделать все вышеперечисленное вручную, но это займет очень много времени, вот как мы автоматизируем процесс. Каждый шаг выполняется.
- Удалите
AssemblyVersion
и AssemblyFileVersion
атрибуты из всех файлов проекта AssemblyInfo.cs.
- Создайте общий файл информации о сборке (назовите его VersionInfo.cs) и добавьте его в качестве связанного элемента во все ваши проекты.
- Добавьте
AssemblyVersion
и AssemblyFileVersion
атрибуты к версии со значениями «0.0.0.0».
- Создайте проект MsBuild, который создает файл вашего решения.
- Добавьте задачу перед сборкой, которая обновляет VersionInfo.cs. Существует несколько библиотек MsBuild с открытым исходным кодом, которые включают задачу AssemblyInfo, которая может установить номер версии. Просто установите его на произвольное число и проверьте.
- Добавьте группу свойств, содержащую свойство для каждого из сегментов номера сборки. Здесь вы устанавливаете мажор и минор. Номер сборки и ревизии должны быть переданы в качестве аргументов.
С подрывной деятельностью:
<PropertyGroup>
<Version-Major>0</Version-Major>
<Version-Minor>0</Version-Minor>
<Version-Build Condition=" '$(build_number)' == '' ">0</Version-Build>
<Version-Build Condition=" '$(build_number)' != '' ">$(build_number)</Version-Build>
<Version-Revision Condition=" '$(revision_number)' == '' ">0</Version-Revision>
<Version-Revision Condition=" '$(revision_number)' != '' ">$(revision_number)</Version-Revision>
</PropertyGroup>
Надеюсь, я был ясен, но многое вовлечено. Пожалуйста, задавайте любые вопросы. Я буду использовать любые отзывы, чтобы составить более краткий пост в блоге.