Pregunta

Estamos utilizando un archivo T4 para administrar nuestro versiones de ensamblaje; Básicamente estamos siguiendo estos procedimientos Para regenerar nuestras versiones de ensamblaje en cada compilación. Esto se hace haciendo que el .csproj use el Modelado de SDK para VS 2013 con el fin de Personalizar la configuración de regeneración T4 con MSBuild.

Esto funciona muy bien! Desafortunadamente, Team-Build para Team Foundation Service no parece admitir la generación de código T4 en el momento de la compilación, ya que las instancias de VS 12 en el servidor de compilación no tienen el TextTemplating. Targets en la ubicación de instalación predeterminada; Supongo que el modelado/VS SDK no está instalado en el servidor de compilación (desde los registros de falla de compilación TFService):

El proyecto importado "C: Archivos de programa (x86) MSBuild 12.0 Microsoft VisualStudio V12.0 TextTemplating Microsoft.texttemplating.Targets" no se encontró. Confirme que la ruta en la declaración es correcta y que el archivo existe en el disco.

¿Hay planes para instalar los complementos VS 2013 liberados por Microsoft (vs SDK, modelado de SDK, etc.) en la imagen del servidor de compilación?

¿Hay un trabajo que pueda implementar para que cuando cometa mi código al servicio de la Fundación Team a través de Git, la compilación no se romperá?

¿Cómo puedo configurar el controlador de compilación alojado de TFService para transformar mis archivos T4 durante sus compilaciones?

¿Fue útil?

Solución

Terminé creando una solución diferente a la tarea de tener la inversión del servidor de compilación de nuestros ensamblados. En lugar de usar T4 para crear dinámicamente un archivo de ensamblaje de ensamblaje.cs para compartir a través de un enlace de elemento a otros proyectos dentro de la solución (y, por lo tanto, tener que lidiar con la molestia de descubrir cómo mantener la regeneración del archivo actual para este propósito), i, i I, i evitó T4 por completo. Era demasiado trabajo integrarse con la máquina de construcción remota de terceros, administrando los complementos y los SDK que permiten la manipulación T4, etc. Hay una solución mucho más simple que implica Tareas de la comunidad de msbuild que encontré de esta pregunta. ¡La solución es elegantemente simple en comparación con T4! Así es como se sacude:

Cada vez que este proyecto, Application.Versioning.CSProj, está creado, MSBuild Tasks definidas en la biblioteca de terceros, instaladas por NUGET 'MSBuildCommunity Tasks "Genere dinámicamente dinámicamente AssemblyFileVersion, AssemblyInformational Versión, Assemblyversion Basado en la hora actual de fecha UTC e ingresarlos en un nuevo archivo, Autoversion.cs, que reside en el directorio 'Propiedades' de este proyecto (junto con el archivo ensamblableinfo.cs). El ensamblaje de.cs tiene estos atributos de ensamblaje para evitar los errores de construcción de los atributos de ensamblaje definidos por múltiples). Después de la generación de autoversión.cs (que ocurre justo antes de la construcción), el compilador integra los atributos de versiones de ensamblaje antes mencionados en el ensamblaje construido. Este verso refleja el tiempo UTC en el que se construyeron (ver más abajo).

Todos los demás .csproj en el .sln se suscriben a este control de ensamblaje dinámico y de tiempo de construcción creando un enlace de archivo al archivo generado de autoversion.cs. Estas asambleas también deben tener su ensamblaje de su ensamblaje. El versiones de ensamblaje para todos los .csprojs de suscripción en el .sln se realiza cada vez que se construye myapplication.versioning.csproj (o se reconstruye). Aquí está el .csproj para el proyecto de versiones:

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

así como una prueba unitaria para verificar por sí mismo:

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

Otros consejos

Resolvimos un problema similar al incluir los archivos V&M SDK (Microsoft.texttemplating.build.tasks.dll, microsoft.texttemplating.targets, microsoft.visualstudio.texttemplating.sdk.host.1x.0.dll) en una carpeta externa_libraries en Source Source control.

En mi opinión, esta es la única forma de administrar SDK de terceros en grandes proyectos: la instalación en cada máquina de desarrollo individual y servidor de compilación es demasiado frágil para ser práctica.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top