65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 PowerShell 自动从 Team System 提取和构建

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.86/5 (5投票s)

2008年4月20日

BSD

8分钟阅读

viewsIcon

64808

downloadIcon

983

我们描述了一个 PowerShell 脚本,用于从 Team System 版本控制中提取源代码并自动化构建过程

 

引言

许多软件项目的薄弱环节是最终的构建。通常,我们认为当最后一行代码在我们的机器上成功编译时,项目就完成了。但还有很多工作要做,需要将所有零散的环节连接起来,以便其他人可以从版本控制中提取代码并进行构建。而仅仅因为别人可以提取和构建项目,并不意味着这个过程是令人愉快或容易的。将 Team Foundation Server (TFS) 工作区映射到磁盘上的某个位置的繁琐过程,进一步增加了在干净的测试环境中构建代码的痛苦。

提取和构建代码的过程应该自动化,以确保过程的可重现性。自动化还能使过程更快、更容易,尽管这是次要的。

在本文中,我们介绍了一个 PowerShell 脚本,我们使用它来自动化从 Visual Studio Team System 提取应用程序源代码并构建 Visual Studio .NET 解决方案。

为什么不使用 MSBuild/TeamBuild?

那么,我们为什么不直接使用 MSBuild/TeamBuild 工具,而是编写一个 PowerShell 脚本呢?我们想要一个轻量级且易于开发人员使用的构建工具。这个脚本可以在任何安装了 Visual Studio .NET 的机器上使用,并且不需要设置 Team Build Server。开发人员可以实时观看构建过程。我们也想尝试 PowerShell。我们使用这个脚本作为 ASP.NET 应用程序部署过程的一部分已经一年多了,它一直很好地为我们服务。

PowerShell 背景

如果您没有安装 PowerShell,请从Microsoft下载。

在运行任何 PowerShell 脚本之前,必须设置执行策略。例如,从 PowerShell 提示符输入 set-executionpolicy remoteSigned 将允许运行未签名的本地脚本,例如此脚本。这只需要执行一次。此后,任何 PowerShell 脚本都可以在该计算机上运行。

您可能还会喜欢 PowerShell 社区扩展 (PSCX) 提供的 PowerShell 工具,在此处可用。这个库为您的 PowerShell 安装添加了许多有价值的工具。一个简单但有用的添加功能是能够在 Windows 资源管理器中右键单击一个文件夹并选择“在此处打开 PowerShell”。

PowerShell 需要显式指定脚本的路径。这是一个安全特性,可以防止有人运行一个与您熟悉的脚本同名但位置不同的恶意脚本。这意味着您不能仅仅通过输入脚本名来运行当前目录下的脚本foo.ps1。您必须指定.\foo.ps1

Using the Code

脚本功能

PowerShell 脚本BuildMe.ps1以一个小的 XML 配置文件作为输入。我们这里称之为BuildMe.xml,但它可以命名为任何您喜欢的名称。

PowerShell 脚本

  1. 读取包含您要构建的 TFS 项目数据的输入 XML 文件
  2. 记住任何当前映射的驱动器号
  3. 映射任何新需要的驱动器(如输入文件中指定);这些在构建期间可用
  4. 在当前文件夹位置创建一个临时工作区
  5. 从 TFS 源存储库提取源代码(在输入文件中描述)
  6. 使用解决方案文件中描述的 Visual Studio .NET 版本构建指定的解决方案/配置
  7. 删除临时工作区
  8. 恢复脚本开始之前存在的任何驱动器映射。

如何运行脚本

输入文件可以通过三种方式指定给脚本

  1. 如果不提供参数,脚本将在当前目录中查找名为BuildMe.xml的文件。
  2. 如果您的输入文件名称不同,或者位于不同位置,您可以将文件名和文件系统位置作为命令行参数指定。
  3. 您可以指定输入文件在 TFS 中的路径。

要运行脚本,请执行以下操作:

  1. 编辑BuildMe.ps1文件,提供您的 TFS 服务器计算机的名称。在文件中第 126 行,将类似 $g_myServer = "theTFSserverName" 的文本更改为您自己的服务器名称。
  2. 导航到一个工作文件夹,例如D:\buildarea\BuildMe.ps1必须可以从该文件夹访问。
  3. 如果您安装了 PSCX,请右键单击该文件夹并从上下文菜单中选择“在此处打开 PowerShell”。否则,先打开一个 PowerShell 窗口并导航到工作文件夹。
  4. 在出现的 CommandWindow 中输入.\BuildMe.ps1或指定BuildMe.ps1文件的完整路径。这将导致从当前目录中的默认文件BuildMe.xml读取输入。输入文件可以具有任何有效的名称。
  5. 或者,您可以指定 TFS 中输入 XML 文件的位置:.\BuildMe.ps1 $/MyTFSproject/BuildMe.xml
    路径开头的$/表示 XML 文件位于 TFS 中。这最方便,因为它允许您不必先从 TFS 中提取输入 XML 文件;脚本会执行版本控制中的“get”。

如果脚本使用工作目录中的默认输入文件运行,则 Visual Studio .NET 编译器的输出将写入BuildMe.xml.SolutionBuild.log。如果指定了不同的输入文件名,则日志文件名将反映输入文件的名称,并在其后附加SolutionBuild.log字符串。此日志文件只是 Visual Studio 构建解决方案时生成的日志文件。

注意:一个目录位置一次只能映射一个 TFS 工作区。如果您尝试在映射到另一个项目工作区的位置构建第二个项目,脚本将打印一条警告,说明 CreateMapping 失败,因为该路径已映射到某个工作区。

准备输入文件

要构建的项目在输入文件中指定如下。下面的示例项目是一个虚构的 TFS 项目,名为BEETLE

BuildMe.xml

<Solution>

  <SlnToBuild> .\BEETLE\BEETLE_sln\BEETLE.sln </SlnToBuild>
  <ConfigToBuild>  Release </ConfigToBuild>
  <BuildBitsOutputFolder>
    .\BEETLE\BEETLE_sln\projects\BEETLE_Setup\($ConfigToBuild)
  </BuildBitsOutputFolder>

  <MappedDrive>
    <Drive> M: </Drive>
    <MapTo> \\myServer\myShare\myDir </MapTo>
  </MappedDrive>

  <TFSproject >
    <ProjName> $/BEETLE </ProjName>
    <ProjLocalDir> .\BEETLE\code </ProjLocalDir>
    <ProjTreeToGet> $/BEETLE </ProjTreeToGet>
    <Label> v0.6 </Label>
  </TFSproject>

</Solution>

<SlnToBuild> 是要构建的 Visual Studio .NET 解决方案文件(相对于当前目录位置)的路径。当脚本处理<TFSProject>元素时,此文件将从 TFS 中提取。

<ConfigToBuild> 是要构建的 Visual Studio .NET 配置的名称。如果想构建多个配置,可以重复此元素。

<BuildBitsOutputFolder> 是构建结果预期生成的路径(相对于当前目录位置)。这是一个“仅信息”路径,在成功构建结束时由脚本输出。路径不会被验证。

<MappedDrive> 元素提供了一种映射构建期间所需驱动器的机制。<MapTo>元素可以指定一个网络位置或您本地磁盘上的一个位置。SUBST命令用于映射本地驱动器号。如果具有相同字母的驱动器已映射,它将被记住、取消映射,然后指定的字母将被映射。在构建结束时,指定的驱动器号将被取消映射,并且之前的映射将得到恢复。此元素可以重复。如果不需要映射驱动器,此元素可以省略。

<TFSproject> 元素指定有关将从版本控制系统中提取的 TFS 项目的信息。此元素可以重复。

<ProjName> 是 TFS 项目的名称。注意$/前缀,它表示这是 TFS 系统中的一个路径。

<ProjLocalDir> 是从 TFS 提取源代码树时,在本地磁盘上放置它的(相对)位置。

<ProjTreeToGet> 是源代码“get”应该开始的 TFS 项目文件夹层次结构中的位置。注意$/前缀,它表示这是 TFS 路径。从该点到树的底层的所有代码都将从 TFS 中检索。在上面的示例中,来自 TFS 位置$/BEETLE的所有代码将被提取并放置在硬盘上的相对位置.\BEETLE\code

<Label> 是您应用于要检索的源代码的标签。要获取“最新版本”,只需将此元素的内容留空即可。

示例

PSH> set-executionPolicy unrestricted

这放宽了 PowerShell 中的默认安全设置,允许您的代码运行。您只需要在每台计算机上执行一次此操作。此后它将保持有效。

PSH> .\BuildMe.ps1 

运行 PowerShell 脚本。它将在当前目录中读取默认输入文件(BuildMe.xml)。输入文件中描述的 TFS 项目将从 TFS 中提取,并在输入文件中描述的位置进行构建。

PSH> .\BuildMe.ps1 MyProject.xml

运行 PowerShell 脚本。它将在当前目录中读取指定的输入文件(MyProject.xml)。输入文件中描述的 TFS 项目将从 TFS 中提取,并在输入文件中描述的位置进行构建。

PSH> .\BuildMe.ps1 $/BETTLE/BuildMe.xml

运行 PowerShell 脚本。它将从$/BEETLE TFS 项目中获取输入文件BuildMe.xml,并将其放置在当前目录中。然后将读取输入文件,并从 TFS 中提取输入文件中描述的 TFS 项目。然后将在输入文件中描述的位置构建项目。注意:输入文件上的$/前缀表示脚本该输入文件位于 TFS 中(而不是本地磁盘上)。

PSH> .\BuildMe.ps1 $/BETTLE/BuildMe.xml v1.2

与上面相同,只是标签为“v2.1”的输入文件将从 TFS 中提取。输入文件中的标签将用于提取其他源代码。

关注点

我们发现 TFS .NET 类库非常全面,但也很少有文档且难以使用。此处显示的 PowerShell 代码说明了 TFS API 在几个有趣操作中的使用。特别感谢James Manning,他的博客帮助我们了解了 TFS API。

历史

  • 2008 年 4 月 18 日:初始发布
© . All rights reserved.