Jenkins声明式流水线调用自定义codeLint方法无执行结果求助
问题描述
我有一个用于多环境代码扫描的Jenkins声明式流水线,会根据传入的参数调用自定义codeLint方法。但构建过程中,调用该方法的Stage无任何执行内容,也无返回结果。已确认在控制台执行「Build with Parameters」时勾选了所需参数,且代码语法符合声明式流水线规范。
Jenkinsfile代码
IAMMap = [ "west": [ account: "XXXXXXXX", ], "east": [ account: "YYYYYYYYY", ], ] pipeline { options { ansiColor('xterm') } parameters { booleanParam( name: 'WEST', description: 'Whether to lint code from west account or not. Defaults to "false"', defaultValue: false ) booleanParam( name: 'EAST', description: 'Whether to lint code from east account or not. Defaults to "false"', defaultValue: true ) booleanParam( name: 'LINT', description: 'Whether to perform linting. This should always default to "true"', defaultValue: true ) } environment { CODE_DIR = "/code" } stages { stage('Start Lint') { steps { script { if (params.WEST && params.LINT) { codeLint("west") } if (params.EAST && params.LINT) { codeLint("east") } } } } } post { always { cleanWs disableDeferredWipeout: true, deleteDirs: true } } } def codeLint(account) { return { stage('Code Lint') { dir(env.CODE_DIR) { withAWS(IAMMap[account]) { sh script: "./lint.sh" } } } } }
执行结果日志
15:00:20 [Pipeline] { (Start Lint) 15:00:20 [Pipeline] script 15:00:20 [Pipeline] { 15:00:20 [Pipeline] } 15:00:20 [Pipeline] // script 15:00:20 [Pipeline] } 15:00:20 [Pipeline] // stage 15:00:20 [Pipeline] stage 15:00:20 [Pipeline] { (Declarative: Post Actions) 15:00:20 [Pipeline] cleanWs 15:00:20 [WS-CLEANUP] Deleting project workspace... 15:00:20 [WS-CLEANUP] Deferred wipeout is disabled by the job configuration... 15:00:20 [WS-CLEANUP] done
问题原因
你的codeLint方法返回的是一个闭包(Closure),但在script块中调用codeLint("west")或codeLint("east")时,只是获取了这个闭包对象,并没有实际执行它。这就是为什么流水线跳过了代码扫描步骤,直接进入了后置动作。
修复方案
有两种简单的修复方式:
方式一:执行返回的闭包
在调用codeLint方法时,通过.call()或者直接加()来执行闭包:
script { if (params.WEST && params.LINT) { codeLint("west").call() // 或者 codeLint("west")() } if (params.EAST && params.LINT) { codeLint("east").call() // 或者 codeLint("east")() } }
方式二:修改codeLint方法为直接执行步骤
把codeLint改成普通方法,直接执行流水线步骤,而不是返回闭包:
def codeLint(account) { stage('Code Lint') { dir(env.CODE_DIR) { withAWS(IAMMap[account]) { sh script: "./lint.sh" } } } }
这样原有的调用方式codeLint("west")就能直接执行对应的步骤了。
额外提示
如果需要为不同环境的扫描阶段设置不同的名称(比如区分West和East的扫描),可以修改stage的名称:
def codeLint(account) { stage("Code Lint - ${account.toUpperCase()}") { dir(env.CODE_DIR) { withAWS(IAMMap[account]) { sh script: "./lint.sh" } } } }
这样流水线日志里会显示Code Lint - WEST和Code Lint - EAST两个独立的阶段,更便于区分执行情况。
内容的提问来源于stack exchange,提问作者user19998543
相关产品推荐
相关产品推荐

