Вопрос

Мы используем файл T4 для управления версией нашей сборки; В основном мы следуем эти процедуры Чтобы регенерировать наши версии сборки на каждой сборке. Это делается путем использования .csproj Моделирование SDK для VS 2013 чтобы Настроить конфигурацию регенерации T4 с помощью MSBuild.

Это прекрасно работает! К сожалению, команда-сборка для командного фонда, по-видимому, не поддерживает генерацию кода T4 в время сборки, поскольку экземпляры VS 12 на сервере сборки не имеют TextTemplating.Targets в месте установки по умолчанию; Предполагается, что моделирование/VS SDK не устанавливаются на сервере сборки (из журналов сбоев сбоя tfservice):

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

Планируют ли установку Addons Microsoft Vs 2013 (VS SDK, моделирование SDK и т. Д.) На изображение сервера сборки?

Есть ли работа, которую я могу реализовать, чтобы, когда я совершаю свой код в службу команды через GIT, сборка не сломается?

Как я могу настроить размещенный контроллер сборки TFService для преобразования моих файлов T4 во время его сборки?

Это было полезно?

Решение

В итоге я создал другое решение для задачи, когда сервер сборки автоматической версии наших сборков. Вместо использования T4 для динамического создания файла AssemblyInfo.cs для обмена по ссылке элемента с другими проектами в районе (и, следовательно, необходимо справиться с раздражением выяснения того, как сохранить регенерацию тока файла для этой цели), i Избегал T4 вообще. Это было слишком много работы, интегрирующейся с сторонней машиной удаленной сборки удаленного строительства, управляя аддонами и SDK, которые позволяют манипулировать T4 и т. Д. Задачи сообщества MSBUILD что я нашел из это так вопрос. Анкет Решение элегантно простое по сравнению с T4! Вот как это дрожит:

Каждый раз, когда этот проект, Application.Versioning.csproj, строится, задачи MSBuild, определенные в 3-й части, Nuget-установленной библиотеке задач MSBuildCommunity Динамически генерируют. Ассамблея -флевеверсия, AssemblyInformationalVersion, Assemblyversion На основании текущего времени UTC Date Time и введите их в новый файл, Autoversion.cs, который находится в каталоге «Свойства» этого проекта (наряду с файлом AssemblyInfo.cs). AssemblyInfo.cs имеет эти атрибуты сборки навсегда, чтобы избежать ошибок сборки атрибутов мульти определенных сборки). После генерации Autoversion.cs (который происходит непосредственно перед сборкой), компилятор интегрирует вышеупомянутые атрибуты версий сборки в сборку встроенную сборку. Эта версия отражает время UTC, в которое они были построены (см. Ниже).

Все остальные .csproj в .sln подписывается на эту динамическую версию сборки времени сборки, создавая ссылку файла в файл сгенерированного Autoversion.cs. Эти сборки также должны иметь обрезку. Управление версией сборки для всех подписчиков .csprojs в. Вот .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");
}

Другие советы

Мы решили аналогичную проблему, включив файлы V & M SDK (microsoft.texttemplating.build.tasks.dll, microsoft.texttemplating.targets, microsoft.visualstudio.texttempling.sdk.host.1x.dll) в папке External_librares в источнике. контроль.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top