Полуавтоматическое увеличение версии проекта при работе с GIT в Visual Studio

В Интернетах написано немало статей об инкреминировании версий своих приложений и каждый использует свой метод. У кого-то ревизии используются в качестве «билдов», у кого-то это количество секунд текущих суток (например, Microsoft), у кого-то что-то другое.В моем проекте используются 4 определяющие версии.

Например, 1.2.34.56, где:1 — Major version: Критические изменения проекта (введен новый функционал, в корне переработан существующий и пр.). Устанавливается вручную;2 — Minor version: Изменение функциональных частей приложения, значительное улучшение кода и пр. Устанавливается вручную;24 — Build: номер релиза, попадающего в общество. Назначается автоматически;56 — Revision: номер ревизии, полученный с GIT. Назначается автоматически.

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

Шаг 1. ПодготовкаСперва нам нужно зайти в настройки проекта (Project → MyProject Properties). Здесь, во вкладке Application, идем в Assembly Information и проверяем, чтобы все 4 поля параметра Assembly version были заполнены, причем, первые 2 цифры указываем соответствующие нашему релизу. В моем случае это версия »2.3», а остальные цифры ставим любые.image

После внесения изменений нам нужно зайти в папку проекта и найти файл AssemblyInfo.cs, который обычно находится в папке Properties.Открываем файл на редактирование и в самом низу ищем строки:

// You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion (»1.0.*»)] [assembly: AssemblyVersion (»2.3.0.0»)] [assembly: AssemblyFileVersion (»2.3.0.0»)] Удаляем закомментированную строку:

// [assembly: AssemblyVersion (»1.0.*»)] Сделать это необходимо по той причине, что при записи новой версии будет использоваться регулярное выражение, считывающее ключевые цифры версии (major, minor) из первого найденного совпадения.Удалили, сохранили, закрыли файл. Более он нам не понадобится.Шаг 2. «ChangeRevision» Для удобства я скомпилировал консольное приложение, которое считывает значения major, minor и build из файла Properties\AssemblyInfo.cs, а также количество коммитов GIT.Итак, код ChangeRevision.exe: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.IO; using System.Diagnostics;

namespace ChangeRevision { class Program { static void Main (string[] args) { try { Process process = new Process (); process.StartInfo.FileName = »\«c:\\Program Files (x86)\\Git\\cmd\\git.exe\»; process.StartInfo.Arguments = @«rev-list master --count»; process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true;

StringBuilder output = new StringBuilder (); int timeout = 5000;

using (AutoResetEvent outputWaitHandle = new AutoResetEvent (false)) using (AutoResetEvent errorWaitHandle = new AutoResetEvent (false)) { process.OutputDataReceived += (sender, e) => { if (e.Data == null) outputWaitHandle.Set (); else output.AppendLine (e.Data); };

process.Start (); process.BeginOutputReadLine ();

if (process.WaitForExit (timeout) && outputWaitHandle.WaitOne (timeout)) { string text = File.ReadAllText (args[0] + @»\Properties\AssemblyInfo.cs»);

Match match = new Regex («AssemblyVersion\\(\»(.*?)\»\\)»).Match (text); Version ver = new Version (match.Groups[1].Value); int build = args[1] == «Release» ? ver.Build + 1: ver.Build; Version newVer = new Version (ver.Major, ver.Minor, build, Convert.ToInt16(output.ToString ().Trim ()));

text = Regex.Replace (text, @«AssemblyVersion\((.*?)\)», «AssemblyVersion (\» + newVer.ToString () + »\»)»); text = Regex.Replace (text, @«AssemblyFileVersionAttribute\((.*?)\)», «AssemblyFileVersionAttribute (\» + newVer.ToString () + »\»)»); text = Regex.Replace (text, @«AssemblyFileVersion\((.*?)\)», «AssemblyFileVersion (\» + newVer.ToString () + »\»)»);

File.WriteAllText (args[0] + @»\Properties\AssemblyInfo.cs», text); } } } catch (Exception ex) { Console.WriteLine (ex.Message); Console.WriteLine (»); Console.WriteLine (ex.StackTrace); Console.ReadLine (); }

} } } Скомпилированный файл кладем в директорию Solution.

Ниже подробнее распишу как работает данный код.

Шаг 3. Pre-Build Event Так как мне необходимо изменить версию билда перед компиляцией, код вписывается в окно Pre-Build Event. »$(SolutionDir)ChangeRevision.exe» »$(ProjectName)» $(ConfigurationName) image

Где:»$(SolutionDir)ChangeRevision.exe» — Указывается путь к solution с указанием запуска нашего скомпилированного файла, о котором написано выше.»$(ProjectName)» — Передаем имя проекта, для которого будем инкреминировать версию$(ConfigurationName) — Тип конфигурации (Debug или Release).Если при запуске файла ChangeRevision.exe был передан параметр Debug, то в версии проекта будет увеличено только значение ревизии, то есть, если было 2.3.0.0, то станет 2.3.0.х, где «х» — количество коммитов по проекту. Если передан параметр Release, то автоматически будет инкреминирован номер билда совместно с изменением ревизии по количеству коммитов. Например, было 2.3.0.0, станет 2.3.1.х, где «х» — количество коммитов по проекту.

Количество коммитов можно узнать путем передачи параметра

git rev-list master --count Это в том случае, если нужно получить количество коммитов из ветки MASTER.По завершению работы приложения будет изменен файл Properties\AssemblyInfo.cs, переданного в первом параметре, проекта, после чего среда разработки скомпилирует файл самого проекта с указанной в файле версией.P.S.: При изменении версии AssemblyVersion также изменяется и значение в параметре AssemblyFileVersion, а в некоторых случаях и AssemblyFileVersionAttribute.

Таким образом я достиг полуавтоматического инкреминирования версии своего приложения.

Спасибо за внимание!

© Habrahabr.ru