Procédure pas à pas : personnalisation de Team Foundation Build avec une tâche personnalisée
Mise à jour : novembre 2007
Vous pouvez étendre Team Foundation Build en créant vos propres tâches personnalisées et en les exécutant pendant une génération. Cette rubrique explique les étapes nécessaires pour étendre une définition de build à l'aide d'une tâche personnalisée.
Autorisations requises
Pour exécuter cette procédure pas à pas, vous devez disposer de l'autorisation Administrer une build avec la valeur Autoriser. Pour plus d'informations, consultez Autorisations de Team Foundation Server.
Création d'une définition de build
Utilisez la boîte de dialogue Définition de build pour créer une définition de build. Vous pouvez partager un fichier TFSBuild.proj existant ou en créer un à l'aide de l'Assistant Création de fichier de projet MSBuild. Vous modifiez le fichier TFSBuild.proj pour personnaliser chaque définition de build associée à lui. Pour plus d'informations sur la création de définitions de build, consultez Comment : créer une définition de build.
Création de tâches personnalisées
Les tâches fournissent le code exécuté pendant le processus de génération. Ces tâches sont contenues dans les éléments Target de fichiers projet MSBuild. MSBuild est le moteur derrière Team Foundation Build. Les tâches personnalisées doivent être dans un format que MSBuild comprend. Chaque tâche doit être implémentée comme une classe .NET qui implémente l'interface ITask, qui est définie dans l'assembly Microsoft.Build.Framework.dll.
Vous pouvez suivre deux approches pour implémenter une tâche :
Implémentez l'interface ITask directement.
Dérivez votre classe de la classe d'assistance, Task, qui est définie dans l'assembly Microsoft.Build.Utilities.dll. Task implémente ITask et fournit des implémentations par défaut de certains membres ITask.
Dans les deux approches, vous devez ajouter à votre classe une méthode nommée Execute, qui est la méthode appelée lorsque la tâche s'exécute. Cette méthode ne prend pas de paramètres et retourne une valeur Boolean : true si la tâche réussit ou false si elle échoue. L'exemple suivant montre une tâche que n'exécute aucune action et retourne true.
using System;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace MyTasks
{
public class SimpleTask : Task
{
public override bool Execute()
{
return true;
}
}
}
Les tâches peuvent également accepter des paramètres, déclencher des événements et enregistrer la sortie dans un journal. Pour plus d'informations, consultez Tâches MSBuild et Vue d'ensemble de MSBuild.
Extraction de TFSBuild.proj
Après avoir écrit votre tâche, vous devez l'inscrire et l'appeler dans l'une des cibles afin que votre code de tâche s'exécute au point désiré dans le processus de génération. Si vous avez utilisé l'Assistant Création de fichier de projet MSBuild pour créer un fichier projet MSBuild et accepté l'emplacement par défaut dans le contrôle de code source, votre fichier TFSBuild.proj se trouve dans le dossier $/MonProjetD'équipe/TeamBuildTypes/MonNomDeBuild dans votre contrôle de code source Visual Studio Team System. Dans ce scénario, MonProjetD'équipe est le nom de votre projet d'équipe et le nœud racine de toutes vos sources de projet d'équipe, et MonNomDeBuild est le nom que vous avez donné à votre définition de build pour laquelle vous avez, à l'origine, créée le fichier TFSBuild.proj.
Pour déterminer l'emplacement de contrôle de code source du fichier TFSBuild.proj, sélectionnez la définition de génération dans le dossier Builds dans Team Explorer, cliquez dessus avec le bouton droit, puis cliquez sur Modifier. L'emplacement de contrôle de code source du fichier TFSBuild.proj s'affiche dans le volet Fichier projet de la boîte de dialogue Définition de build.
Remarque : |
---|
Ne modifiez pas le fichier Microsoft.TeamFoundation.Build.targets parce que les personnalisations s'appliqueront à toutes les générations sur cet ordinateur. |
Pour plus d'informations sur l'extraction de fichiers, consultez Utilisation du contrôle de version Team Foundation.
Inscription de votre tâche
Après avoir créé votre tâche, vous devez l'inscrire en spécifiant votre tâche dans un élément UsingTask du fichier TFSBuild.proj. L'élément UsingTask mappe la tâche à l'assembly qui contient l'implémentation de la tâche. Pour plus d'informations, consultez UsingTask, élément (MSBuild).
Pour inscrire une tâche personnalisée
Ouvrez le fichier TFSBuild.proj.
Ajoutez un élément UsingTask au fichier et spécifiez les détails de votre tâche.
Par exemple :
<UsingTask TaskName="MyTasks.SimpleTask" AssemblyName="MyAssembly.Build.Tasks"/>
- ou -
<UsingTask TaskName="MyTasks.SimpleTask" AssemblyFile="MyAssembly.Build.Tasks.dll"/>
- ou -
<UsingTask TaskName="MyTasks.SimpleTask" AssemblyFile="c:\somediskpath\MyAssembly.Build.Tasks.dll"/>
Enregistrez le fichier.
Exécution de la tâche personnalisée
Maintenant que vous avez créé et inscrit votre tâche, vous devez spécifier le point dans le processus de génération au niveau duquel vous souhaitez exécuter votre tâche.
Pour exécuter une tâche
Choisissez où vous souhaitez exécuter votre tâche personnalisée dans le processus de génération.
Pour plus d'informations sur l'extension du processus de génération, consultez Présentation des fichiers de configuration de Team Foundation Build.
Ouvrez TFSBuild.proj et ajoutez l'élément Target que vous avez choisi ci-dessus.
Ajoutez l'élément de tâche pour exécuter votre tâche à l'intérieur de l'élément Target.
Par exemple, le XML suivant dans TFSBuild.proj exécute la tâche SimpleTask dans la cible BeforeGet qui s'exécute immédiatement avant la cible Get.
<Target Name="BeforeGet"> <SimpleTask /> </Target>
Enregistrez le fichier.
Archivage de fichiers
Vous devez archiver le fichier TFSBuild.proj pour que les modifications prennent effet. Team Foundation Build copie ce fichier du contrôle de code source vers l'ordinateur de build. Ainsi, les modifications apportées à la copie locale n'affecteront pas la génération. Pour plus d'informations sur l'archivage de fichiers dans le contrôle de code source, consultez Comment : archiver les modifications en attente.
Si vous avez besoin de Team Foundation Build pour copier la DLL de tâche vers l'ordinateur de build, vous devez ajouter la DLL de tâche au contrôle de code source sous le nœud de projet d'équipe.
Exemple de tâche
Cet exemple crée une tâche personnalisée qui étend la/les définition(s) de build associée(s) au fichier TFSBuild.proj en enregistrant la taille des fichiers produite par la build. L'exemple se divise en deux parties :
Le code de la tâche.
Le fichier TFSBuild.proj.
Les informations enregistrées de cette tâche peuvent être consultées dans le fichier journal de génération, Buildlog.txt qui se trouve dans le dossier cible de build. Le journal de génération contient des informations semblables aux éléments suivants :
La taille totale est de 9216 octets dans le répertoire d:\BuildDir\MyTeamProj\MyBuildType\sources\..\Binaries\Release
Code de tâche C#
L'exemple suivant contient le code qui calcule la taille binaire totale en ajoutant la taille des fichiers dans le dossier des binaires.
Remarque : |
---|
Tous les binaires générés pendant une génération se trouvent dans le dossier Binaries du répertoire de build sur l'agent de build. |
Pour que cette tâche soit incluse dans une génération, la DLL compilée doit être archivée dans le contrôle de code source sous le dossier du projet d'équipe. Cela garantit que le fichier sera copié vers l'agent de build pendant une génération.
Le code suivant calcule la taille des binaires présents dans le dossier Binaires du répertoire de build. La propriété de racine de la solution est passée à cette tâche par le script 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;
}
}
Fichier TFSBuild.proj
Une fois que la tâche est compilée et archivée dans le contrôle de code source, elle doit être appelée depuis le fichier TFSBuild.proj. Dans cet exemple, la tâche doit être appelée après que les fichiers ont été compilés et que tous les binaires ont été copiés dans le répertoire Binaries. Par conséquent, la tâche doit être exécutée dans la cible BeforeDropBuild. Pour plus d'informations sur les cibles extensibles dans TFSBuild.proj, consultez Présentation des fichiers de configuration de Team Foundation Build.
L'exemple suivant contient le code dans le fichier TFSBuild.proj modifié. L'exemple XML est presque entièrement généré par l'Assistant Création de fichier de projet MSBuild à l'exception de l'élément UsingTask et de l'élément Target situés à la fin du fichier.
<?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>