26

我遇到了问题Teamcity,即使之前的步骤不成功,它也会继续运行构建步骤。

我的构建配置的最后一步是部署我的站点,如果我的任何测试失败,我不希望它这样做。

每个构建步骤都设置为仅在所有先前步骤都成功时才执行。

在 Build Failure Conditions 选项卡中,我检查了 Fail build if 下的以下选项:

-build process exit code is not zero
-at least one test failed
-an out-of-memory or crash is detected (Java only)

这不起作用 - 即使测试失败 TeamCity 部署我的站点,为什么?

我什至尝试添加一个额外的构建失败条件,它将在构建日志中查找特定文本(即“测试运行失败”。)

在概览页面中查看已完成的测试时,您可以看到针对最新版本的错误消息:

“试运行失败。” 文本出现在构建日志中

但无论如何它仍然会部署它。

有谁知道如何解决这一问题?看来这个问题已经运行了很长时间,here

显然有一个解决方法:

到目前为止,我们并不认为此功能非常重要,因为有一个明显的解决方法:脚本可以检查必要的条件,并且不会生成 TeamCity 中配置的工件。

例如,脚本可以将工件从临时目录移动到 TeamCity 中指定的目录,作为在完成之前发布的工件,以防构建操作成功。

但这对我来说并不清楚如何做到这一点,而且听起来也不是最好的解决方案。任何帮助表示赞赏。

编辑:我还能够解决快照依赖项的问题,在那里我将有一个单独的“部署”构建,它依赖于测试构建,现在如果测试失败,它就不会运行。

对于设置依赖关系很有用。

4

5 回答 5

27

这是 TeamCity 7.1 中的一个已知问题(参见http://youtrack.jetbrains.com/issue/TW-17002),该问题已在 TeamCity 8.x+ 中得到修复(请参阅此答案)。

TeamCity 区分失败的构建和失败的构建步骤。虽然失败的单元测试会使整个构建失败,但不幸的是,TeamCity 仍然认为测试步骤本身是成功的,因为它没有返回非零错误代码。因此,后续步骤将继续运行。

已经提出了各种解决方法,但我发现它们要么需要不平凡的设置,要么会影响 TeamCity 的测试体验。

但是,在查看了来自 @arex1337 的建议后,我们找到了一种让 TeamCity 做我们想做的事情的简单方法。只需在包含以下内联脚本的现有测试步骤之后添加一个额外的 Powershell 构建步骤(替换YOUR_TEAMCITY_HOSTNAME为您的实际 TeamCity 主机/域):

$request = [System.Net.WebRequest]::Create("http://YOUR_TEAMCITY_HOSTNAME/guestAuth/app/rest/builds/%teamcity.build.id%")
$xml = [xml](new-object System.IO.StreamReader $request.GetResponse().GetResponseStream()).ReadToEnd()
Microsoft.PowerShell.Utility\Select-Xml $xml -XPath "/build" | % { $status = $_.Node.status }

if ($status -eq "FAILURE") {
    throw "Failing this step because the build itself is considered failed. This is our way to workaround the fact that TeamCity incorrectly considers a test step to be successful even if there are test failures. See http://youtrack.jetbrains.com/issue/TW-17002"
}

这个内联 PowerShell 脚本只是使用 TeamCity REST API 来询问构建本身是否作为一个整体被认为是失败的(%teamcity.build.id%"当执行该步骤时,该变量将被 TeamCity 替换为实际的构建 ID)。如果整个构建被视为失败(例如,由于测试失败),则此 PowerShell 脚本会引发错误,导致进程返回非零错误代码,从而导致单个构建步骤本身被视为不成功. 此时,可以阻止后续步骤运行。

请注意,此脚本使用 guestAuth,这需要启用 TeamCity 来宾帐户。或者,您可以改用 httpAuth,但您需要更新脚本以包含 TeamCity 用户名和密码(例如http://USERNAME:PASSWORD@YOUR_TEAMCITY_HOSTNAME/httpAuth/app/rest/builds/%teamcity.build.id%)。

因此,有了这个附加步骤,如果有任何先前的单元测试失败,将跳过所有设置为执行“仅当所有先前的步骤都成功”的后续步骤。如果在 JetBrains 解决问题之前我们的任何 NUnit 测试都不成功,我们将使用它来阻止自动部署。

感谢@arex1337 的想法。

于 2013-03-13T16:29:54.290 回答
24

只是为了防止混淆,这个问题在 Team City v8.x 中得到了修复,我们现在不需要那些变通方法。

您可以通过执行步骤选项指定步骤执行策略:

仅当构建状态成功- 在开始步骤之前,构建代理向服务器请求构建状态,如果状态失败则跳过该步骤。

https://confluence.jetbrains.com/display/TCD8/Configuring+Build+Steps

当然,如果至少有一个单元测试失败,您需要使构建失败:

https://confluence.jetbrains.com/display/TCD8/Build+Failure+Conditions

在“构建失败条件”页面的“如果构建失败”区域,指定 TeamCity 构建失败的时间:

至少一项测试失败:如果构建失败至少一项测试,请选中此选项以将构建标记为失败。

于 2014-10-20T10:40:43.050 回答
3

这是(正如您所发现的)TeamCity 的一个已知问题,在他们的问题跟踪器中有一组链接问题。这个问题有望在 TeamCity 的下一个版本(8.x 版)中得到解决

同时,我们确定解决问题的方法(对于版本 6.5.5)是下载测试结果文件作为后续步骤的一部分。然后对其进行解析以检查任何测试失败,返回错误代码并因此正确地破坏构建(执行我们需要的任何清理作为该失败的一部分),这可能对您有用。

于 2013-03-07T13:46:11.767 回答
1

TeamCity 构建失败并不意味着它将停止构建,并且如果您的构建提供了 TeamCity 要求的构建输出文件,它将发布工件。它只会正确更新构建状态。

但是,您可以很好地通过修改构建脚本来停止构建过程,以在测试用例失败时停止构建。如果您使用的是 MSBuild,那么ContinueOnError="false"会这样做。

于 2013-03-06T19:52:33.177 回答
0

最后,我能够通过快照依赖关系解决问题,我将有一个单独的“部署”构建,它依赖于测试构建,现在如果测试失败,它就不会运行。

对于设置依赖关系很有用。

于 2013-03-08T10:24:19.710 回答