web-dev-qa-db-ja.com

動的行列軸の値を持つ宣言型パイプライン

こんにちは、Jenknis-Declarative-Pipeline-Jobの作業を取得しようとしています。

Use-Caseはかなり単純なはずです。
同じJenkinsパイプラインで複数のプラグインを構築したい。そのために、プラグインがパラメーターに使用できるインターフェースを備えた「JenkinsLibrary」を作成しました。このパラメーターの1つは、軸の値です。

私の問題は このreddistの投稿 によく似ています。

マトリックスビルドの「軸」の「値」を変数から設定したい。私はアイデアがありません、これは可能ですか?

これが私の例です:
my_library.groovyファイルを含む「JenkinsLibrary」

def call(Map i_options)
{
// later I will parse the options to set the values, but currently the step before already crashes ...

    def axis_1_values = "axis_1_value_A"
// already tried the following alternatives ...
//    def axis_1_values = 'axis_1_value_A'
//    def axis_1_values = '''axis_1_value_A'''
//    def axis_1_values = ["axis_1_value_A", "axis_2_value_A"]
    pipeline
    {
        agent any
        stages { stage("stage A") { matrix {
            axes {
                axis {
                    name "axis_1"
                    // values "axis_1_value_A" // <- of course this works ...
                    // but I want to read it from a variable
                    values "${axis_1_values}" 
                    // I already tried more variants
                    // values ${axis_1_values}
                    // values axis_1_values
                }
                axis {
                    name "axis_2"
                    values "axis_2_value_A", "axis_2_value_B"
                }
            }
            stages {
                stage("another stage") { steps {
                    echo "hello world from ${axis_1} && ${axis_2}"
                } }
            }
        } } }
    }
}

「Jenkinsfile」ファイルを含むプラグイン:

@Library("JenkinsLibrary") _

def options = [
    axis_values: "a_axis_value"
]

my_library(options)

次のエラーが発生します。

[...] Expected string literal but got "${axis_1_values}"

完全なログ:

    19: Expected string literal but got "${axis_1_values}" @ line 19, column 28.
                       values "${axis_1_values}" 
                              ^

1 error

    at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.Java:310)
    at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.Java:1085)
    at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.Java:603)
    at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.Java:581)
    at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.Java:558)
    at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.Java:298)
    at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.Java:268)
    at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.Java:254)
    at groovy.lang.GroovyClassLoader.recompile(GroovyClassLoader.Java:761)
    at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.Java:718)
    at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.Java:787)
    at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.Java:775)
    at org.jenkinsci.plugins.workflow.cps.global.UserDefinedGlobalVariable.getValue(UserDefinedGlobalVariable.Java:57)
    at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.Java:113)
    at Sun.reflect.GeneratedMethodAccessor729.invoke(Unknown Source)
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
    at Java.lang.reflect.Method.invoke(Method.Java:498)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.Java:93)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.Java:325)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.Java:1213)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.Java:1022)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.Java:42)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.Java:48)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.Java:113)
    at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.Java:160)
    at org.kohsuke.groovy.sandbox.GroovyInterceptor.onMethodCall(GroovyInterceptor.Java:23)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.Java:157)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.Java:142)
    at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.Java:158)
    at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.Java:162)
    at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.Java:17)
    at WorkflowScript.run(WorkflowScript:21)
    at ___cps.transform___(Native Method)
    at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.Java:86)
    at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.Java:113)
    at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.Java:83)
    at Sun.reflect.GeneratedMethodAccessor500.invoke(Unknown Source)
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
    at Java.lang.reflect.Method.invoke(Method.Java:498)
    at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.Java:72)
    at com.cloudbees.groovy.cps.impl.LocalVariableBlock$LocalVariable.get(LocalVariableBlock.Java:39)
    at com.cloudbees.groovy.cps.LValueBlock$GetAdapter.receive(LValueBlock.Java:30)
    at com.cloudbees.groovy.cps.impl.LocalVariableBlock.evalLValue(LocalVariableBlock.Java:28)
    at com.cloudbees.groovy.cps.LValueBlock$BlockImpl.eval(LValueBlock.Java:55)
    at com.cloudbees.groovy.cps.LValueBlock.eval(LValueBlock.Java:16)
    at com.cloudbees.groovy.cps.Next.step(Next.Java:83)
    at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.Java:174)
    at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.Java:163)
    at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.Java:129)
    at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.Java:268)
    at com.cloudbees.groovy.cps.Continuable.run0(Continuable.Java:163)
    at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$001(SandboxContinuable.Java:18)
    at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.Java:51)
    at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.Java:185)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.Java:405)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$400(CpsThreadGroup.Java:96)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.Java:317)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.Java:281)
    at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.Java:67)
    at Java.util.concurrent.FutureTask.run(FutureTask.Java:266)
    at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.Java:131)
    at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.Java:28)
    at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.Java:59)
    at Java.util.concurrent.Executors$RunnableAdapter.call(Executors.Java:511)
    at Java.util.concurrent.FutureTask.run(FutureTask.Java:266)
    at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1149)
    at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:624)
    at Java.lang.Thread.run(Thread.Java:748)
Finished: FAILURE

私のシステム:Jenkins-Version:Jenkins ver。 2.190.1
Declarative-Plugin-Version 1.5.0
宣言型エージェントAPI:1.1.1
宣言型拡張ポイントAPI:1.5.0
(他の多くのプラグイン、これは重要なプラグインだと思います)

[〜#〜]更新[〜#〜]
まだ解決策がありません。しかし、このように変数を定義すると、それに「GStringImpl」を挿入しようとしていることを理解しています。しかし、Java文字列としてキャストすることはできません。

def _str_1 = "a string"
def _str_2 = "${_str_1}"
println _str_1.class             // -> class Java.lang.String
println _str_2.class             // -> class org.codehaus.groovy.runtime.GStringImpl
def _str_3 = "${_str_1}" as Java.lang.String  
println _str_3.class             // -> class Java.lang.String

しかし、私はまだ単一の値を追加する方法がわかりません。

values "${axis_1_values}" as as Java.lang.String     // error-msg: Expected string literal but got ${as}  
values ("${axis_1_values}" as Java.lang.String)      // error-msg: Expected string literal but got ${"${axis_1_values}"  
values axis_1_values.toString()                      // error-msg: Method calls on objects not allowed outside "script" blocks.
values "${axis_1_values}".toString()                 // error-msg: Expected a symbol @ line 26, column 28.

このキャストは単一の値で機能する可能性がありますが、デフォルトの例で可能なように、値のリストを追加できるようにしたいのですが...
values "axis_2_value_A", "axis_2_value_B"

これは、宣言型パイプラインの「docker-agent」部分で機能するのではないかと思います。

agent { 
    docker {
        image "${_image}:latest"
        label "${_label}"
    }
}

しかし、私はコードで、docker-labelの解析が個別に実装されていることに気付きました...

宣言的パイプラインのマトリックス/軸機能内でその目標を達成する方法はまだわかりません。

(事実:これを行っても、スクリプトパイプラインの青海ビューでの視覚化がまだバグがあり、問題が無視されているように見える主な理由の1つ...
https://issues.jenkins-ci.org/browse/JENKINS-53751

5
tharilya

動的軸の値は、プラグインのv1.6.0以降、宣言型パイプラインではサポートされていません。エラーメッセージは、「リテラル文字列」の値を想定していることを示しています。おそらくメッセージには、「テンプレート文字列、配列、変数、または関数呼び出しは許可されていません」と記載されているはずです。

これは仕様によるものであり、パイプラインの作成者がパイプラインエンジンの内部前提に噛み付かれるのを防ぐことを目的としています。変更することは可能ですが、慎重な計画とテストが必要になります。

https://issues.jenkins.io/ でJIRAを提出するか、 Jenkins Pipeline Authoring SIG に参加して、この機能の実装にご協力ください。

2
BitwiseMan

あなたが達成しようとしているのは、それをテンプレートとして再利用するために、共有ライブラリにパイプラインをラップすることですか?

このライブラリを試すことをお勧めします https://github.com/SAP/jenkins-pipelayer/

これはテンプレートシステムを実装し、プロパティファイルに基づいてジョブを生成します。ジョブがjenkinsに生成されると、二重中括弧間の変数が置き換えられます。 https://github.com/SAP/jenkins-pipelayer/blob/master/USAGE.md#template-engine

Libは、パイプラインの最初の実行時にビルドされないジョブパラメーターに関する問題も解決します

0
fredericrous