Compartir a través de


Tutorial: Personalizar Team Foundation Build con una tarea personalizada

Actualización: noviembre 2007

Puede extender Team Foundation Build creando sus propias tareas personalizadas y ejecutándolas durante una compilación. En este tema se explican los pasos necesarios para extender una definición de compilación con una tarea personalizada.

Permisos necesarios

Para completar este tutorial, debe tener el permiso Administrar una compilación establecido en Permitir. Para obtener más información, vea Permisos de Team Foundation Server.

Crear un definición de compilación

Utilice el cuadro de diálogo Definición de compilación para crear una nueva definición de compilación. Puede compartir un archivo TFSBuild.proj existente o crear uno nuevo con el Asistente para crear archivos de proyecto de MSBuild. Debe modificar el archivo TFSBuild.proj para personalizar cada definición de compilación asociada a dicho archivo. Para obtener más información acerca de cómo crear definiciones de compilación, vea Cómo: Crear una definición de compilación.

Crear tareas personalizadas

Las tareas proporcionan el código que se ejecuta durante el proceso de generación. Estas tareas están incluidas en elementos Target de archivos de proyecto de MSBuild. MSBuild es el motor de Team Foundation Build. Las tareas personalizadas tienen que tener un formato que MSBuild entienda. Cada tarea debe implementarse como una clase de .NET que implementa la interfaz ITask, que se define en el ensamblado Microsoft.Build.Framework.dll.

Al implementar una tarea se pueden utilizar dos enfoques:

  • Implementar la interfaz ITask directamente.

  • Derive la clase a partir de la clase auxiliar, Task, que se define en el ensamblado Microsoft.Build.Utilities.dll. Task implementa ITask y proporciona implementaciones predeterminadas de algunos miembros ITask.

En ambos enfoques, debe agregar a la clase un método denominado Execute, al que se llama cuando se ejecuta la tarea. Este método no utiliza ningún parámetro y devuelve un valor Boolean: es true si la tarea se realiza correctamente o false si se produce un error. El ejemplo siguiente muestra una tarea que no realiza ninguna acción y devuelve true.

using System;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace MyTasks
{
    public class SimpleTask : Task
    {
        public override bool Execute()
        {
            return true;
        }
    }
}

Las tareas también aceptan parámetros, producen eventos y generan registros. Para obtener más información, vea Tareas de MSBuild y Información general sobre MSBuild.

Protección de TFSBuild.proj

Después de haber escrito la tarea, debe registrarla y llamarla en uno de los destinos de modo que el código de la tarea se ejecute en el punto deseado en el proceso de generación. Si ha utilizado el Asistente para crear archivos de proyecto de MSBuild para crear un archivo de proyecto de MSBuild y ha aceptado la ubicación predeterminada en el control de código fuente, su archivo TFSBuild.proj se encuentra en la carpeta $/MiProyectoDeEquipo/TeamBuildTypes/MiNombreDeCompilación en el control de código fuente de Visual Studio Team System. En este escenario, MiEquipoDeProyecto es el nombre de su proyecto de equipo y es el nodo raíz del código fuente de todos sus proyectos de equipo, y MiNombreDeCompilación es el nombre que asignó a su definición de compilación para la que creó originalmente el archivo TFSBuild.proj.

Para determinar la ubicación de control de código fuente del archivo TFSBuild.proj, seleccione la definición de compilación en la carpeta Builds en Team Explorer, haga clic con el botón secundario del mouse en ella y, a continuación, haga clic en Editar. La ubicación de control de código fuente del archivo TFSBuild.proj se muestra en el panel Archivo de proyecto del cuadro de diálogo Definición de compilación.

Nota:

No edite el archivo Microsoft.TeamFoundation.Build.targets porque las personalizaciones se aplican a todas las generaciones de ese equipo.

Para obtener más información acerca de la protección de archivos, vea Trabajar con el control de versiones de Team Foundation.

Registrar su tarea

Después de crear la tarea, debe registrarla especificándola en un elemento UsingTask del archivo TFSBuild.proj. El elemento UsingTask asigna la tarea al ensamblado que contiene la implementación de la tarea. Para obtener más información, vea Elemento UsingTask (MSBuild).

Para registrar una tarea personalizada

  1. Abra el archivo TFSBuild.proj.

  2. Agregue un elemento UsingTask al archivo y especifique los detalles de la tarea.

    Por ejemplo:

    <UsingTask 
        TaskName="MyTasks.SimpleTask" 
        AssemblyName="MyAssembly.Build.Tasks"/>
    

    O bien

    <UsingTask 
        TaskName="MyTasks.SimpleTask" 
        AssemblyFile="MyAssembly.Build.Tasks.dll"/>
    

    O bien

    <UsingTask
        TaskName="MyTasks.SimpleTask"
        AssemblyFile="c:\somediskpath\MyAssembly.Build.Tasks.dll"/>
    
  3. Guarde el archivo.

Ejecución de la tarea personalizada

Una vez que ha creado y registrado la tarea, debe especificar el punto del proceso de generación en el que desea ejecutar la tarea.

Para ejecutar una tarea

  1. Decida en qué punto del proceso de generación desea ejecutar la tarea personalizada.

    Para obtener más información acerca de dónde puede extender el proceso de generación, vea Introducción a los archivos de configuración de Team Foundation Build.

  2. Abra TFSBuild.proj y agregue el elemento Target que eligió anteriormente.

  3. Agregue el elemento de tarea para ejecutar la tarea dentro del elemento Target.

    Por ejemplo, el siguiente código XML de TFSBuild.proj ejecuta la tarea SimpleTask en el destino BeforeGet, que se ejecuta justo antes que el destino Get.

    <Target Name="BeforeGet">
        <SimpleTask />
    </Target>
    
  4. Guarde el archivo.

Protección de los archivos

Debe proteger el archivo TFSBuild.proj para que los cambios surtan efecto. Team Foundation Build copia este archivo desde el control de código fuente al equipo de compilación, de modo que los cambios que se realicen en la copia local del equipo no afecten a la compilación. Para obtener información acerca de la protección de archivos en el control de código fuente, vea Cómo: Proteger cambios pendientes.

Si necesita Team Foundation Build para copiar la DLL de la tarea en el equipo de compilación, debe agregar la DLL al control de código fuente bajo el nodo de proyecto de equipo.

Tarea de ejemplo

En este ejemplo se crea una tarea personalizada que extiende la definición o definiciones de compilación asociadas al archivo TFSBuild.proj registrando el tamaño de los archivos generados por la compilación. Este ejemplo tiene dos partes:

  • El código de la tarea.

  • El archivo TFSBuild.proj.

La información registrada en esta tarea puede verse en el archivo de registro de la compilación, Buildlog.txt, que se encuentra en la carpeta de entrega de la compilación. El registro de la generación contiene información parecida a la que se muestra a continuación:

El tamaño total es de 9216 bytes en d:\BuildDir\MyTeamProj\MyBuildType\sources\..\Binaries\Release dir

Código de tarea de C#

El ejemplo siguiente contiene el código que calcula el tamaño binario total al agregar el tamaño de los archivos de la carpeta de binarios.

Nota:

Todos los archivos binarios generados durante la compilación se encuentran en la carpeta Binaries de la carpeta del directorio de compilación en el agente de compilación.

Para incluir esta tarea en una generación, la DLL compilada debe estar protegida en el control de código fuente en la carpeta del proyecto de equipo. Esto garantiza que el archivo se copie en el agente de generación durante la compilación.

El código siguiente calcula el tamaño de los archivos binarios de la carpeta Binaries del directorio de compilación. La propiedad de la raíz de la solución se pasa a la tarea mediante el script de Team Foundation Build.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Build.Framework; 
using Microsoft.Build.Utilities;
using System.Diagnostics;
using System.IO;

namespace BuildTask
{
    public class BinSize : Task
    {
        private string sourceDir;

        [Required]
        public string SourceDir
        {
            get { return sourceDir; }
            set { sourceDir = value; }
        }
        public override bool Execute()
        {
            string szDir = sourceDir + "\\..\\Binaries";
            ProcessDirectory(szDir);
            return true;
        }
        private void ProcessDirectory(string targetDirectory)
        {
            // Process the list of files found in the directory.
            string[] fileEntries = Directory.GetFiles(targetDirectory, "*.*");
            if (fileEntries.Length > 0)
            {
                dwSize = 0;
                szCurrDir = targetDirectory;
                foreach (string fileName in fileEntries)
                    ProcessFile(fileName);
                ////////////////////////////////////////////////////////////////////////
                // This log message would just print out a line in the build log file. 
                // You need to add code to do what you need to do with this data. e.g. 
                // publishing it into the warehouse for reporting. 
                ///////////////////////////////////////////////////////////////////////
                Log.LogMessage("The total size of is {0} bytes in {1} dir",
                    dwSize, targetDirectory);
            }
            // Recurse into subdirectories of this directory.
            string[] subdirectoryEntries = Directory.GetDirectories(targetDirectory);
            foreach (string subdirectory in subdirectoryEntries)
                ProcessDirectory(subdirectory);
        }
        private void ProcessFile(string path)
        {
            FileInfo fi = new FileInfo(path);
            dwSize = dwSize + fi.Length;
        }
        private long dwSize;
        private string szCurrDir;
    }
}

Archivo TFSBuild.proj

Cuando se haya compilado la tarea y protegido en el control de código fuente, debe llamarse desde el archivo TFSBuild.proj. En este ejemplo, la tarea debe llamarse después de haber compilado los archivos y haber copiado todos los archivos binarios en el directorio Binaries. Por lo tanto, la tarea debe ejecutarse en el destino BeforeDropBuild. Para obtener más información sobre los destinos extensibles en TFSBuild.proj, vea Introducción a los archivos de configuración de Team Foundation Build.

El siguiente ejemplo contiene el código del archivo TFSBuild.proj modificado. El ejemplo de XML está generado casi completamente por el Asistente para crear archivos de proyecto de MSBuild excepto los elementos UsingTask y Target que se encuentran al final de archivo.

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="DesktopBuild" xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
  <!-- TO EDIT BUILD TYPE DEFINITION

   TODO: Update all of the comments in this file!

   To edit the build type, you will need to edit this file which was generated
   by the Create New Build Type wizard.  This file is under source control and
   needs to be checked out before making any changes.

   The file is available at:
   
       $/{TeamProjectName}/TeamBuildTypes/{BuildTypeName}
       
   where you will need to replace TeamProjectName and BuildTypeName with your
   Team Project and Build Type name that you created

   Checkout the file
     1. Open Source Control Explorer by selecting View -> Other Windows -> Source Control Explorer
     2. Ensure that your current workspace has a mapping for the $/{TeamProjectName}/TeamBuildTypes folder and 
        that you have done a "Get Latest Version" on that folder
     3. Browse through the folders to {TeamProjectName}->TeamBuildTypes->{BuildTypeName} folder
     4. From the list of files available in this folder, right click on TfsBuild.Proj. Select 'Check Out For Edit...'


   Make the required changes to the file and save

   Checkin the file
     1. Right click on the TfsBuild.Proj file selected in Step 3 above and select 'Checkin Pending Changes'
     2. Use the pending checkin dialog to save your changes to the source control

   Once the file is checked in with the modifications, all future builds using
   this build type will use the modified settings
  -->

  <!-- Do not edit this -->
  <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\TeamBuild\Microsoft.TeamFoundation.Build.targets" />

  <ProjectExtensions>

    <!-- Team Foundation Build Version - DO NOT CHANGE -->
    <ProjectFileVersion>2</ProjectFileVersion>

    <!--  DESCRIPTION
     TODO: Obsolete.
    -->
    <Description>this one automatically  builds on check in</Description>

    <!--  BUILD MACHINE
     TODO: Obsolete.
    -->
    <BuildMachine>ahetod-test2</BuildMachine>

  </ProjectExtensions>

  <PropertyGroup>

    <!-- Properties set by the build type creation wizard -->
    
    <!--  TEAM PROJECT
     TODO: Obsolete.
    -->
    <TeamProject>TeamProjectName</TeamProject>

    <!--  BUILD DIRECTORY
     TODO: Obsolete.
    -->
    <BuildDirectoryPath>C:\Documents and Settings\user\Local Settings\Temp\1\TeamProjectName\BuildDefinitionName</BuildDirectoryPath>

    <!--  DROP LOCATION
     TODO: Obsolete.
    -->
    <DropLocation>\\UNKNOWN\drops</DropLocation>

    <!--  TESTING
     Set this flag to enable/disable running tests as a post build step.
    -->
    <RunTest>false</RunTest>

    <!--  CODE ANALYSIS
     To change CodeAnalysis behavior edit this value. Valid values for this
     can be Default,Always or Never.

         Default - To perform code analysis as per the individual project settings
         Always  - To always perform code analysis irrespective of project settings
         Never   - To never perform code analysis irrespective of project settings
     -->
    <RunCodeAnalysis>Never</RunCodeAnalysis>

    <!-- Additional Properties -->

    <!--  WorkItemType
     The type of the work item created on a build break - if empty, "Bug" will be used 
     -->
    <WorkItemType Condition=" '$(WorkItemType)'=='' "></WorkItemType>

    <!--  WorkItemFieldValues
     Add/edit key value pairs to set values for fields in the work item created
     during the build process. Please make sure the field names are valid 
     for the work item type being used.
     -->
    <WorkItemFieldValues>Symptom=build break;Steps To Reproduce=Start the build using Team Build</WorkItemFieldValues>

    <!--  WorkItemTitle
     Title for the work item created on build failure 
     -->
    <WorkItemTitle>Build failure in build:</WorkItemTitle>

    <!--  DescriptionText
     Description for the work item created on a build failure 
     -->
    <DescriptionText>This work item was created by Team Build on a build failure.</DescriptionText>

    <!--  BuildLogText
     Additional text for the work item create on a build failure.
     -->
    <BuildlogText>The build log file is at:</BuildlogText>

    <!--  ErrorWarningLogText
     Additional text for the work item create on a build failure 
     -->
    <ErrorWarningLogText>The errors/warnings log file is at:</ErrorWarningLogText>

    <!--  UpdateAssociatedWorkItems
     Set this flag to enable/disable updating associated workitems on a successful build
     -->
    <UpdateAssociatedWorkItems>true</UpdateAssociatedWorkItems>

    <!--  AdditionalVCOverrides
     Additional text for the VCOverrides file generated for VC++ projects
     -->
    <AdditionalVCOverrides></AdditionalVCOverrides>

    <!--  CustomPropertiesForClean
     Custom properties to pass to the MSBuild task while calling the "Clean" target for all solutions.
     The format should be: PropertyName1=value1;PropertyName2=value2;...
     -->
    <CustomPropertiesForClean></CustomPropertiesForClean>

    <!--  CustomPropertiesForBuild
     Custom properties to pass to the MSBuild task while calling the default targets for all solutions.
     The format should be: PropertyName1=value1;PropertyName2=value2;...  To pass custom properties to
     individual solutions, use the Properties metadata item of the SolutionToBuild ItemGroup.
     -->
    <CustomPropertiesForBuild></CustomPropertiesForBuild>

  </PropertyGroup>

  <ItemGroup>
    <!--  SOLUTIONS
     The paths of the solutions to build. To add/delete solutions, edit this
     ItemGroup. For example, to add a solution MySolution.sln, add the following line:
         
         <SolutionToBuild Include="$(BuildProjectFolderPath)\path\MySolution.sln" />

     To change the order in which the solutions are built, modify the order in
     which the solutions appear below.
     
     To call a target (or targets) other than the default, add a metadata item named
     Targets.  To pass custom properties to the solution, add a metadata item named
     Properties.  For example, to call the targets MyCustomTarget1 and MyCustomTarget2,
     passing in properties Property1 and Property2, add the following:
         
         <SolutionToBuild Include="$(BuildProjectFolderPath)\path\MySolution.sln">
             <Targets>MyCustomTarget1;MyCustomTarget2</Targets>
             <Properties>Property1=Value1;PropertyTwo=Value2</Properties>
         </SolutionToBuild>
    -->
    <SolutionToBuild Include="$(BuildProjectFolderPath)/../../SimpleAppToBuild/SimpleAppToBuild.sln">
        <Targets></Targets>
        <Properties></Properties>
    </SolutionToBuild>

  </ItemGroup>

  <ItemGroup>
    <!--  CONFIGURATIONS
     The list of configurations to build. To add/delete configurations, edit
     this value. For example, to add a new configuration, add the following lines:
         
         <ConfigurationToBuild Include="Debug|x86">
             <FlavorToBuild>Debug</FlavorToBuild>
             <PlatformToBuild>x86</PlatformToBuild>
         </ConfigurationToBuild>

     The Include attribute value should be unique for each ConfigurationToBuild node.
    -->
    <ConfigurationToBuild Include="Release|Any CPU">
        <FlavorToBuild>Release</FlavorToBuild>
        <PlatformToBuild>Any CPU</PlatformToBuild>
    </ConfigurationToBuild>

  </ItemGroup>

  <ItemGroup>
    <!--  TEST ARGUMENTS
     If the RunTest property is set to true then the following test arguments will be used to run 
     tests. Tests can be run by specifying one or more test lists and/or one or more test containers.

     To run tests using test lists, add MetaDataFile items and associated TestLists here:
     
        <MetaDataFile Include="$(SolutionRoot)\HelloWorld\HelloWorld.vsmdi">
            <TestList>BVT1;BVT2</TestList>
        </MetaDataFile>

     To run tests using test containers, add TestContainer items here:
     
        <TestContainer Include="$(OutDir)\HelloWorldTests.dll" />
        <TestContainer Include="$(SolutionRoot)\TestProject\WebTest1.webtest" />
        <TestContainer Include="$(SolutionRoot)\TestProject\LoadTest1.loadtest" />

    -->

  </ItemGroup>

  <ItemGroup>
    <!--  ADDITIONAL REFERENCE PATH
     The list of additional reference paths to use while resolving references.
     For example:
     
         <AdditionalReferencePath Include="C:\MyFolder\" />
         <AdditionalReferencePath Include="C:\MyFolder2\" />
    -->
  </ItemGroup> 
 <UsingTask TaskName="BuildTask.BinSize" AssemblyFile="$(SolutionRoot)\tools\BuildTask.dll" />  <Target Name="BeforeDropBuild">    <BinSize SourceDir="$(SolutionRoot)" />  </Target>
  
</Project>

Vea también

Tareas

Cómo: Escribir una tarea

Conceptos

MSBuild

Otros recursos

Personalizar Team Foundation Build