从Jenkins的管道中止当前构建

tml*_*lye 45 jenkins jenkins-pipeline

我有一个Jenkins管道,它有多个阶段,例如:

node("nodename") {
  stage("Checkout") {
    git ....
  }
  stage("Check Preconditions") {
    ...
    if(!continueBuild) {
      // What do I put here? currentBuild.xxx ?
    }
  }
  stage("Do a lot of work") {
    ....
  }
}
Run Code Online (Sandbox Code Playgroud)

如果不满足某些先决条件并且没有实际工作要做,我希望能够取消(而不是失败)构建.我怎样才能做到这一点?我知道currentBuild变量可用,但我找不到它的文档.

Chr*_*Orr 85

您可以将构建标记为ABORTED,然后使用该error步骤使构建停止:

if (!continueBuild) {
    currentBuild.result = 'ABORTED'
    error('Stopping early…')
}
Run Code Online (Sandbox Code Playgroud)

在舞台视图中,这将显示构建在此阶段停止,但整体构建将被标记为已中止,而不是失败(请参阅构建#9的灰色图标):

管道舞台视图

  • 大。有没有办法早日成功退出? (5认同)
  • 不好意思,已经找到了。只需在“节点级别”而不是“阶段级别”上返回即可使管道成功提前退出。 (3认同)

CSc*_*ulz 12

经过一些测试,我想出了以下解决方案:

def autoCancelled = false

try {
  stage('checkout') {
    ...
    if (your condition) {
      autoCancelled = true
      error('Aborting the build to prevent a loop.')
    }
  }
} catch (e) {
  if (autoCancelled) {
    currentBuild.result = 'ABORTED'
    echo('Skipping mail notification')
    // return here instead of throwing error to keep the build "green"
    return
  }
  // normal error handling
  throw e
}
Run Code Online (Sandbox Code Playgroud)

这将导致进入以下阶段视图:

在此处输入图片说明

失败的阶段

如果您不喜欢失败的阶段,则必须使用return。但是请注意,您必须跳过每个阶段或包装器。

def autoCancelled = false

try {
  stage('checkout') {
    ...
    if (your condition) {
      autoCancelled = true
      return
    }
  }
  if (autoCancelled) {
    error('Aborting the build to prevent a loop.')
    // return would be also possible but you have to be sure to quit all stages and wrapper properly
    // return
  }
} catch (e) {
  if (autoCancelled) {
    currentBuild.result = 'ABORTED'
    echo('Skipping mail notification')
    // return here instead of throwing error to keep the build "green"
    return
  }
  // normal error handling
  throw e
}
Run Code Online (Sandbox Code Playgroud)

结果:

在此处输入图片说明

自定义错误作为指标

您还可以使用自定义消息代替局部变量:

final autoCancelledError = 'autoCancelled'

try {
  stage('checkout') {
    ...
    if (your condition) {
      echo('Aborting the build to prevent a loop.')
      error(autoCancelledError)
    }
  }
} catch (e) {
  if (e.message == autoCancelledError) {
    currentBuild.result = 'ABORTED'
    echo('Skipping mail notification')
    // return here instead of throwing error to keep the build "green"
    return
  }
  // normal error handling
  throw e
}
Run Code Online (Sandbox Code Playgroud)