首页 > 解决方案 > Job DSL:如果存在多个这样的节点,我如何向先前生成的 XML 添加配置块?

问题描述

我正在使用Active Choices 插件来动态生成参数值。不幸的是,Job DSL 不支持安全脚本配置。这就是为什么我尝试使用 Job DSL 的configure块添加它。

我使用获取工作上下文或参数上下文或其他任何内容的方法。但是我从另一个问题中了解到,我无法使用configure相同的方法访问生成的 XML,因为尚未生成 XML。我希望我理解这一点 - 所以就我而言,我调用了两种方法。第一个创建基本的 Active Choices 配置,第二个添加一个安全的 Groovy 脚本。

请注意,我通过读取 Groovy 脚本的源代码(Branch在本例中)来动态添加 Groovy 脚本。

      factory.freeStyleJob(jobName) {
        ...
        parameters {
          activeChoiceFormattedHtmlParameter delegate, PARAMETER_BRANCH, BRANCH_PARAMETER_DESCRIPTION, PARAMETER_STAGE, PARAMETER_DATABASE
        }
        ...

        activeChoiceFormattedHtmlScript delegate, PARAMETER_BRANCH, Branch
      }

还有我的方法:

    static void activeChoiceFormattedHtmlParameter(Object parameterContext, String parameterName, String parameterDescription, String... referencedParameters) {
      parameterContext.with {
        activeChoiceReactiveReferenceParam(parameterName) {
          description(parameterDescription)
          choiceType(CHOICE_TYPE_FORMATTED_HTML)
          referencedParameters.each { referencedParameter(it) }
        }
      }
    }

这会产生:

            <org.biouno.unochoice.DynamicReferenceParameter>
                <name>BRANCH</name>
                <description>...the description...</description>
                <randomName>choice-parameter-12102071997857508</randomName>
                <visibleItemCount>1</visibleItemCount>
                <referencedParameters>STAGE, DATABASE</referencedParameters>
                <choiceType>ET_FORMATTED_HTML</choiceType>
                <omitValueField>false</omitValueField>
                <parameters class="linked-hash-map"/>
            </org.biouno.unochoice.DynamicReferenceParameter>

然后是第二种方法:

    static void activeChoiceFormattedHtmlScript(Object jobContext, String parameterName, Class scriptClass) {
      jobContext.with {
        configure { node ->
          def parameterNode = node / 'properties' / 'hudson.model.ParametersDefinitionProperty' / 'parameterDefinitions' / 'org.biouno.unochoice.DynamicReferenceParameter'
          parameterNode << 'script'('class':'org.biouno.unochoice.model.GroovyScript') {
            'secureScript' {
              'script'(ScriptReader.readScript(scriptClass))
              'sandbox'('false')
              'classpath' {
                'entry' {
                  'url'("file:${GROOVY_JAR}")
                }
              }
            }
            'secureFallbackScript' {
              'script'('')
              'sandbox'('false')
            }
          }
        }
      }
    }

这将添加脚本:

            <org.biouno.unochoice.DynamicReferenceParameter>
                <name>BRANCH</name>
                <description>...the description...</description>
                <randomName>choice-parameter-12102071997857508</randomName>
                <visibleItemCount>1</visibleItemCount>
                <referencedParameters>STAGE, DATABASE</referencedParameters>
                <choiceType>ET_FORMATTED_HTML</choiceType>
                <omitValueField>false</omitValueField>
                <parameters class="linked-hash-map"/>
                <script class="org.biouno.unochoice.model.GroovyScript">
                    <secureScript>
                        <script>...the script...</script>
                        <sandbox>false</sandbox>
                        <classpath>
                            <entry>
                                <url>file:/path/to/my/groovy-library.jar</url>
                            </entry>
                        </classpath>
                    </secureScript>
                    <secureFallbackScript>
                        <script/>
                        <sandbox>false</sandbox>
                    </secureFallbackScript>
                </script>
            </org.biouno.unochoice.DynamicReferenceParameter>

现在解决我的问题:在第二种方法configure中选择第一种org.biouno.unochoice.DynamicReferenceParameter. 但是由于我要添加更多参数,所以我需要按名称选择它,而不仅仅是找到的第一个节点。否则我总是覆盖第一个参数的脚本,而其他所有参数都没有 Groovy 脚本。

我尝试访问... / 'org.biouno.unochoice.DynamicReferenceParameter' / 'name' / parameterName哪个有效,但当然写入错误的位置并破坏<name>节点。

我也尝试使用... / 'org.biouno.unochoice.DynamicReferenceParameter' / 'name' / parameterName然后parameterNode.parent,但这似乎返回null

谁能给个提示?我究竟做错了什么?

标签: jenkinsjenkins-job-dsl

解决方案


OK, I managed to access the required node, even if it feels not very elegant:

    ...
    jobContext.with {
      configure { node ->
        def parameterDefinitionsNode = node / 'properties' / 'hudson.model.ParametersDefinitionProperty' / 'parameterDefinitions'
        def parameters = parameterDefinitionsNode.children().findAll { it.name() == parameterClass }
        for (parameter in parameters) {
          def name = parameter.'name'
          if (name.text() == parameterName) {
            parameter << 'script'('class':'org.biouno.unochoice.model.GroovyScript') {

推荐阅读