TFS 2013构建代理共享公共构建文件夹

时间:2013-11-03 16:35:56

标签: tfs tfsbuild

我在内部使用TFS 2013。我在Build机器上配置了四个构建代理。几个构建定义编译ASP .NET网站。我配置了msbuild参数,将IIS应用程序部署到集成服务器,该服务器位于Rackspace中。

默认情况下,webdeploy通过比较文件日期来执行差异部署。在我看来,这是一个很大的优势,因为将文件从我们的网络复制到Rackspace需要相当长的时间。现在,为了保留文件日期,构建代理必须编译相同的基本源代码集。在每个构建中,只有差异源代码会产生一个新的DLL,从而最大限度地减少部署的文件数量。

所有这些工作正常,但需要注意:必须将给定的构建定义分配给构建代理(通过代理名称或标记)。问题是,当分配给同一代理的所有构建版本排队时,我会创建大量意外事件。他们排队等候,直到上一次构建完成。

在理想的世界中,任何代理都应该能够处理任何构建,但无论代理如何,编译的源代码都必须相同。

我尝试将所有代理的工作文件夹更改为指向同一位置但我收到错误,因为无法将两个代理映射到同一文件夹。我猜每个代理商都有一个工作区。

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

最后我找到了一种方法。以下是您需要做的所有更改:

  • 默认情况下,每个代理的工作文件夹是$(SystemDrive)\ Builds \ $(BuildAgentId)\ $(BuildDefinitionPath)。这意味着每个BuildAgentId有一个工作文件夹。我更改了它,以便所有代理共享同一个文件夹:$(SystemDrive)\ Builds \ WorkingFolder \ $(BuildDefinitionPath)
  • 默认情况下,在运行时,工作流会创建一个看起来像“[BuildDefinitionId] [AgentId] [MachineName]”的工作区。由于所有代理共享同一个工作文件夹,因此尝试创建每个单独的工作区时出错。解决方案是在构建定义中:编辑xaml并查找名为“从Team Foundation版本控制获取源”的活动。有一个名为WrokspaceName的属性。由于我希望每个构建定义都有一个工作区,因此我将该属性设置为BuildDetail.BuildDefinition.Name。
  • 保存自定义构建模板并创建使用它的构建。
  • 确保选项“1. TF VersionControl / 1. Clean workspace”设置为False。否则,构建将清除每个构建的所有源代码。
  • 确保选项“2. Build / 3.Clean build”设置为false。否则,构建将在每次构建时清除输出二进制文件。

使用此设置,您可以在任何代理上排队相同的构建,并且所有代理都将指向相同的源代码和bin输出。当源代码更改时,仅重新编译受影响的二进制文件。我在模板中有一个自定义步骤,使用msdeploy.exe将输出文件部署到IIS,以及我们webfarm中的所有服务器。现在我的构建+部署需要一到两分钟,因为只有在构建期间更改的dll或内容才会同步到服务器。

答案 1 :(得分:1)

您无法在同一文件夹中运行两个构建代理。构建代理的目的是并行运行多个构建,通常在不同的PC上运行。如果你尝试在相同的源代码上运行它们,那么(a)它是毫无意义的,因为完全相同的源的两个构建应该产生相同的结果,并且(b)它们几乎肯定会相互跳过并导致构建到失败或产生意外结果。

如果您希望能够构建并部署一系列版本的代码库,那么有两种选择:

  • 如果排队多个构建,那么最后一个构建将“获胜”,因此中间构建没有实际价值。因此,如果您在第一次构建完成之前签入新代码,那么您也可以停止活动构建并启动新构建。你应该问问自己,为什么构建速度太慢,或者为什么你经常检查更改,这是必要的。

  • 如果每个构建产生对已部署结果的增量更新,那么您需要将构建的输出传递给某个部署代理,该部署代理能够针对部署的版本区分它并仅发送要部署的更改。这可以设置为从多个构建代理收集结果,如果这将是有益的。

  • 但是我想知道你的构建是否很慢,因为你每次都做一个完整的构建(它清理构建文件夹,获取所有源代码,并进行完全重建),当你想要的是一个增量构建(获取最新的更改,仅编译受影响的内容,并快速完成)。也许你应该调查你的构建增量。