如何确保在运行Jenkins管道之前更新参数列表?

izkcnapc  于 2023-03-22  发布在  Jenkins
关注(0)|答案(6)|浏览(277)

Jenkins管道项目被配置为从Git repo中获取其Jenkinsfile

如果我更改参数列表,例如,从:

properties([
        parameters([
                string(name: 'FOO', description: 'Choose foo')
        ])
])

致:

properties([
        parameters([
                string(name: 'FOO', description: 'Choose foo'),
                string(name: 'BAR', description: 'Choose bar')
        ])
])

并运行构建,第一次运行时不显示新添加的BAR参数:

由于更新后的Jenkins文件期望存在BAR参数,这会导致更改后的第一次构建失败,因为用户没有输入该值。
有什么方法可以防止这种情况吗?在显示参数输入页面之前确保Jenkinsfile是最新的?

c9x0cxw0

c9x0cxw01#

简短回答:没有。如果有一些工具可以解析和处理Jenkinsfile,与构建分开,那就太好了,但是没有。
Jenkins在检索、解析和运行Jenkinsfile之前并不知道新参数,唯一的方法就是...运行构建。
实际上,构建历史将始终“落后于”Jenkinsfile;当你改变Jenkinsfile中的某些东西时,下一个构建将使用“旧的”Jenkinsfile运行,但是在那之后为构建选择和处理新的Jenkinsfile。

zf2sa74q

zf2sa74q2#

解决这个问题的唯一方法是手动添加一个“skip_run”布尔参数,然后在作业的每个阶段添加一个when{}子句。

properties([
        parameters([
                BooleanParameter(name: 'skip_run', description: 'Skips all stages. Used to update parameters in case of changes.', default: False)
        ])
    ])

...

stage('Doing Stuff') {
        when {
            expression { return params.skip_run ==~ /(?i)(N|NO|F|FALSE|OFF|STOP)/ }
        }
        steps {
            ...
        }
    }

当然,这很容易出错。
或者,您可以添加一个阶段作为管道的开始,并故意使构建失败。

stage('Update Build Info only') {
        when {
            expression { return params.skip_run ==~ /(?i)(Y|YES|T|TRUE|ON|RUN)/ }
        }
        steps {
            error("This was done deliberately to update the build info.")
        }
    }

更新:感谢Abort current build from pipeline in Jenkins,我想出了这个解决方案:

为了防止构建实际上显示为红色,您可以使用try - catch Package 此构建并优雅地退出构建。

final updateOnly = 'updateOnly'     
try {
      stage('Update Build Info only') {
            when {
                expression { return params.skip_run ==~ /(?i)(Y|YES|T|TRUE|ON|RUN)/ }
            }
            steps {
                error(updateOnly)
            }
        }
...
//other stages here
...
    } catch (e) {
      if (e.message == updateOnly) {
        currentBuild.result = 'ABORTED'
        echo('Skipping the Job to update the build info')
        // return here instead of throwing error to keep the build "green"
        return
      }
      // normal error handling
      throw e
    }
wz8daaqr

wz8daaqr3#

我有一个函数,除非作业具有所有必需的参数,否则会跳过构建,例如:

if (job.hasParameters(['FOO', 'BAR'])) {
    // pipeline code
}
wr98u20j

wr98u20j4#

几年前在Jenkins中报告了一个与此问题https://issues.jenkins-ci.org/browse/JENKINS-41929相关的问题
还在开着所以还没有好的解决办法

41ik7eoe

41ik7eoe5#

以下方法的思想是定义一次默认值,并且如果参数还不存在,则不会使管道失败-这是第一次运行时的情况。

  • 定义管道上方的默认值。
  • 在参数定义中使用它
  • 重写环境部分中的参数,并在整个管道中使用环境变量

示例:

NEW_PARAM_DEFAULT = 'the default value'

pipeline {

  parameters {
    string(
        name: 'NEW_PARAM',
        description: 'Safely introduce a new parameter without a failure on the first run.',
        defaultValue: NEW_PARAM_DEFAULT)
  }
  
  environment {
     NEW_PARAM_VALUE = params.getOrDefault('NEW_PARAM', NEW_PARAM_DEFAULT)
     // safely use NEW_PARAM_VALUE everywhere
  }

  stages {
    ...
  }
}
0lvr5msh

0lvr5msh6#

试试..

parameters {
        string(name: 'GRADLE_ARGS', defaultValue: '--console=plain', description: 'Gradle arguments')
    }

    environment{
        GRADLE_ARGS = "${params.GRADLE_ARGS}"
    }

相关问题