我正在尝试使用jobDSL插入中的pipelineJob函数生成Jenkins管道,但是无法将参数从DSL传递到管道脚本。我有几个项目使用的本质上是相同的Jenkinsfile,只有几个步骤之间存在差异。我正在尝试使用JobDSL插件动态生成这些管道,将要更改的值解释为与DSL匹配的参数。
我已经尝试了在管道脚本和DSL中可以使用的字符串解释的每种组合,但是无法让Jenkins / groovy来解释管道脚本中的变量。
我正在管道步骤中调用作业DSL:
def projectName = "myProject"
def envs = ['DEV','QA','UAT']
def repositoryURL = 'myrepo.com'
jobDsl targets: ['jobs/*.groovy'].join('\n'),
additionalParameters: [
project: projectName,
environments: envs,
repository: repositoryURL
],
removedJobAction: 'DELETE',
removedViewAction: 'DELETE'
DSL如下:
pipelineJob("${project} pipeline") {
displayName('Pipeline')
definition {
cps {
script(readFileFromWorkspace(pipeline.groovy))
}
}
}
pipeline.groovy:
pipeline {
agent any
environment {
REPO = repository
}
parameters {
choice name: "ENVIRONMENT", choices: environments
}
stages {
stage('Deploy') {
steps {
echo "Deploying ${env.REPO} to ${params.ENVIRONMENT}..."
}
}
}
}
我在AdditionalParameters中传递的变量在jobDSL脚本中解释;具有正确名称的管道会生成。问题在于变量没有传递到从工作空间读取的管道脚本中-生成的管道的Jenkins配置看起来与文件完全相同,而对变量没有任何解释。
我已经做了很多尝试来解释字符串,包括“ $ {environments}”,$ {environments},$ environments,\ $ environments的许多变体...我找不到任何工作。我也尝试过将文件读取为gstringImpl:
script("${readFileFromWorkspace(pipeline.groovy)}")
有人对我如何使变量传播到管道脚本有任何想法吗?我知道我可以只使用一个for循环对脚本文本执行string.replaceAll(),但这似乎很麻烦;一定有更好的方法。
答案 0 :(得分:1)
您需要使用完整的作业名称作为不带引号的变量。例如,如果 JOBNAME 是包含整个作业名称的参数:
pipelineJob(JOBNAME) {
displayName('Pipeline')
definition {
cps {
script(readFileFromWorkspace(pipeline.groovy))
}
}
}
答案 1 :(得分:0)
我想出了一种方法来完成这项工作。这不是我想要的,而是在作业创建过程中隐式解释了文件的字符串内容,但是它确实有效。它只是增加了一个额外的步骤。
import groovy.text.SimpleTemplateEngine
def fileContents = readFileFromWorkspace "pipeline.groovy"
def engine = new SimpleTemplateEngine()
template = engine.createTemplate(fileContents).make(binding.getVariables()).toString()
pipelineJob("${project} pipeline") {
displayName('Pipeline')
definition {
cps {
script(template)
}
}
}
这将从工作空间中读取文件,然后将其用作具有绑定变量的模板。进行此工作所需的其他更改是转义Jenkinsfile脚本中使用的任何变量,例如\${VARIABLE}
,以便在运行时而不是在构建作业时对其进行扩展。您要在创建工作时要扩展的任何变量都应引用为${VARIABLE}
。
答案 2 :(得分:0)
您可以通过在pipelineJob中定义环境变量,然后在管道中使用这些变量来实现您想要的目的。
由于环境变量是字符串,所以它们有一定的局限性,但是它应该适用于基本内容
例如:
//job-dsl
pipelineJob('example') {
environmentVariables {
// these vars could be specified by parameters of this job
env('repository', 'blah')
env('environments', "a,b,c"]) //comma separated string
}
displayName('Pipeline')
definition {
cps {
script(readFileFromWorkspace(pipeline.groovy))
}
}
}
}
然后在管道中:
//pipeline.groovy
pipeline {
agent any
environment {
REPO = env.repository
}
parameters {
choice name: "ENVIRONMENT", choices: env.environments.split(',')
//note the need to split the comma separated string above
}
}