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






4.86/5 (5投票s)
我们描述了一个 PowerShell 脚本,
引言
许多软件项目的薄弱环节是最终的构建。通常,我们认为当最后一行代码在我们的机器上成功编译时,项目就完成了。但还有很多工作要做,需要将所有零散的环节连接起来,以便其他人可以从版本控制中提取代码并进行构建。而仅仅因为别人可以提取和构建项目,并不意味着这个过程是令人愉快或容易的。将 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 脚本
- 读取包含您要构建的 TFS 项目数据的输入 XML 文件
- 记住任何当前映射的驱动器号
- 映射任何新需要的驱动器(如输入文件中指定);这些在构建期间可用
- 在当前文件夹位置创建一个临时工作区
- 从 TFS 源存储库提取源代码(在输入文件中描述)
- 使用解决方案文件中描述的 Visual Studio .NET 版本构建指定的解决方案/配置
- 删除临时工作区
- 恢复脚本开始之前存在的任何驱动器映射。
如何运行脚本
输入文件可以通过三种方式指定给脚本
- 如果不提供参数,脚本将在当前目录中查找名为BuildMe.xml的文件。
- 如果您的输入文件名称不同,或者位于不同位置,您可以将文件名和文件系统位置作为命令行参数指定。
- 您可以指定输入文件在 TFS 中的路径。
要运行脚本,请执行以下操作:
- 编辑BuildMe.ps1文件,提供您的 TFS 服务器计算机的名称。在文件中第 126 行,将类似
$g_myServer = "theTFSserverName"
的文本更改为您自己的服务器名称。 - 导航到一个工作文件夹,例如D:\buildarea\。BuildMe.ps1必须可以从该文件夹访问。
- 如果您安装了 PSCX,请右键单击该文件夹并从上下文菜单中选择“在此处打开 PowerShell”。否则,先打开一个 PowerShell 窗口并导航到工作文件夹。
- 在出现的 CommandWindow 中输入.\BuildMe.ps1或指定BuildMe.ps1文件的完整路径。这将导致从当前目录中的默认文件BuildMe.xml读取输入。输入文件可以具有任何有效的名称。
- 或者,您可以指定 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 日:初始发布