在 TeamCity 中处理 Perforce 工作空间
为了执行与 Perforce 相关的操作,TeamCity 通常以“无工作区”模式运行,即它在没有工作区上下文的情况下执行 Perforce 命令。 例如,跟踪更改或执行大部分服务器端操作并不需要工作区。
创建工作空间的情况有:
如果启用了 代理端签出(agent-side checkout) (它是默认的签出模式)。 在这种情况下,TeamCity 会创建一个 Perforce 工作空间来检出构建源代码。
使用 Perforce Helix Core 的 版本化项目设置。
使用 Perforce 流作为功能分支。 在这种情况下,TeamCity 在 Perforce 服务器上创建工作空间,以正确处理任务流。
Perforce 工作区名称
创建的工作空间的名称以 TC_p4_ 为前缀。 为了支持 功能分支 ,在 Perforce 服务器端创建的工作区是带有 TC_p4_server_ 前缀的。
如果您的构建配置使用了 代理端签出(agent-side checkout) ,您可以按照以下步骤修改工作空间名称:
通过
teamcity.perforce.workspace.prefix配置参数 添加工作区名称前缀。如果您的工作流需要特定的工作区名称模式,那么请设定一个自定义的工作区名称。 为了做到这一点,请设置
vcsroot。<VCSRootExternalID>。p4client参数。 如果指定了自定义工作空间名称,TeamCity 将根据相应的 VCS 根目录设置(例如,如果 VCS 根目录启用了流支持,则应用相关流参数)在检出之前更新工作空间。 另见: 在云代理上重复使用已签出的源代码。
工作空间名称还包括构建代理名称和由签出目录以及(可选的)签出规则生成的哈希值。
Perforce 工作区参数
在使用 代理端签出(agent-side checkout) 时,TeamCity 提供了描述在签出过程中创建的 Perforce 工作区的环境变量。
如果多个 Perforce VCS 根用于签出,则会为构建的 VCS 根列表中的 编码辅助 VCS 根创建变量:
P4USER— 与vcsroot.<VCS_root_ID>.user参数 相同。P4PORT— 与vcsroot.<VCS_root_ID>.port参数 相同。P4CLIENT— 与vcsroot。<VCS_root_ID>。p4client参数相同,这是在代理上生成的 P4 工作区的名称。
这些变量可用于在检出之后执行自定义 Perforce 命令。 例如,要能够访问 PerforceTest VCS 根的端口,请在项目或构建配置设置中定义 env.P4PORT=%vcsRoot.PerforceTest.port% 环境变量。
工作区删除
Perforce 工作区 是用户计算机上的一组文件,这些文件反映了仓库中部分文件的子集。 TeamCity 会在代理机器和 Perforce 服务器上自动创建工作区。 随着时间的推移,这些工作区可能会占用服务器/代理机器上相当多的资源,因此您可能需要定期清理它们。
- 默认删除机制
默认情况下,TeamCity 在以下情况下删除 代理 Perforce 工作区:
在版本设置提交后立即创建(为每个提交创建一个工作区)。
对于代理端签出时 — 当执行了 清理签出 操作时(在这种情况下,TeamCity 也会运行
p4 sync -f,详见 下方 详述)。在代理进程的背景中(在构建之间),当其检测到与当前代理关联的工作区不存在的工作区目录时。 一个 TeamCity 代理执行未使用的 检出目录 的清理(默认超时是 8 天,可以通过
system.teamcity.build.checkoutDir.expireHours系统属性 进行更改)。 当删除一个签出目录时,如果此目录与 Perforce 工作区关联,则该工作区也会被删除。 清理 Perforce 工作区的功能可以通过teamcity.perforce.workspace.cleanup=false设置进行禁用,无论是在buildAgent.properties文件中还是在服务器级别上作为根项目的 配置参数。
- Perforce 连接设置
在 Perforce 管理员访问连接设置中启用 自动删除 Perforce 工作区 选项,以自动清理 TeamCity 生成的、已停用 7 天或更长时间的工作区。 工作区会在定期的 数据清理中被移除。
影响拥有此连接的项目及其子项目中的所有构建配置。
无论 自动删除 Perforce 工作区 选项状态如何,服务器工作区都会被自动移除。
如果启用了相应的设置,由 TeamCity 云代理创建的工作区(以
TC_p4名称前缀开头)将被移除。 由裸机代理创建的工作区不受影响。在连接设置中输入凭据的用户必须具有 "admin" 权限。
您可以在云代理属性中 添加
teamcity.perforce.keepWorkspaces=true属性,以保留此代理的自动工作区并将其排除在定期清理之外。
- VCS 根设置
在 Perforce VCS 根设置中启用 自动删除 Perforce 工作区 选项,以在构建完成后自动清理 TeamCity 生成的工作区。
仅影响附加到此 VCS 根的构建配置。
删除裸机和云 TeamCity 代理上的代理工作区。
工作区会在构建完成后被移除,这会强制每次新构建进行干净检出。
如果启用了此 VCS 根选项,
teamcity.perforce.keepWorkspaces=true属性不会阻止代理工作区被移除。
- 手动删除工作区
点击配置 操作 菜单中的 删除 Perforce 工作区... 项以执行一次性清理。

此操作允许您清理代理和服务器工作区。
要清理服务器工作区,您需要输入 Perforce 流的路径。
清理代理工作区允许您设置非活动阈值(以天为单位)。 超过此限制的工作区将被移除。
Perforce Sync -f 和工作区重用
当使用 代理端签出(agent-side checkout)时,TeamCity 会创建一个绑定到代理上的检出目录的工作区。 执行签出操作是通过增量 p4 sync 命令进行的(适用于个人和非个人构建)。
当VCS根配置为使用 p4 sync -p 时,TeamCity总是运行此命令来检出源代码。
通常,每次 clean checkout 构建都会生成用于清理源代码的 p4 sync -f 命令。 对于 Perforce 代理检出,以下有所描述的例外情况。
签出过程中的错误
当检出过程中发生错误,或者构建在检出过程中被中断/停止,或者发生超时,同一构建代理上的后续构建将不会进行 clean checkout。 反而,TeamCity 将依赖于 Perforce 的能力从状态中恢复。
VCS 根客户端映射修改
通常,当项目管理员修改在 VCS 根中指定的 VCS 根客户端映射时,这被视为 VCS 根设置的改变,并导致一次 clean checkout。 这种清洁检出行为可以通过使用 teamcity.perforce.enable-no-clean-checkout=true 内部属性 来禁用。
更改 teamcity.perforce.enable-no-clean-checkout 内部属性会导致所有受影响的构建配置进行一次性清理签出。
当 VCS 根配置为使用客户端名称,或流,当在 Perforce 中编辑相应客户端 / 流的客户端映射时,将不会进行清理检出。
强制保护以防止清空检出
为了保护构建配置免受 TeamCity 发起的清理检出,您可以将 teamcity.agent.failBuildOnCleanCheckout 配置参数 设置为 true。 在这种情况下,TeamCity 将会把构建标记为失败,而不是运行一次清理检查。 除非通过 Enforce clean checkout操作明确请求,否则它永远不会清理工作区,或者在构建配置的版本控制设置的检出选项中启用了“ Delete all files in the checkout directory before the build ”选项。
当使用自定义检出路径时,TeamCity 在版本控制系统设置更改时不会清理检出目录 —— 相反,它会导致构建失败。 若要忽略清理检出并继续进行增量检出,可对项目或构建配置使用 teamcity.agent.failBuildOnCleanCheckout=ignoreAndContinue 参数。 仅在您完全确定签出目录中的源文件处于正确状态时,才进行此操作。
对于出现问题的个人构建,同样适用。 当源文件已损坏且设置了此选项时,TeamCity 会使构建失败,而不是执行一次全新的检出。 您可以通过 p4 clean 清理工作副本,然后尝试使用 ignoreAndContinue 值继续(运行具有指定的 配置参数 的自定义构建)。
在云代理上重复使用已签出的源代码
为了避免在每一个新的 TeamCity 云代理上进行清理检出,您可以将代码源的持久存储复制或挂载到代理检出目录中。 然而,由于 Perforce 跟踪工作区、代理 IP 地址和名称、存储在代理上的修订版以及其他数据,因此在新的云代理上运行构建会导致 p4 sync 操作忽略现有的源文件,并导致一个干净的检出。
为了防止这种情况发生并重用持久存储中的资源,请执行以下操作:
将
teamcity.agent.failBuildOnCleanCheckout=ignoreAndContinue参数添加到您的构建配置中,以明确地 禁用清理检出。要在检出开始之前对工作空间进行调整,请启用 Bootstrap steps。
向您的配置中添加一个或多个命令行或脚本步骤,并检查它们的 在引导期间运行 选项。 这些引导步骤应完成以下事项:
确保构建检出目录指向您的持久存储,并且此存储已在正确的修订版本上检出所有所需的源代码;
运行
p4 -c <p4_workspace_name> flush <changelist_revision>命令,告知 Perforce 服务器工作区已经拥有了所有所需的源代码;将自定义工作空间名称设置为所需值。 为了实现这个目标,发送 setParameter 服务消息 ,将新的值赋给
vcsroot。<VCSRootExternalID>。p4client属性。echo "##teamcity[setParameter name='vcsroot.P4_ExternalVCSRootID.p4client' value='customP4ClientName']"
在这些引导步骤到位后,TeamCity 将更新您的 P4 客户端规范,运行 p4 sync 命令并执行一次检出,这应该只获取清除的 <changelist_revision> 与当前构建相关联的修订之间的更改。