Frage

Wir verwenden eine T4 -Datei, um unsere Assembly -Versioning zu verwalten. Grundsätzlich folgen wir diese Prozedur Um unsere Montageversionings bei jedem Build zu regenerieren. Dies geschieht, indem die .csproj die verwenden Modellierung SDK für VS 2013 um zu Passen Sie die T4 -Regenerationskonfiguration mit msbuild an.

Das funktioniert großartig! Leider scheint das Team-Build für Team Foundation Service T4 Code Generation zum Build-Zeit nicht zu unterstützen, da die Instanzen von VS 12 auf dem Build-Server nicht über die textTemplatation.targets im Standard-Installationsort verfügen. Angenommen, die Modellierung/VS -SDKs werden auf dem Build -Server nicht installiert (aus den TFService -Build -Fehlerprotokollen):

Das importierte Projekt "C: Programme (x86) msbuild 12.0 microsoft visualstudio v12.0 textTemplating microsoft.textTemplatation.targets" wurde nicht gefunden. Bestätigen Sie, dass der Pfad in der Deklaration korrekt ist und dass die Datei auf der Festplatte vorhanden ist.

Gibt es Pläne, die von Microsoft veröffentlichten VS 2013 Addons (VS SDK, Modellierung SDK usw.) am Build-Server-Image zu installieren?

Gibt es eine Arbeit, die ich implementieren kann, damit der Build, wenn ich meinen Code für den Team Foundation -Service über Git verpflichte, nicht brechen wird?

Wie kann ich den gehosteten Build -Controller von TFService so konfigurieren, dass ich meine T4 -Dateien während seiner Builds transformieren kann?

War es hilfreich?

Lösung

Am Ende habe ich eine andere Lösung für die Aufgabe erstellt, den Build-Server automatisch zu veröffentlichen, unsere Baugruppen. Anstatt T4 zu verwenden, um eine dynamische Erstellung einer AssemblyInfo.cs -Datei zu erstellen, die über einen Element -Link zu anderen Projekten innerhalb der Lösung freigegeben werden kann (und daher mit dem Ärger zu tun haben muss, herauszufinden, wie die Regeneration der Datei für diesen Zweck aktualisiert werden kann), ist ich vermieden T4 insgesamt. Es war zu viel Arbeit, die sich in den Remote -Build -Maschine der Drittanbieter integrieren, die Addons und SDKs verwaltet, die T4 -Manipulation usw. ermöglichen. Es gibt eine viel einfachere Lösung mit MSBUILD -Community -Aufgaben das habe ich fand aus Diese Frage. Die Lösung ist im Vergleich zu T4 elegant einfach! So zittert es:

Jedes Mal, wenn dieses Projekt, application.versioning.csproj, erstellt wird, wird MSBUILD-Aufgaben in der 3. Party, Nuget-installiertes 'MSBuildCommunity-Aufgaben' Bibliothek, dynamisch generiert AssemblyFileVersion, AssemblyInformationalversion, Assemblyversion Basierend auf dem aktuellen UTC -Datumzeitszeitpunkt und in eine neue Datei Autoversion.cs, die sich im Verzeichnis „Eigenschaften“ dieses Projekts befindet (neben der Datei montageInfo.cs). Die AssemblyInfo.cs hat diese Montageattribute für immer ausgeschaltet, um Fehler von Multiplikum-definierten Montageattributen zu vermeiden. Nach der Erzeugung von Autoversion.cs (die kurz vor dem Bau stattfindet) integriert der Compiler die oben genannten Versioning -Attribute der Montage in die gebaute Baugruppe. Diese Versionierung spiegelt die UTC -Zeit wider, zu der sie gebaut wurden (siehe unten).

Jedes andere .csproj im .sln abonniert diese dynamische Versionsversionsversions-Versioning, die einen Datei-Link zur generierten autoversion.cs-Datei erstellt. Diese Baugruppen müssen auch ihre AssemblyInfo.cs 'beschnitten haben. Die Assembly -Versioning für alle Abonnements .csprojs in der .sln erfolgt jedes Mal, wenn die MyApplication.versioning.csproj gebaut (oder umgebaut) wird. Hier ist der .csproj für das Versioning -Projekt:

  <!-- 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-->

sowie Unit -Test, um sich selbst zu überprüfen:

/// <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");
}

Andere Tipps

Wir haben ein ähnliches Problem gelöst, indem wir die V & M SDK -Dateien (microsoft.TextTemplatation.build.tasks.dll, microsoft.textTemplating.targets, microsoft.visualstudio.texttemPlating.sdk.host.1x.0.dll) in einem external_library in screeS.host.1x.0.dll) gelöst haben. Kontrolle.

IMO Dies ist die einzige Möglichkeit, Drittanbieter -SDKs in großen Projekten zu verwalten: Die Installation auf jedem einzelnen Entwicklungsgerät und Build -Server ist zu spröde, um praktisch zu sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top