共用方式為


逐步解說:使用自訂工作自訂 Team Foundation Build

更新:2007 年 11 月

您可以建立您自己的自訂工作,並且在組建 (Build) 期間執行這些工作,藉此來擴充 Team Foundation Build。本主題將說明利用自訂工作來擴充組建定義所需執行的步驟。

必要的使用權限

您必須將 [管理組建] 使用權限設定為 [允許],才能完成此逐步解說。如需詳細資訊,請參閱 Team Foundation Server 使用權限

建立組建定義

使用 [組建定義] 對話方塊建立新的組建定義。您可以使共用現有的 TFSBuild.proj 檔,或使用 [MSBuild 專案檔建立精靈] 建立新的專案檔。您可以編輯 TFSBuild.proj 檔,自訂每一個與該檔案相關的組建定義。如需建立組建定義的詳細資訊,請參閱 HOW TO:建立組建定義

建立自訂工作

提供程式碼的工作,這些程式碼會在建置程序中執行。這些工作都包含在 MSBuild 專案檔的 Target 項目中。MSBuild 是 Team Foundation Build 後方的引擎。自訂工作的格式必須為 MSBuild 能了解的格式。每一項工作都必須實作為 .NET 類別 (Class),而這個類別又會實作在 Microsoft.Build.Framework.dll 組件 (Assembly) 中定義的 ITask 介面。

實作工作的方法有兩種:

  • 直接實作 ITask 介面。

  • 從 Microsoft.Build.Utilities.dll 組件中定義的 Helper 類別 Task 衍生您的類別。Task 會實作 ITask,而且會預設實作某些 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

在您撰寫工作之後,必須為它註冊,並且在其中一個目標中呼叫它,這樣工作程式碼才會在建置流程中的必要位置執行。如果您之前使用 [MSBuild 專案檔建立精靈] 建立 MSBuild 專案檔,並且接受原始檔控制中的預設位置,則您的 TFSBuild.proj 檔會位於 Visual Studio Team System 原始檔控制的 $/MyTeamProject/TeamBuildTypes/MyBuildName 資料夾中。在這種情況下,MyTeamProject 會是您 Team 專案的名稱,而且是所有 Team 專案原始檔的根節點,而 MyBuildName 是您為原本建立 TFSBuild.proj 檔之組建定義指定的名稱。

若要判斷 TFSBuild.proj 檔的原始檔控制位置,請在 Team 總管的 [組建] 資料夾中選取組建定義,以滑鼠右鍵按一下該定義,然後按一下 [編輯]。TFSBuild.proj 檔的原始檔控制位置會在 [組建定義] 對話方塊的 [專案檔] 窗格中顯示。

注意事項:

請不要編輯 Microsoft.TeamFoundation.Build.targets 檔,因為自訂部分將會套用至該部電腦上的所有組建。

如需簽出檔案的詳細資訊,請參閱使用 Team Foundation 版本控制

註冊您的工作

在您建立工作之後,必須在 TFSBuild.proj 檔的 UsingTask 項目中指定工作,為它進行註冊。UsingTask 項目會將工作對應至包含該工作實作 (Implementation) 的組件。如需詳細資訊,請參閱 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 Build 組態檔

  2. 開啟 TFSBuild.proj 檔,並且加入您在上述步驟中選擇的 Target 項目。

  3. 加入工作項目,以便在 Target 項目內執行工作。

    例如,下列 TFSBuild.proj 中的 XML 會在 BeforeGet 目標中執行 SimpleTask 工作,這項工作會緊接在 Get 目標之前執行。

    <Target Name="BeforeGet">
        <SimpleTask />
    </Target>
    
  4. 儲存檔案。

簽入檔案

您必須簽入 TFSBuild.proj 檔,才能使變更生效。Team Foundation Build 會將這個檔案從原始檔控制中複製到組建電腦上,因此在您電腦上的本機複本中所做的任何變更都不會影響組建。如需將檔案簽入至原始檔控制的詳細資訊,請參閱 HOW TO:簽入暫止的變更

如果需要 Team Foundation Build 將工作 DLL 複製到組建電腦中,必須將工作 DLL 加入至 Team 專案節點下的原始檔控制中。

範例工作

這個範例會藉由記錄組建所產生檔案大小的方式,建立擴充組建定義或與 TFSBuild.proj 檔相關定義的自訂工作。這個範例包含兩個部分:

  • 工作程式碼

  • TFSBuild.proj 檔。

在建置記錄檔 Buildlog.txt 中可以看見這項工作所記錄的資訊,此記錄檔位於建置放置的資料夾中。建置記錄檔包含類似下列的資訊:

位於 d:\BuildDir\MyTeamProj\MyBuildType\sources\..\Binaries\Release dir,總大小為 9216 個位元組。

C# 工作程式碼

下面範例中所包含的程式碼會加上 Binaries 資料夾中的檔案大小,以計算二進位檔總計大小。

注意事項:

在組建期間產生的所有二進位檔,都會位於組建代理程式上組建目錄資料夾內的 Binaries 資料夾中。

若要將這項工作包含在組建中,必須將已編譯的 DLL 簽入至 Team 專案資料夾下的原始檔控制中。這麼做可以保證,在組建期間一定會將檔案複製到組建代理程式上。

下列程式碼會計算位於組建目錄的 Binaries 資料夾中二進位檔大小。Team Foundation Build 指令碼會將方案根目錄 (Solution Root) 屬性傳遞給這項工作。

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 Build 組態檔

下面範例包含已修改之 TFSBuild.proj 檔中的程式碼。此範例 XML 幾乎全部是由 [MSBuild 專案檔建立精靈] 產生的,只有位於檔案結尾的 UsingTask 項目和 Target 項目例外。

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

請參閱

工作

HOW TO:撰寫工作

概念

MSBuild

其他資源

自訂 Team Foundation Build