在 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%
环境变量。
工作区删除
在构建代理上删除工作空间
在以下情况下,TeamCity 会删除 Perforce 工作空间:
在版本设置提交后立即创建(为每个提交创建一个工作区)。
对于代理端签出时 — 当执行了 清理签出 操作时(在这种情况下,TeamCity 也会运行
p4 sync -f
,详见 下方 详述)。在代理进程的背景中(在构建之间),当其检测到与当前代理关联的工作区不存在的工作区目录时。 一个 TeamCity 代理执行未使用的 检出目录 的清理(默认超时是 8 天,可以通过
system.teamcity.build.checkoutDir.expireHours
系统属性 进行更改)。 当删除一个签出目录时,如果此目录与 Perforce 工作区关联,则该工作区也会被删除。 清理 Perforce 工作区的功能可以通过teamcity.perforce.workspace.cleanup=false
设置进行禁用,无论是在buildAgent.properties
文件中还是在服务器级别上作为根项目的 配置参数。
当删除包含有待处理更改或已打开文件的 Perforce 工作区时,TeamCity 会试图撤销这些更改并移除待处理的更改列表,然后重复该操作。 如果第二次尝试也失败,TeamCity 将试图运行 p4 client -d -f
操作(强制)。 所有这些操作都被记录在 teamcity-vcs.log
中。
TeamCity 在使用 Perforce 边缘 / 复制服务器时,不会强制删除工作区。
在 Perforce 服务器上清理工作空间
如果您在 Perforce VCS 根中启用了 功能分支支持,那么 TeamCity 将开始处理您的 Perforce 任务流。 为了正确完成此操作,需要在 Perforce 服务器上创建专用工作区。 随着时间的推移,这些工作空间可能会消耗这台服务器机器的大量资源。 您可以直接从 TeamCity 用户界面清理不再需要的工作区。
为了直接连接到您的 Perforce 服务器,请转到 TeamCity 的 Project Settings | Connections,并添加一个 Perforce 管理员访问 连接。 在其设置中,输入访问 Perforce 服务器所需的主机和用户凭证(用户必须具有 admin
权限),然后 TeamCity 将会连接到它。
在每次 清理 过程中,TeamCity 将会检测并删除超过 7 天未活动的工作区。 您也可以随时在连接设置中点击 Delete workspaces 以删除它们。 请注意,工作空间只在服务器上删除 —— 不在构建代理上删除 —— 并且只有在 TeamCity 创建的情况下才会删除。
也可以只删除与特定流相关联的工作区。 为了实现这一点,请转到 构建配置首页,打开操作菜单,然后单击删除 Perforce 流工作空间。 默认情况下,所有拥有项目开发者角色的用户都可以使用此操作。
在打开的对话框中,指定一个到流的路径,TeamCity 将在 Perforce 服务器上删除相关的工作空间。 要连接到服务器,TeamCity 将使用项目的 Perforce 管理员访问连接的设置。 如果不可用,它将使用 Perforce VCS root 的设置代替。
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 发起的清理检出,您可以将 配置参数 设置为 true
。 在这种情况下,TeamCity 将会把构建标记为失败,而不是运行一次清理检查。 除非通过 强制清理检出 动作明确请求,或者在构建配置的版本控制设置的检出选项中启用了 "构建前清理检出目录中的所有文件" 选项,否则它永远不会清理工作区。
当使用自定义检出路径时,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>
与当前构建相关联的修订之间的更改。