チュートリアル : カスタム タスクを使って Team Foundation ビルドをカスタマイズする

更新 : 2007 年 11 月

独自のカスタム タスクを作成してビルド中に実行することで、Team Foundation ビルドを拡張できます。ここでは、カスタム タスクを使用してビルド定義を拡張するために必要な手順について説明します。

必要なアクセス許可

このチュートリアルを完了するには、[ビルドを管理します] のアクセス許可が [許可] に設定されている必要があります。詳細については、「Team Foundation Server のアクセス許可」を参照してください。

ビルド定義の作成

新しいビルド定義を作成するには、[ビルド定義] ダイアログ ボックスを使用します。既存の TFSBuild.proj ファイルを共有するか、MSBuild プロジェクト ファイルの作成ウィザードで新しいファイルを作成できます。TFSBuild.proj ファイルを編集して、それに関連付けられているビルド定義をカスタマイズします。ビルド定義の作成の詳細については、「方法 : ビルド定義を作成する」を参照してください。

カスタム タスクの作成

タスクでは、ビルド プロセスの間に実行するコードを指定します。これらのタスクは MSBuild プロジェクト ファイルの Target 要素に含まれます。Team Foundation ビルドの内部処理は MSBuild によって処理されます。カスタム タスクは MSBuild で扱える形式になっている必要があります。各タスクは、ITask インターフェイスを実装する .NET クラスとして実装する必要があります。これは、Microsoft.Build.Framework.dll アセンブリで定義されます。

タスクを実装する際には、次の 2 つの手法があります。

  • ITask インターフェイスを直接実装する。

  • Microsoft.Build.Utilities.dll アセンブリで定義されるヘルパー クラス Task からクラスを派生させます。TaskITask を実装し、一部の ITask メンバの既定の実装を提供します。

どちらの方法でも、Execute という名前のメソッドをクラスに追加する必要があります。これはタスクの実行時に呼び出されるメソッドです。このメソッドはパラメータを受け取らず、Boolean 値を返します。タスクが成功した場合は true、失敗した場合は false となります。次の例は、アクションを実行せずに true を返すタスクを示します。

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

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

タスクではパラメータの受け入れ、イベントの発生、出力の記録も実行できます。詳細については、「MSBuild タスク」および「MSBuild の概要」を参照してください。

TFSBuild.proj のチェックアウト

タスクを記述した後、ビルド プロセスの目的の時点でタスク コードが実行されるように、タスクを登録してターゲットの 1 つで呼び出す必要があります。MSBuild プロジェクト ファイルの作成ウィザードを使用して MSBuild プロジェクト ファイルを作成し、ソース管理で既定の場所を使用した場合、TFSBuild.proj ファイルは、Visual Studio Team System ソース管理のフォルダ $/MyTeamProject/TeamBuildTypes/MyBuildName にあります。このシナリオでは、MyTeamProject がチーム プロジェクトの名前であり、すべてのチーム プロジェクト ソースのルート ノードです。MyBuildName は、最初に TFSBuild.proj ファイルを作成したビルド定義に付けた名前です。

TFSBuild.proj ファイルのソース管理の場所を確認するには、チーム エクスプローラで [ビルド] フォルダ内のビルド定義を右クリックし、[編集] をクリックします。TFSBuild.proj ファイルのソース管理の場所が、[ビルド定義] ダイアログの [プロジェクト ファイル] ペインに表示されます。

ms400767.alert_note(ja-jp,VS.90).gifメモ :

Microsoft.TeamFoundation.Build.targets ファイルは、編集するとカスタマイズがそのコンピュータ上のすべてのビルドに適用されるため、編集しないでください。

ファイルのチェックアウトの詳細については、「Team Foundation のバージョン管理の使用」を参照してください。

タスクの登録

タスクを作成した後、TFSBuild.proj ファイルの UsingTask 要素でタスクを指定して、タスクを登録する必要があります。UsingTask 要素は、タスクの実装を持つアセンブリに対応付けます。詳細については、「UsingTask 要素 (MSBuild)」を参照してください。

カスタム タスクを登録するには

  1. TFSBuild.proj ファイルを開きます。

  2. UsingTask 要素をファイルに追加して、タスクの詳細を指定します。

    次に例を示します。

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

    または

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

    または

    <UsingTask
        TaskName="MyTasks.SimpleTask"
        AssemblyFile="c:\somediskpath\MyAssembly.Build.Tasks.dll"/>
    
  3. ファイルを保存します。

カスタム タスクの実行

タスクを作成して登録した後は、ビルド プロセスでタスクを実行する時点を指定する必要があります。

タスクを実行するには

  1. ビルド プロセス内でカスタム タスクを実行する時点を決定します。

    ビルド プロセスを拡張できる時点の詳細については、「Team Foundation ビルドの構成ファイルについて」を参照してください。

  2. TFSBuild.proj を開き、前に選択した Target 要素を追加します。

  3. タスクを実行するには、Target 要素内にタスク要素を追加します。

    たとえば、TFSBuild.proj 内の次の XML は、BeforeGet ターゲットで SimpleTask タスクを実行します。このターゲットは、Get ターゲットの直前に実行されます。

    <Target Name="BeforeGet">
        <SimpleTask />
    </Target>
    
  4. ファイルを保存します。

ファイルのチェックイン

変更を有効にするには、TFSBuild.proj ファイルをチェックインする必要があります。このファイルは Team Foundation ビルドによってソース管理からビルド コンピュータにコピーされるので、コンピュータのローカル コピーに加えた変更はビルドには反映されません。ソース管理へのファイルのチェックインの詳細については、「方法 : 保留中の変更をチェックインする」を参照してください。

Team Foundation ビルドでタスク DLL をビルド コンピュータにコピーする必要がある場合は、チーム プロジェクト ノードの下のソース管理にタスク DLL を追加する必要があります。

サンプル タスク

この例では、TFSBuild.proj ファイルに関連付けられたビルド定義を拡張して、ビルドで生成されたファイルのサイズをログに記録するカスタム タスクを作成します。この例は 2 つの部分で構成されています。

  • タスク コード。

  • TFSBuild.proj ファイル。

このタスクで記録されたログ情報は、ビルド ログ ファイル Buildlog.txt に出力されます。このファイルは、ビルド ドロップ フォルダにあります。ビルド ログには、次のような情報が格納されます。

d:\BuildDir\MyTeamProj\MyBuildType\sources\..\Binaries\Release ディレクトリ内の合計サイズは 9,216 バイトです。

C# タスク コード

バイナリ フォルダ内のファイルのサイズを加算して、バイナリ サイズの合計を計算するコードを次の例に示します。

ms400767.alert_note(ja-jp,VS.90).gifメモ :

ビルド中に生成されるバイナリはすべて、ビルド エージェントのビルド ディレクトリ フォルダ内の Binaries フォルダにあります。

このタスクをビルドに含めるには、コンパイルされた DLL をチーム プロジェクト フォルダのソース管理にチェックインする必要があります。これにより、ビルド中にファイルがビルド エージェントにコピーされます。

次のコードは、ビルド ディレクトリの Binaries フォルダにあるバイナリのサイズを計算します。ソリューション ルート プロパティは、Team Foundation ビルド スクリプトによってこのタスクに渡されます。

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;
    }
}

TFSBuild.proj ファイル

タスクがコンパイルされ、ソース管理にチェックインされた後、TFSBuild.proj ファイルからタスクを呼び出す必要があります。次の例では、ファイルがコンパイルされ、すべてのバイナリが Binaries ディレクトリにコピーされた後にタスクを呼び出す必要があります。したがって、BeforeDropBuild ターゲットでタスクを実行する必要があります。TFSBuild.proj で拡張できるターゲットの詳細については、「Team Foundation ビルドの構成ファイルについて」を参照してください。

変更された TFSBuild.proj ファイル内のコードを次の例に示します。このサンプル XML は、ファイルの最後にある UsingTask 要素と Target 要素を除いて、MSBuild プロジェクト ファイルの種類の作成ウィザードによって生成されます。

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

参照

処理手順

方法 : タスクを記述する

概念

MSBuild

その他の技術情報

Team Foundation ビルドのカスタマイズ