You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jenkins流水线如何配置Stage任意环节失败仍继续执行作业

问题说明

现有Jenkins声明式流水线Infracost阶段配置如下:

stage('Infracost'){
  agent {
    docker {
        image 'infracost/infracost:ci-latest'
        args "--user=jenkins --entrypoint=''"
        alwaysPull true
        reuseNode true
    }
  }
  environment {
      INFRACOST_API_KEY = credentials('INFRACOST_API_KEY')
      USAGE_FILE = '/tmp/infracost-usage.yml'
      SYNC_USAGE_FILE = true          
  }
  steps {
    dir('./services/' + serviceType + '/terraform'){
      sh script:'infracost breakdown --path .', label: "Infracost output"
      sh script:'infracost diff --path plan.json', label: "Infracost diff"
    }
  }
}

需求为该阶段任意环节(包括Docker镜像拉取、容器启动等agent准备环节,以及steps内脚本执行环节)失败时,整个流水线不终止,继续执行后续阶段。此前在steps块内使用catchError仅能覆盖steps内的脚本异常,Docker agent相关故障依然会导致流水线直接失败。

原因说明

声明式流水线的stage执行顺序为:分配/启动agent -> 执行stage内部的options、steps、post等逻辑。stage级别的docker agent准备工作(拉镜像、启容器、挂载工作区)属于前置环节,早于steps块执行,因此steps内部的catchError根本无法捕获agent阶段抛出的异常,自然无法阻止流水线终止。

可行方案

方案一(推荐,与原配置行为完全一致)

将Docker agent逻辑从stage的agent块下沉到steps内部,通过脚本式Docker调用执行任务,让镜像拉取、容器启动、命令执行全流程都处于catchError的捕获范围内。由于原配置已经开启reuseNode true,本身就是复用当前工作节点启动容器,不存在额外节点调度,调整后行为和原配置无差异。
调整后配置如下:

stage('Infracost'){
  // 直接复用上层流水线分配的工作节点,和原reuseNode true效果一致
  agent any
  environment {
      INFRACOST_API_KEY = credentials('INFRACOST_API_KEY')
      USAGE_FILE = '/tmp/infracost-usage.yml'
      SYNC_USAGE_FILE = true          
  }
  steps {
    // 全链路捕获异常,覆盖从镜像拉取到命令执行的所有环节
    catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE', message: 'Infracost阶段执行失败,流水线继续运行') {
      dir('./services/' + serviceType + '/terraform'){
        // 对应原配置alwaysPull true,每次执行拉取最新镜像
        docker.image('infracost/infracost:ci-latest').pull()
        // 传入原配置的docker启动参数,在容器内执行原有命令
        docker.image('infracost/infracost:ci-latest').inside("--user=jenkins --entrypoint=''") {
          sh script:'infracost breakdown --path .', label: "Infracost output"
          sh script:'infracost diff --path plan.json', label: "Infracost diff"
        }
      }
    }
  }
}

配置说明:

  • buildResult: 'UNSTABLE'表示该阶段失败时,仅将整个构建标记为不稳定(黄色告警状态),不会中断流水线执行;如果不需要保留失败标记,也可以设置为SUCCESS,但不推荐,会丢失故障排查记录。
  • 不要使用stage options内置的catchError,该配置依然无法覆盖agent准备阶段的异常。

方案二(保留原stage结构,外层嵌套捕获)

如果不想改动原有Infracost stage的配置结构,可以在外层套一个使用基础常驻agent的父stage,在父stage的steps中用catchError包裹整个原有Infracost stage,这样子stage所有环节(包括agent启动)的异常都会被外层捕获。
配置示例:

stage('Infracost-Ignore-Failure') {
  // 使用常驻可用的基础agent,不存在docker启动类异常
  agent any
  steps {
    catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE', message: 'Infracost阶段执行失败,流水线继续运行') {
      // 原有Infracost stage完整放在此处,所有异常都会被外层捕获
      stage('Infracost'){
        agent {
          docker {
              image 'infracost/infracost:ci-latest'
              args "--user=jenkins --entrypoint=''"
              alwaysPull true
              reuseNode true
          }
        }
        environment {
            INFRACOST_API_KEY = credentials('INFRACOST_API_KEY')
            USAGE_FILE = '/tmp/infracost-usage.yml'
            SYNC_USAGE_FILE = true          
        }
        steps {
          dir('./services/' + serviceType + '/terraform'){
            sh script:'infracost breakdown --path .', label: "Infracost output"
            sh script:'infracost diff --path plan.json', label: "Infracost diff"
          }
        }
      }
    }
  }
}

内容的提问来源于stack exchange,提问作者fraserc182

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 21:21:32