2013-11-07 6 views
0

Мы используем файл T4 для управления версиями сборки; В основном мы следим за these procedure, чтобы восстановить версии сборки на каждой сборке. Это делается путем использования .csproj Modeling SDK for VS 2013 для того, чтобы customize T4 regeneration configuration with MSBUILD.TFService MSBUILD и T4 Code Generation

Это отлично работает! К сожалению, сборка команд Team Foundation Service, похоже, не поддерживает генерацию кода T4 во время сборки, поскольку экземпляры VS 12 на сервере сборки не имеют объектов TextTemplating.targets в месте установки по умолчанию; предположительно в SDKs Моделирование/VS не установлены на сервере сборки (из TFService построения журналов отказов):

Импортированная проекта «C: \ Program Files (x86) \ MSBuild \ 12.0 \ Microsoft \ VisualStudio \ v12 .0 \ TextTemplating \ Microsoft.TextTemplating.targets "не найден. Убедитесь, что путь в объявлении правильный, и что файл существует на диске.

Планируется ли установить выпуски VS 2013 с выпуском Microsoft (VS SDK, Modeling SDK и т. Д.) На изображение сервера сборки?

Есть ли работа, которую я могу реализовать, чтобы, когда я передаю свой код Team Foundation Service через Git, сборка не сломается?

Как настроить TBService Hosted Build Controller для преобразования файлов T4 во время его сборки?

ответ

0

Я закончил тем, что создал другое решение задачи создания автоматической сборки сборки наших сборок. Вместо того, чтобы использовать T4 для динамического создания файла AssemblyInfo.cs для совместного использования по ссылке на другие проекты в рамках решения (и, следовательно, приходится иметь дело с досадой, чтобы выяснить, как сохранить регенерацию файла, имеющегося для этой цели), I вообще избегал Т4. Это была слишком большая работа, интегрированная с сторонней удаленной сборной машиной, управление аддонами и SDK, которые позволяют манипулировать T4 и т. Д. Существует гораздо более простое решение с участием MSBuild Community Tasks, которое я нашел от this SO question. Решение элегантно просто по сравнению с T4! Вот как он качает вниз:

Каждый раз, когда этот проект, Application.Versioning.csproj, построен, MSBuild задачи, определенные в 3-партии, NuGet установлена ​​библиотека «MSBuildCommunity Задачи» динамически генерировать [AssemblyFileVersion], [AssemblyInformationalVersion], [AssemblyVersion] основан на текущем времени даты UTC и вводит их в новый файл, AutoVersion.cs, который находится в каталоге «Свойства» этого проекта (вместе с файлом AssemblyInfo.cs). AssemblyInfo.cs имеет эти атрибуты сборки навсегда, чтобы избежать ошибок сборки многократно определенных атрибутов сборки). После генерации AutoVersion.cs (что происходит непосредственно перед сборкой) компилятор объединяет вышеупомянутые атрибуты управления версиями сборки в встроенную сборку. Это управление версиями отражает время UTC, на котором они были построены (см. Ниже).

Все остальные .csproj в .sln подписываются на это динамическое построение сборки сборки, создавая ссылку на файл сгенерированного файла AutoVersion.cs. Эти сборки также должны иметь обрезку AssemblyInfo.cs. Исполнение сборки для всех подписных .csprojs в .sln выполняется каждый раз, когда MyApplication.Versioning.csproj построен (или перестроен). Вот.csproj для проекта версий:

<!-- START DYNAMIC ASSEMBLY VERSIONING WORK--> 
    <!--MSBuild Community Tasks path as installed via the nuget package 'Install-Package MSBuildTasks'--> 

<PropertyGroup> 
    <MSBuildCommunityTasksPath>$(MSBuildThisFileDirectory)..\.build</MSBuildCommunityTasksPath> 
    <My-PropertiesDir>Properties</My-PropertiesDir> 
    </PropertyGroup> 
    <PropertyGroup> 

    <!--this should only be incremented (starting at zero) for MAJOR application releases this should never be reset only incremented!--> 
    <ManualMajorVersion>0</ManualMajorVersion> 

    <!--3 digits maximum should only be manually incremented (starting at zero) for feature releases--> 
    <!--!this should be reset to '0' at the start of each caldenar Year--> 
    <ManualMinorVersion>0</ManualMinorVersion> 
    </PropertyGroup> 

    <!--Import MSBuild Community Tasks library installed from Nuget --> 
    <!--This library contains defined MSBUILD tasks useful for dynamically generating Assembly information via MSBUILD https://github.com/loresoft/msbuildtasks--> 
    <Import Project="$(MSBuildCommunityTasksPath)\MSBuild.Community.Tasks.Targets" /> 
    <Target Name="BeforeBuild"> 
    <Time Format="yy.MM.dd.HHmm" Kind="Utc"> 
     <Output TaskParameter="FormattedTime" PropertyName="My-VersionNumber" /> 
    </Time> 
    <Message Text="Auto versioning from UTC time: $(My-VersionNumber) ..."> 
    </Message> 
    <Time Format="yy" Kind="Utc"> 
     <Output TaskParameter="FormattedTime" PropertyName="Year" /> 
    </Time> 
    <Time Format="MM" Kind="Utc"> 
     <Output TaskParameter="FormattedTime" PropertyName="Month" /> 
    </Time> 
    <Time Format="dd" Kind="Utc"> 
     <Output TaskParameter="FormattedTime" PropertyName="Day" /> 
    </Time> 
    <Time Format="HH" Kind="Utc"> 
     <Output TaskParameter="FormattedTime" PropertyName="Hour" /> 
    </Time> 
    <Time Format="mm" Kind="Utc"> 
     <Output TaskParameter="FormattedTime" PropertyName="Minute" /> 
    </Time> 
    <ItemGroup> 
     <My-AssemblyInfo Include="$(My-PropertiesDir)\AutoVersion.cs" /> 
     <Compile Include="@(My-AssemblyInfo)" /> 
    </ItemGroup> 
    <MakeDir Directories="$(My-PropertiesDir)" /> 
    <PropertyGroup> 
     <GeneratedAssemblyVersion>$(ManualMajorVersion).$(Year)$(ManualMinorVersion).$(Month)$(Day).$(Hour)$(Minute)</GeneratedAssemblyVersion> 
    </PropertyGroup> 
    <AssemblyInfo OutputFile="@(My-AssemblyInfo)" CodeLanguage="CS" AssemblyFileVersion="$(GeneratedAssemblyVersion)" AssemblyInformationalVersion="$(GeneratedAssemblyVersion)" AssemblyVersion="$(GeneratedAssemblyVersion)" Condition="$(GeneratedAssemblyVersion) != '' " /> 
    </Target> 
    <!-- END DYNAMIC ASSEMBLY VERSIONING WORK--> 

, а также модульного тестирования, чтобы проверить для себя:

/// <summary> A test to validate the configured, auto-generated assembly versioning is working as expected </summary> 
[Test] 
public void AssemblyVersioningTest() 
{ 
    DirectoryInfo currentDirectory = new DirectoryInfo(Directory.GetCurrentDirectory()); 
    DirectoryInfo versioningDir = new DirectoryInfo(currentDirectory.FullName + "\\" + VERSIONING_DYNAMIC_FILE_DIRECTORY); 

    // verify versioning directory located/loaded/exists 
    Assert.IsTrue(versioningDir.Exists); 

    // locate the VERSIONING_DYNAMIC_FILE file within the VERSIONING_DYNAMIC_FILE_DIRECTORY directory 
    string dynamicFilePath = versioningDir.FullName + "\\" + VERSIONING_DYNAMIC_FILE; 

    // get the FileInfo for the file that is used to dynamically generate assembly versioning 
    FileInfo dynamicVersioningFileInfo = new FileInfo(dynamicFilePath); 
    Assert.IsTrue(dynamicVersioningFileInfo.Exists); 

    // get the two digit creation Dates/Times for the assembly's file as strings 
    // since that's what the versioning reflects 
    DateTime dynamicVersioningFileLastWriteTime = dynamicVersioningFileInfo.LastWriteTime; 

    #region Created VERSIONING_DYNAMIC_FILE 
    string dynamicVersioningFileLastWriteTimeYear = dynamicVersioningFileLastWriteTime.ToUniversalTime().ToString("yy"); 

    string dynamicVersioningFileLastWriteTimeMonth = dynamicVersioningFileLastWriteTime.ToUniversalTime().ToString("MM"); 
    string dynamicVersioningFileLastWriteTimeDay = dynamicVersioningFileLastWriteTime.ToUniversalTime().ToString("dd"); 

    string dynamicVersioningFileLastWriteTimeHour = dynamicVersioningFileLastWriteTime.ToUniversalTime().ToString("HH"); 
    string dynamicVersioningFileLastWriteTimeMinute = dynamicVersioningFileLastWriteTime.ToUniversalTime().ToString("mm"); 
    #endregion Created VERSIONING_DYNAMIC_FILE 

    // get *this* assembly from the .sln using reflection since this assembly consumes/is dependent upon the versioning functionality we 
    // are testing 
    Assembly theAssemblyExecutingThisTest = Assembly.GetExecutingAssembly(); 

    // get this assembly's version 
    // we will investigate this to compare it to a reverse-engineering of what we would 
    // expect it to be based 
    AssemblyName testingAssemblyName = theAssemblyExecutingThisTest.GetName(); 
    Version testingAssemblyVersion = testingAssemblyName.Version; 

    #region Generated Assembly Versioning 
    // get the first two digits of the assemblyVersion.MinorVersion - these represent the year 
    string testingAssemblyVersionMinorYear = testingAssemblyVersion.Minor.ToString().Substring(0, 2); 
    // the rest of the digits represent the manually-configured version and can be 1-3 chars long 
    string testingAssemblyVersionMinorManual = GetMinorManualFromVersionString(testingAssemblyVersion.Minor.ToString()); 

    string testingAssemblyVersionBuildMonth = testingAssemblyVersion.Build.ToString("D4").Substring(0, 2); 
    string testingAssemblyVersionBuildDay = testingAssemblyVersion.Build.ToString("D4").Substring(2, 2); 

    string testingAssemblyVersionRevisionHour = testingAssemblyVersion.Revision.ToString("D4").Substring(0, 2); 
    string testingAssemblyVersionRevisionMinute = testingAssemblyVersion.Revision.ToString("D4").Substring(2, 2); 
    #endregion Generated Assembly Versioning 

    // verify the assembly's minor version: last two digits match of assembly file creation year 
    // (pad minorversion 4 spaces in case released minor version is empty) 
    Assert.AreEqual(dynamicVersioningFileLastWriteTimeYear, 
     testingAssemblyVersionMinorYear, 
     "Assembly's minor version: last two digits do not match assembly file last write time year"); 

    // verify the assembly's minor version is comprised of two digit 'released minor version' + two digit year of assembly file creation date 
    Assert.AreEqual(dynamicVersioningFileLastWriteTimeYear + testingAssemblyVersionMinorManual, 
     testingAssemblyVersionMinorYear + testingAssemblyVersionMinorManual, 
     "Assembly's minor version: not comprised of two digit year of assembly file last write time date + dynamically-sized 'minor manual version' + "); 

    // verify the Assembly's build version is comprised of two digit month + two digit day of assembly file creation date 
    Assert.AreEqual(dynamicVersioningFileLastWriteTimeMonth + dynamicVersioningFileLastWriteTimeDay, 
     testingAssemblyVersionBuildMonth + testingAssemblyVersionBuildDay, 
     "Assembly's build version: not comprised of two digit month + two digit day of assembly file last write time date"); 

    // verify the Assembly's revision version is comprised two digit hour + two digit minute of assembly file creation date 
    Assert.AreEqual(dynamicVersioningFileLastWriteTimeHour + dynamicVersioningFileLastWriteTimeMinute, 
     testingAssemblyVersionRevisionHour + testingAssemblyVersionRevisionMinute, 
     "Assembly's revision version: comprised two digit hour + two digit minute of assembly file last write time date"); 
} 
0

Мы решили подобную проблему, в том числе в V & M SDK файлы (Microsoft.TextTemplating.Build. Tasks.dll, Microsoft.TextTemplating.targets, Microsoft.VisualStudio.TextTemplating.Sdk.Host.1X.0.dll) в папке external_libraries в исходном элементе управления.

IMO это единственный способ управлять сторонними SDK в больших проектах: установка на каждой отдельной машине dev и создание сервера слишком хрупкие, чтобы быть практичным.

 Смежные вопросы

  • Нет связанных вопросов^_^