在TeamCity中如何取消同级依赖的快照关系

24次阅读
没有评论

问题描述

在使用TeamCity构建链时遇到了一个问题。他在构建链中有两个步骤:buildtest,并且有一个依赖于它们的步骤docker publish。他开启了”当依赖构建失败时取消构建”选项,这意味着如果buildtest失败,排队的docker publish步骤将被取消。然而,如果build失败,test步骤仍然会继续运行,反之亦然。用户希望能够在任何一个步骤失败时取消所有同级任务,或者如果一个依赖步骤被取消(例如docker publish),那么所有当前正在运行的该依赖步骤的子任务都会被停止。他在TeamCity的社区论坛上找到了一个类似的问题,但不确定链接的YouTrack问题是否真正解决了这个问题。

解决方案

请注意以下操作可能涉及到TeamCity API的使用,请确保您对其操作有足够的了解。

要实现在TeamCity中取消同级依赖的快照关系,您可以使用TeamCity API来实现这一功能。以下是一个解决方案的示例,这个示例中使用了一个bash脚本来完成操作。这个脚本被扩展了,以在构建脚本失败时触发相应的操作。

方案

  1. build.shtest.sh的构建脚本中,扩展失败函数,这是一个在构建脚本失败时调用的简单bash函数。
teamcityFailure () {
    . ./cancel_build_chain.sh
    echo "##teamcity[buildProblem description='$1']"
    exit 1
}
  1. 创建一个名为cancel_build_chain.sh的新脚本,用于处理取消操作。该脚本的逻辑如下:
#!/bin/bash
teamcityProgress () {
    echo "##teamcity[progressMessage '$1']"
}

teamcityProgress "Build step has failed, attempting to cancel the rest of the build chain..."

BUILD_ID=$TEAMCITY_BUILD_ID # 从构建链配置中传递的

# 使用当前失败步骤ID查询快照依赖关系
FINAL_STEP_DATA=$(curl --silent --request GET \
    "https://teamcity/app/rest/builds/project:MyProjectName,snapshotDependency:(from:(id:$BUILD_ID),includeInitial:true),defaultFilter:false" \
    --header "Content-Type: application/xml")

# 从最终的“docker publish”步骤中解析出所有依赖步骤ID。其中一个是当前步骤,其他的是其兄弟步骤
# 这一步骤需要进行两次,一次针对排队的步骤,一次针对当前运行的步骤。因为我们需要以不同的方式取消运行中和排队中的构建
QUEUED_DEPENDENT_STEP_IDS=$(echo $FINAL_STEP_DATA | grep -Eo '<snapshot-dependencies.+<build id="[0-9]+".+state="queued"' \
    | grep -Eo 'id="([0-9]+)"' | grep -Eo '[0-9]+')
QUEUED_DEPENDENT_STEP_IDS=${QUEUED_DEPENDENT_STEP_IDS/$BUILD_ID/}
QUEUED_DEPENDENT_STEP_IDS=${QUEUED_DEPENDENT_STEP_IDS/ /}

RUNNING_DEPENDENT_STEP_IDS=$(echo $FINAL_STEP_DATA | grep -Eo '<snapshot-dependencies.+<build id="[0-9]+".+state="running"' \
    | grep -Eo 'id="([0-9]+)"' | grep -Eo '[0-9]+')
RUNNING_DEPENDENT_STEP_IDS=${RUNNING_DEPENDENT_STEP_IDS/$BUILD_ID/}
RUNNING_DEPENDENT_STEP_IDS=${RUNNING_DEPENDENT_STEP_IDS/ /}

# 取消所有排队中的依赖步骤
for DEP_ID in $QUEUED_DEPENDENT_STEP_IDS
do
    teamcityProgress "Cancelling queued build step $DEP_ID"
    curl --silent --request POST \
        "https://teamcity/app/rest/buildQueue/project:MyProjectName,id:$DEP_ID" \
        --data "<buildCancelRequest comment='Another part of the build chain failed so this sibling step was cancelled.' readdIntoQueue='false' />" \
        --header "Content-Type: application/xml"
done

# 取消所有运行中的依赖步骤
for DEP_ID in $RUNNING_DEPENDENT_STEP_IDS
do
    teamcityProgress "Cancelling running build step $DEP_ID"
    curl --silent --request POST \
        "https://teamcity/app/rest/builds/project:MyProjectName,id:$DEP_ID" \
        --data "<buildCancelRequest comment='Another part of the build chain failed so this sibling step was cancelled.' readdIntoQueue='false' />" \
        --header "Content-Type: application/xml"
done

这个解决方案不太优雅,但能够实现目标,防止构建代理在已经失败的构建步骤上继续运行。根据实际需要,您可以根据此示例进一步优化或适应您的环境。

总结

在TeamCity中,通过使用TeamCity API,您可以编写脚本来在构建步骤失败时取消同级依赖的快照关系。这个解决方案允许您在一个依赖步骤被取消时,停止所有当前正在运行的该依赖步骤的子任务,以确保构建链的正确性。希望这个解决方案能够帮助您解决您的问题。

如果您想了解更多有关TeamCity的定制和扩展的信息,可以参考TeamCity的官方文档和社区论坛。

正文完