パイプラインスクリプトの入力として使用したいXMLファイルがあります。問題は、XMLParserがシリアル化できないため、NonCPS関数に入れましたが、そのためにNodeオブジェクトを失いました。
これはパイプラインスクリプトです:
def buildPlanPath = 'C:\\buildPlan_test.xml'
@NonCPS
groovy.util.Node getBuildPlan(path) {
new XmlParser().parseText(readFile(path))
}
node {
//def buildPlan = new XmlParser().parseText(readFile(buildPlanPath))
groovy.util.Node buildPlan = getBuildPlan(buildPlanPath)
println buildPlan.getClass()
println buildPlan
println buildPlan.branch
}
これは入力サンプルです:
<branch name='mybranch'>
<stage>
<job name='job11' />
<job name='job12' />
</stage>
<stage>
<job name='job21' />
<job name='job22' />
<job name='job23' />
</stage>
<stage>
<job name='job31' />
</stage>
</branch>
結果は次のとおりです。
Started by user admin
[Pipeline] node
Running on master in C:\Jenkins\workspace\pipeline-develop
[Pipeline] {
[Pipeline] readFile
[Pipeline] echo
class Java.lang.String
[Pipeline] echo
<branch name='mybranch'>
<stage>
<job name='job11' />
<job name='job12' />
</stage>
<stage>
<job name='job21' />
<job name='job22' />
<job name='job23' />
</stage>
<stage>
<job name='job31' />
</stage>
</branch>
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
groovy.lang.MissingPropertyException: No such property: branch for class: Java.lang.String
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.Java:53)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.Java:458)
at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.getProperty(DefaultInvoker.Java:25)
at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.Java:17)
at WorkflowScript.run(WorkflowScript:16)
at ___cps.transform___(Native Method)
at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.get(PropertyishBlock.Java:62)
at com.cloudbees.groovy.cps.LValueBlock$GetAdapter.receive(LValueBlock.Java:30)
at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.fixName(PropertyishBlock.Java:54)
at Sun.reflect.GeneratedMethodAccessor327.invoke(Unknown Source)
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at Java.lang.reflect.Method.invoke(Unknown Source)
at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.Java:72)
at com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.Java:21)
at com.cloudbees.groovy.cps.Next.step(Next.Java:58)
at com.cloudbees.groovy.cps.Continuable.run0(Continuable.Java:154)
at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.Java:164)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.Java:276)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$000(CpsThreadGroup.Java:78)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.Java:185)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.Java:183)
at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.Java:47)
at Java.util.concurrent.FutureTask.run(Unknown Source)
at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.Java:112)
at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.Java:28)
at Java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at Java.util.concurrent.FutureTask.run(Unknown Source)
at Java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at Java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at Java.lang.Thread.run(Unknown Source)
Finished: FAILURE
現在最新のパイプライン2.1でJenkins2.7を使用しています。
あなたはXmlSlurperを使うことができます、それは私のために働きます。
def xmlText = new XmlSlurper().parse(MyURL)
xmlText.data.artifact.each {******
@NonCPS
メソッドは、Serializable
タイプのみを受け入れるか返す必要があります。メソッドから.branch
を返してみてください。
結局、私のアプローチは間違っていたと思います。XMLファイルを別のGroovyスクリプトに変換し、パイプライン内にロードすることにしました。
更新:最近、わかりやすくするために回答の編集を始めましたが、実際には、構成をXMLファイルに保存するのをやめ、Groovyスクリプトを選択したため、柔軟性が向上しました。それは一般的な習慣ではないかもしれませんが、私のニーズには合っています。
例-代わりに:
config.xml:
<settings>
<floopi>2</floopi>
</settings>
私が使用した:
config.groovy:
def call() {[
floopi: 2
]}
return this
そしてパイプラインスクリプトでは:
stage('init') {
def settings = load('config.groovy')()
echo "floopi: ${settings.floopi}"
}
私はそれがより良い答えであることを願っています:)
ブランチはルート要素であるため、解析されたノードにアクセスするときに明示的に指定する必要はありません。
変更してみてください
println buildPlan.branch
に
println buildPlan.stage
ステージノードを印刷するには