Pergunta

Estamos usando um arquivo T4 para gerenciar nossa versão de montagem; Basicamente, estamos seguindo estes procedimentos Para regenerar nossas versões de montagem em cada compilação. Isso é feito com o .csproj usar o Modelando SDK para VS 2013 em ordem de Personalize a configuração de regeneração T4 com MSBuild.

Isso funciona muito bem! Infelizmente, o Serviço de Fundação da Team-Build for Team não parece suportar a geração de código T4 no horário de construção, pois as instâncias do VS 12 no servidor de construção não têm o textTemplating.Targets no local de instalação padrão; Supuvelmente, os SDKs de Modelagem/VS não estão instalados no servidor de construção (a partir dos logs de falha de construção do TFService):

O projeto importado "C: Arquivos de Programas (x86) msbuild 12.0 Microsoft VisualStudio V12.0 TextTemplating Microsoft.textTemplating.Targets" não foi encontrado. Confirme se o caminho na declaração está correto e que o arquivo existe no disco.

Existem planos para instalar os complementos do Microsoft VS 2013 (vs SDK, Modelando SDK, etc) na imagem do servidor de construção?

Existe um trabalho por aí que eu possa implementar para que, quando comprometo meu código no serviço da equipe da Team Foundation via Git, a construção não quebre?

Como posso configurar o controlador de construção hospedado do TFService para transformar meus arquivos T4 durante suas compilações?

Foi útil?

Solução

Acabei criando uma solução diferente para a tarefa de ter o servidor de compilação automaticamente nossos conjuntos. Em vez de usar o T4 para criar dinamicamente um arquivo de AssemblyInfo.cs para compartilhar através do link do item para outros projetos dentro da solução (e, portanto, tem que lidar com o aborrecimento de descobrir como manter a regeneração do arquivo atual para esse fim), i Evitou T4 completamente. Foi muito trabalho integrando com a máquina de construção remota de terceiros, gerenciando os complementos e SDKs que permitem manipulação T4 etc. Há uma solução muito mais simples envolvendo Tarefas da comunidade msbuild que eu encontrei de isso é tão pergunta. A solução é elegantemente simples em comparação com T4! Aqui está como isso abre para baixo:

Cada vez que este projeto, Application.versioning.csProj, é construído, tarefas msbuild definidas na biblioteca de terceiros e instalados por Nuget ' AssemblyFileversion, AssemblyInformationalVersion, AssemblyVersion Com base na hora atual do UTC e insira -os em um novo arquivo, o Autoversão.cs, que reside no diretório 'Propriedades' deste projeto (juntamente com o arquivo AssemblyInfo.cs). O AssemblyInfo.cs tem esses atributos de montagem para sempre abordados para evitar erros de construção de atributos de montagem definidos por multiplicação). Após a geração de autoversão.cs (que ocorre imediatamente antes da construção), o compilador integra os atributos de versão de montagem acima mencionados na montagem construída. Este versão reflete o horário da UTC em que foram construídos (veja abaixo).

Todos os outros .csproj no .sln assina esse versão dinâmica de montagem de tempo de construção, criando um link de arquivo para o arquivo gerado autoversão.cs. Esses assemblies também devem ter seus assemblyInfo.cs de poda. O versão de montagem para todos os assinantes .csprojs no .sln é feito sempre que o myapplication.versioning.csproj é construído (ou reconstruído). Aqui está o .csproj para o projeto de versão:

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

bem como teste de unidade para verificar por si mesmo:

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

Outras dicas

Resolvamos uma questão semelhante, incluindo os arquivos V&M SDK (microsoft.textTemplating.build.tasks.dll, microsoft.texttemplating.targets, microsoft.visualstudio.textTemplating.sdk.host.1x.0.dll) em um externo Fronders. ao controle.

IMO Esta é a única maneira verdadeira de gerenciar SDKs de terceiros em grandes projetos: a instalação em todas as máquina de desenvolvimento individual e o servidor de construção é muito quebradiço para ser prático.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top