Напівавтоматичне збільшення версії проекту при роботі з 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 і створити з файлу 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-master list --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-master list --count

Це в тому випадку, якщо потрібно отримати кількість комітів з гілки MASTER.

По завершенню роботи програми буде змінений файл Properties\AssemblyInfo.cs, переданого в першому параметрі, проекту, після чого середовище розробки скомпилирует файл самого проекту з зазначеної у файлі версією.
P.S.: При зміні версії AssemblyVersion також змінюється і значення в параметрі AssemblyFileVersion, а в деяких випадках і AssemblyFileVersionAttribute.

Таким чином я досяг напівавтоматичного инкреминирования версії своєї програми.

Спасибі за увагу!

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.