如何访问参数化版本中的参数?


73

您如何访问parameters“工作流程” Jenkins作业的“此构建已参数化”部分中的设置?

测试用例

  1. 创建一个工作流作业。
  2. 启用“此构建已参数化”。
  3. 添加foo具有默认值的STRING PARAMETER bar text
  4. 将以下代码添加到Workflow Script

    node()
    {
         print "DEBUG: parameter foo = ${env.foo}"
    }
    
  5. 运行工作。

结果

DEBUG: parameter foo = null


2
另一个误解(在#jenkins:transcript中自动劫持)是您应该使用$foo,如中所述if ($PARAM == 'true') {…}。那只是Groovy中的变量标识符。$只是某些字符串中的元字符。
Jesse Glick 2015年

要修改Jenkins参数,请尝试使用EnvInject插件。这是一个示例:stackoverflow.com/a/7067223/658497
Noam Manos

Answers:


90

我认为使用Workflow插件时,该变量直接可用,而不是通过env。尝试:

node()
{
    print "DEBUG: parameter foo = ${foo}"
}

2
正确的,因为解释在这里
杰西·格里克

但要使其可用于外壳的任务,我似乎已经分配到“ENV” -这感觉奇怪......比如:env.PARAM =参数
DOMI

2
不,我错了-我使用的是sh'''echo X'''而不是sh“”“ echo X”“”
domi

6
确保使用双引号而不是单引号。后者将跳过插值。
Henrique Gontijo

确保您不使用“ env”作为参数之一,因为它是保留关键字,并且不起作用
Yeikel

64

我尝试了该线程的一些解决方案。它似乎有效,但是我的价值观始终是正确的,而且我还遇到以下问题: JENKINS-40235

我设法使用jenkinsfile以下语法在groovy中使用参数:params.myVariable

这是一个工作示例:

print 'DEBUG: parameter isFoo = ' + params.isFoo
print "DEBUG: parameter isFoo = ${params.isFoo}"

更详细(且有效)的示例:

node() {
   // adds job parameters within jenkinsfile
   properties([
     parameters([
       booleanParam(
         defaultValue: false,
         description: 'isFoo should be false',
         name: 'isFoo'
       ),
       booleanParam(
         defaultValue: true,
         description: 'isBar should be true',
         name: 'isBar'
       ),
     ])
   ])

   // test the false value
   print 'DEBUG: parameter isFoo = ' + params.isFoo
   print "DEBUG: parameter isFoo = ${params.isFoo}"
   sh "echo sh isFoo is ${params.isFoo}"
   if (params.isFoo) { print "THIS SHOULD NOT DISPLAY" }

   // test the true value
   print 'DEBUG: parameter isBar = ' + params.isBar
   print "DEBUG: parameter isBar = ${params.isBar}"
   sh "echo sh isBar is ${params.isBar}"
   if (params.isBar) { print "this should display" }
}

输出量

[Pipeline] {
[Pipeline] properties
WARNING: The properties step will remove all JobPropertys currently configured in this job, either from the UI or from an earlier properties step.
This includes configuration for discarding old builds, parameters, concurrent builds and build triggers.
WARNING: Removing existing job property 'This project is parameterized'
WARNING: Removing existing job property 'Build triggers'
[Pipeline] echo
DEBUG: parameter isFoo = false
[Pipeline] echo
DEBUG: parameter isFoo = false
[Pipeline] sh
[wegotrade-test-job] Running shell script
+ echo sh isFoo is false
sh isFoo is false
[Pipeline] echo
DEBUG: parameter isBar = true
[Pipeline] echo
DEBUG: parameter isBar = true
[Pipeline] sh
[wegotrade-test-job] Running shell script
+ echo sh isBar is true
sh isBar is true
[Pipeline] echo
this should display
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

我发送了一个“拉取请求”以更新误导性管道tutorial#build-parameters的报价,该报价说:“它们可以作为具有相同名称的Groovy变量来访问。” 。;)

编辑:正如杰西·格里克(Jesse Glick)指出的那样: 发行说明进入更多细节

您还应该将Pipeline Job Plugin更新到2.7或更高版本,以便将构建参数定义为环境变量,从而可以像全局Groovy变量一样对其进行访问。


4
参数将继续可用,而不会params像以前一样(作为扁平字符串,不支持默认值)。从技术上讲,它们现在是环境变量,尽管您仍然可以使用裸表达式来引用它们的值,因为env.前缀对于访问也是可选的。发行说明会更详细。
Jesse Glick

1
这确实帮助我解决了我的问题:stackoverflow.com/questions/42115868/…非常感谢。
巴斯蒂

任何线索我可以如何进行:stackoverflow.com/questions/42277315/…
巴斯蒂

1
@Basti:Jon S的答案恰好在您的Q / A中,您properties只能调用一次或每次重写所有参数。
GabLeRoux

4
The properties section has been renamed as of version 0.8. Use options instead.这不再起作用
Carmageddon '18

16

当您添加一个构建参数foo时,它将被转换为类似于“裸变量”的行为,因此在脚本中您将执行以下操作:

node {
   echo foo
}

如果查看工作流程脚本的实现,您将看到执行脚本时会动态生成一个名为WorkflowScript的类。脚本中的所有语句都在此类的上下文中执行。传递给该脚本的所有构建参数都将转换为可从此类访问的属性。

例如,您可以执行以下操作:

node {
    getProperty("foo")
}

如果您感到好奇,这是我编写的工作流脚本,它试图在WorkflowScript类上打印出构建参数,环境变量和方法。

node {
   echo "I am a "+getClass().getName()

   echo "PARAMETERS"
   echo "=========="
   echo getBinding().getVariables().getClass().getName()
   def myvariables = getBinding().getVariables()
   for (v in myvariables) {
       echo "${v} " + myvariables.get(v)
   }
   echo STRING_PARAM1.getClass().getName()

   echo "METHODS"
   echo "======="
   def methods = getMetaClass().getMethods()

   for (method in methods) {
       echo method.getName()    
   } 

   echo "PROPERTIES"
   echo "=========="
   properties.each{ k, v -> 
       println "${k} ${v}" 
   }
   echo properties
   echo properties["class"].getName()

   echo "ENVIRONMENT VARIABLES"
   echo "======================"
   echo "env is " + env.getClass().getName()
   def envvars = env.getEnvironment()
   envvars.each{ k, v ->
        println "${k} ${v}"
   }
}

这是我尝试的另一个代码示例,在这里我想测试一下是否设置了构建参数。

node {
   groovy.lang.Binding myBinding = getBinding()
   boolean mybool = myBinding.hasVariable("STRING_PARAM1")
   echo mybool.toString()
   if (mybool) {
       echo STRING_PARAM1
       echo getProperty("STRING_PARAM1")
   } else {
       echo "STRING_PARAM1 is not defined"
   }

   mybool = myBinding.hasVariable("DID_NOT_DEFINE_THIS")
   if (mybool) {
       echo DID_NOT_DEFINE_THIS
       echo getProperty("DID_NOT_DEFINE_THIS")
   } else {
       echo "DID_NOT_DEFINE_THIS is not defined"
   }
}

1
对我来说,这产生了:org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException:不允许脚本使用方法java.lang.Class getName
Thomas Hirsch

8

在参数变量中添加前缀“ params”。例如:

params.myParam

别忘了:如果您使用myParam的某些方法,也许应该在“脚本批准”中批准它。


3
这已经在这里解释了,为什么要重复呢?
利亚姆'18

因为我添加了重要说明,所以出了什么问题?
burtsevyg

如果您想添加到原始答案中,则此处的适当操作是对原始答案进行评论。1年后未添加新答案。另外,我也不知道您的“重要说明”实际上是什么?
利亚姆(Liam)

1
有人认为这很有用。
burtsevyg

8

使用双引号而不是单引号

例如echo "$foo"echo '$foo'

如果使用Build with Parameters选项将管道配置为接受参数,则这些参数可以作为具有相同名称的Groovy变量来访问。看这里

如果不需要执行变量替换;,则可以删除分号(),删除括号(( and )),并使用单引号(')而不是double(")。看这里。这使我陷入了问题,尽管我发现只需要使用double()即可使其工作。"


4

希望以下代码对您有用:

def item = hudson.model.Hudson.instance.getItem('MyJob')

def value = item.lastBuild.getEnvironment(null).get('foo')

2
这是太多的工作,如果您使用的是“沙盒”模式,或者项目存在并发构建,则甚至无法工作。
Jesse Glick 2015年

您也可以使用jenkins.model.Jenkins.instance
Noam Manos 2015年

2

以下代码段使您可以访问所有Job参数

    def myparams = currentBuild.rawBuild.getAction(ParametersAction)
    for( p in myparams ) {
        pMap[p.name.toString()] = p.value.toString()
    }

2

请注意,在管道脚本(管道插件)中访问构建参数的方式已更改。这种方法:

getBinding().hasVariable("MY_PARAM")

不再工作了。请尝试以下方法:

def myBool = env.getEnvironment().containsKey("MY_BOOL") ? Boolean.parseBoolean("$env.MY_BOOL") : false

我尝试了此操作,但env.getEnvironment()失败并显示以下错误:Scripts not permitted to use method org.jenkinsci.plugins.workflow.support.actions.EnvironmentAction getEnvironment
GabLeRoux

1
@GabLeRoux,您可以在“管理Jenkins”>“进程内脚本批准”下的Jenkins中添加权限(在某些情况下,由于安全性较弱,这可能不是一个好主意)
Maksim 2016年

2
确实,这可能行得通,但是我更喜欢保持较低的安全风险:)我设法使其正常运行并发布了此答案
GabLeRoux

2

您也可以尝试使用parameters指令来使构建参数化并访问参数:

Doc: 管道语法:参数

例:

pipeline{

agent { node { label 'test' } }
options { skipDefaultCheckout() }

parameters {
    string(name: 'suiteFile', defaultValue: '', description: 'Suite File')
}
stages{

    stage('Initialize'){

        steps{

          echo "${params.suiteFile}"

        }
    }
 }

0

根据管道插件教程

如果您已将管道配置为在构建时接受参数(使用参数构建),则可以将它们作为同名的Groovy变量进行访问。

因此,尝试直接访问变量,例如:

node()
{
     print "DEBUG: parameter foo = " + foo
     print "DEBUG: parameter bar = ${bar}"
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.