Minule jsme si ukázali jak docílit automatické aktualizaci čísla file verze assembly při kompilaci C# projektu nebo celé solution. Řešením bylo vytvoření vlastního MSBuild tasku, který před vlastním buildem (BeforeBuild) přepsal hodnotu atributu AssemblyFileVersion v souboru AssemblyInfo.cs na aktuální vygenerované čísla build a revision. U atributu AssemblyVersion pak může číslo verze zůstat nastaveno napevno (kvůli referencování z jiných projektů). Task dále zajišťuje, aby všechny najednou buildované projekty měli číslo verze nastavené shodně.
[assembly: AssemblyVersion("1.0.0.0")]
//Build, Revision v atributu AssemblyFileVersion je automaticky generováno
[assembly: AssemblyFileVersion("1.0.4192.19904")]
Pokud používáme pro VS projekty nějaký Source Control system, může být problém, protože soubor AssemblyInfo.cs je měněn pouze lokálně. My jsme si pro naše firemní projekty, kde používáme TFS Source control, proces automatického generování verze proto ještě dále rozšířily. Zavedli jsme ještě další MSBuild tasky, které soubor AssemblyInfo.cs podle nastavení buď aktualizují i v SC, nebo pomoci Get Latest version po buildu soubor vrací na původní nezměněnou verzi. Tyto nové tasky jsou umístěny v jedné knihovně VersionBuildTask.dll, kterou si zde popíšeme a dáváme jí tímto k dispozici.
Knihovna VersionBuildTask.dll obsahuje kromě již popsaného tasku UpdateAssemblyFileVersion dále tyto MSBuild tasky:
IMP.CustomBuildTasks.ChekOut
Task provede check out souboru v TFS Source control (pokud již není aktuálně ve stavu check out).
Parametry:
- FileName - Lokální celá cesta a název souboru pro check out
- LockLevel - Lock level (None, Checkin, CheckOut, Unchanged) pro check out
- Recursive - Vynucení rekursivního check out (např. pro celé adresáře).
IMP.CustomBuildTasks.CheckIn
Provede check in souboru z TFS Source control pokud nedojde ke konfliktům.
Parametry:
- FileName - Lokální celá cesta a název souboru pro check in
- Comment - Komentář check in operace
- Recursive - Vynucení rekursivního check in (např. pro celé adresáře).
- OverridePolicyFailures - Vynucení provedení check in i případě porušení Policy failures.
IMP.CustomBuildTasks.GetLatestAssemblyInfo
Pokud není soubor AssemblyInfo.cs v TFS aktuálně ve stavu check out, vynutí přehrání lokální verze aktuální verzí ze serveru. Cestu k souboru AssemblyInfo.cs lze určit parametrem nebo je soubor automaticky nalezen v projektu stejně jako u akce UpdateAssemblyFileVersion.
Parametry:
- FileName - Nepovinné cesta a jméno AssemblyInfo.cs souboru, pokud není parametr uveden je soubor AssemblyInfo hledán ve výchozích umístění v projektu.
IMP.CustomBuildTasks.UpdateVersion
Hlavní task knihovny pro použití automatického generování čísla verze pro projekty v TFS SCC. Task provádí záměnu verze v AssemblyInfo.cs stejně jako task UpdateAssemblyFileVersion, navíc ale volá operace source controlu, nastavení a průběh celého procesu bude popsáno níže.
Parametry:
- FileName - Nepovinné cesta a jméno AssemblyInfo.cs souboru, pokud není parametr uveden je soubor AssemblyInfo hledán ve výchozích umístění v projektu.
- Version – Verze, ze které se vezmou Build a Revision čísla pro AssemblyFileVersion v souboru AssemblyInfo.cs, pokud není uvedena, jsou Build a Revision vygenerovány (čísla Major a Minor se nemění a zůstávají tak jak jsou zapsána v atributu AssemblyFileVersion).
- CheckInUpdatedVersion - Nastavení zda automaticky provádět Check In souboru AssemblyInfo.cs.
Všechny operace s TFS SCC probíhají na aktuální lokální workspace.
Pozn.: Pro přístup k TFS Source Control knihovna používá dříve představenou třídu SourceControlClient, kde se připojení získá z aktuálně dostupné lokální workspace a proto není potřeba připojení nijak konfigurovat. To je výhodné pro takováto použití jako je právě např. MSBuild task.
Použití tasku UpdateVersion
Pro VS projekty, které jsou spravovány v TFS Source Control nyní použijeme při akci BeforeBuild místo UpdateAssemblyFileVersion task UpdateVersion a dále při AftedBuild zařadíme ještě akci GetLatestAssemblyInfo. V závislosti na nastavení parametru CheckInUpdatedVersion tasku UpdateVersion pak bude celý proces probíhat následovně:
- CheckInUpdatedVersion = false:
Před kompilací projektu se provede záměna verze souboru AssemblyInfo.cs (na lokální kopii). Po kompilaci se akcí GetLatestAssemblyInfo soubor přehraje zpět na aktuální verzi z TFS serveru (pokud není soubor ve stavu check out). Assembly je tak zkompilována s aktuální verzí, ale soubor AssemblyInfo.cs zůstane přitom nezměněn. Hodí se pro debug nebo testovací buildy.
- CheckInUpdatedVersion = true:
Před kompilací projektu se na soubor AssemblyInfo.cs provede operace check out, následně se v souboru změní verze a provede se check in. Assembly je tak zkompilována s aktuální verzí, která je zapsána i do souboru AssemblyInfo.cs v Source Control. Hodí se pro release buildy určené k nasazení.
Nastavení projektu pro tento proces je následující:
<PropertyGroup>
<TasksPath Condition="'$(TasksPath)'==''">c:\BuildBinaries</TasksPath>
<CheckInUpdatedVersion Condition="'$CheckInUpdatedVersion)'==''">false</CheckInUpdatedVersion>
</PropertyGroup>
<UsingTask TaskName="IMP.CustomBuildTasks.UpdateVersion" AssemblyFile="$(TasksPath)\VersionBuildTask.dll"/>
<UsingTask TaskName="IMP.CustomBuildTasks.GetLatestAssemblyInfo" AssemblyFile="$(TasksPath)\VersionBuildTask.dll"/>
...
<Target Name="BeforeBuild">
<IMP.CustomBuildTasks.UpdateVersion CheckInUpdatedVersion="$(CheckInUpdatedVersion)" Version="$(BuildVersion)" />
</Target>
<Target Name="AfterBuild">
<IMP.CustomBuildTasks.GetLatestAssemblyInfo />
</Target>
</Project>
V tomto nastavení projektu jsou volby BuildVersion a CheckInUpdatedVersion možné nastavit např. command line parametrem při volání vlastní kompilace příkazem MSBuild. To bude využitelné pro automatizované buildy v TFS.
Knihovna VersionBuildTask.dll je ke stažení zde. Knihovnu umístíme do nastaveného adresáře TasksPath tj. např.: c:\BuildBinaries.