Jenkins - 将 array/list 传递给参数化远程构建

Jenkins - Passing array/list to Parameterized Remote Build

我正在使用 Jenkins 通过 Publish Over SSH 命令远程 运行 一个 Ansible 剧本。

这个命令:

curl -k -v -X POST https://jenkins.myhost.com/job/Ansible_Deploy/build?token=<appToken> --user <myUser>:<userToken> --data-urlencode json='{"parameter":[{"name":"thisIsAList","value":["one","two","three"]}]}'

应该触发 post-build 操作以通过 SSH 远程执行以下命令:

ansible-playbook /home/<myUser>/test/practice.yml --extra-vars "thisIsAList=$thisIsAList"

thisIsAList是Job Notifications下的字符串参数,job被参数化。我已经成功地执行了类似的命令,但是这个失败了,假设是因为值是一个列表。我试过 "String Parameter" 和 "Multi-line String Parameter" 都无济于事。

这是堆栈跟踪:

org.kohsuke.stapler.WrongTypeException: Got type array but no lister class found for type class java.lang.String
        at org.kohsuke.stapler.RequestImpl$TypePair.convertJSON(RequestImpl.java:723)
        at org.kohsuke.stapler.RequestImpl.bindJSON(RequestImpl.java:478)
        at org.kohsuke.stapler.RequestImpl.instantiate(RequestImpl.java:777)
Caused: java.lang.IllegalArgumentException: Failed to convert the value parameter of the constructor public hudson.model.StringParameterValue(java.lang.String,java.lang.String)
        at org.kohsuke.stapler.RequestImpl.instantiate(RequestImpl.java:779)
        at org.kohsuke.stapler.RequestImpl.access0(RequestImpl.java:83)
        at org.kohsuke.stapler.RequestImpl$TypePair.convertJSON(RequestImpl.java:678)
Caused: java.lang.IllegalArgumentException: Failed to instantiate class hudson.model.StringParameterValue from {"name":"thisIsAList","value":["one","two","three"]}
        at org.kohsuke.stapler.RequestImpl$TypePair.convertJSON(RequestImpl.java:680)
        at org.kohsuke.stapler.RequestImpl.bindJSON(RequestImpl.java:478)
        at org.kohsuke.stapler.RequestImpl.bindJSON(RequestImpl.java:474)
        at hudson.model.StringParameterDefinition.createValue(StringParameterDefinition.java:88)
        at hudson.model.ParametersDefinitionProperty._doBuild(ParametersDefinitionProperty.java:165)

注意:这可能与 How to pass an array to a jenkins parameterized job via remote access api? 重复,但尚未获得有效回复。

由于在 Jenkins 或 Ansible 文档中的任何地方都没有详细说明这种嵌套级别,既然我已经解决了我的问题,我将阐明该主题。

命令:

ansible-playbook /home/<myUsr>/test/practice.yml --extra-vars "thisIsAList=$thisIsAList"

应该将 thisIsAList 声明为字典对象。即:

ansible-playbook /home/<myUsr>/test/practice.yml --extra-vars "{thisIsAList=$thisIsAList}"

此外,cURL 命令中的数据应该采用不同的格式,如下所示:

json='{"parameter":[{"name":"thisIsAList","value":"[one,two,three]"}]}'

注意:双引号围绕 整个 列表,而不是单个元素。

最后,对于更多嵌套项(例如列表中的字典),您必须像这样转义双引号:

{"parameter":[{"name":"thisIsADictNestedInAList","value":"[{\"name\":\"numbers\",\"value\":[1s, 2s, 3s]}]"}]}

看来,在这个嵌套级别,不再需要双引号列表;可能是因为上一级的引用已经导致它被正确解释。

这是一个猜测,基于我在选择参数方面看到的类似问题。我发现的任何文档关于如何处理这些似乎都是错误的。它不应该是一个列表。尝试作为字符串传递,并用换行符分隔项目。

curl -k -v -X POST https://jenkins.myhost.com/job/Ansible_Deploy/build?token=<appToken> --user <myUser>:<userToken> --data-urlencode json='{"parameter":[{"name":"thisIsAList","value":"one\ntwo\nthree"}]}'

让我知道这是否可行。我有兴趣一探究竟。


编辑:(基于评论)

这行得通吗:

curl -k -v -X POST https://jenkins.myhost.com/job/Ansible_Deploy/build?token=<appToken> --user <myUser>:<userToken> --data-urlencode json='{"parameter":[{"name":"thisIsAList","value":"'{\"thisIsAList\": [\"one\",\"two\",\"three\"]}'"}]}'

嵌套引号有点难看。如果您正在使用管道或者可以先在 shell 脚本中处理数据,它可能会更干净。