2017-02-10 1 views
1

私はJenkinsパイプラインの共有ライブラリを構築していますので、Jenkinsfileはちょっときれいです。"vars/foo.groovy"の "call"メソッドのprintlnは動作しますが、クラスのメソッドにはありません

以下のページを参考にしています:https://jenkins.io/doc/book/pipeline/shared-libraries/

最初に、コード内に "call()"メソッドを持つ "vars/methodName.groovy"のような個々のファイルでいくつかのメソッドを定義しました。これは問題なく動作しますが、特にこれらのメソッドで "println"コールがJenkinsコンソール出力に表示されることに注意してください。

私はその後、私は、メソッド呼び出しの間でいくつかの状態を保存したかったので、私はこの(マイナスいくつかの必要な輸入)のように始まる「uslutils.groovy」という名前の「vars」に新しいファイルを追加したことを決めた:

class uslutils implements Serializable { 

私はプロパティを設定してこれを返すいくつかの "with<property>"メソッドを定義しました。

私は、このような何かに見える「uslutils」で「public String toString()」方法を書きました。そして、

public String toString() { 
    println "Inside uslutils.toString()." 
    return "[currentBuild[${currentBuild}] mechIdCredentials[${mechIdCredentials}] " + 
      "baseStashURL[${baseStashURL}] jobName[${jobName}] codeBranch[${codeBranch}] " + 
      "buildURL[${buildURL}] pullRequestURL[${pullRequestURL}] qBotUserID[${qBotUserID}] " + 
      "qBotPassword[${qBotPassword}]]" 
} 

を、私のJenkinsfile内、uslutilsのプロパティを設定した後、私はこのような行を追加しました:

println "uslutils[${uslutils}]" 

私は仕事をしていましたが、興味深いのは私が "uslutils"という行、または "uslutils.toString()"の中にいないことです。ライン。しかし、私はこれまでに追加した関数メソッドを "uslutils"( "with"メソッド以外)に変更しました。これは文字列値を返し、 "x"を値に追加しました。私のJenkinsfileはその結果を印刷していましたが、追加の "x"が表示されました。

共有ライブラリクラスの中から "println"出力を省略して見知らぬ人でも、 "println"呼び出しの出力を省略したJenkinsfileの暗黙的に " uslutils.toString() "方法。元の "call()"メソッドのprintlnコールは、コンソール出力に表示されていました。

ここで何が起こっている可能性がありますか?

更新:私は今、(特に)私のJenkinsfileに次の行を持って

println "uslutils.qBotPassword[${uslutils.qBotPassword}]" 
println "uslutils[${uslutils}]" 
println "uslutils.toString()[${uslutils.toString()}]" 

そして繰り返すが、ここでは "uslutils.toString()" メソッドです。

:ここ
public String toString() { 
    println "Inside uslutils.toString()." 
    return "[currentBuild[${currentBuild}] mechIdCredentials[${mechIdCredentials}] " + 
      "baseStashURL[${baseStashURL}] jobName[${jobName}] codeBranch[${codeBranch}] " + 
      "codeURL[${codeURL}] buildURL[${buildURL}] pullRequestURL[${pullRequestURL}] qBotUserID[${qBotUserID}] " + 
      "qBotPassword[${qBotPassword}]]" 
} 

ビルドからの出力のラインに対応しています

[Pipeline] echo 
uslutils.qBotPassword[...] 
[Pipeline] echo 
uslutils.toString()[[currentBuild[[email protected]fb2c94] mechIdCredentials[121447d5-0fe4-470d-b785-6ce88225ef01] baseStashURL[https://...] jobName[unified-service-layer-build-pipeline] codeBranch[master] codeURL[ssh://[email protected]] buildURL[http://...] pullRequestURL[] qBotUserID[...] qBotPassword[...]] 

「uslutils [$ {uslutils}」を印刷しようとしている行は、単に無視されました。 "uslutils.toString()[$ {uslutils.toString()}]"を印刷しようとした行はレンダリングしましたが、 "Inside uslutils.toString()"という文字列も表示されました。レンダリングしませんでした。

私はまだこの動作の説明を探していますが、これはより簡潔に要約しているかもしれません。

答えて

6

私はいくつかの掘り出しを行い、この問題を発見しました。https://issues.jenkins-ci.org/browse/JENKINS-41953、基本的には通常のパイプラインスクリプトprintlnechoステップにエイリアスされています。しかし、クラスに入っているとき、たとえばパイプラインCPSの外側では、エコーステップは使用できず、printlnは無視されます(わかっているので、使用可能なロガーはありません)。

変数を使用してスクリプト環境をクラスメソッドに伝播し、echoを変数(found solution in this thread)で呼び出すことができます。

class A { 
    Script script; 
    public void a() { 
     script.echo("Hello") 
    } 
} 
def a = new A(script:this) 
echo "Calling A.a()" 
a.a() 

出力:

Started by user jon 
[Pipeline] echo 
Calling A.a() 
[Pipeline] echo 
Hello 
[Pipeline] End of Pipeline 
Finished: SUCCESS 

私たちが望むものである。このように。比較のために、ここで伝播することなく、次のとおりです。

class A { 
    public void a() { 
     println "Hello" 
    } 
} 
def a = new A() 
echo "Calling A.a()" 
a.a() 

は与える:

Started by user jon 
[Pipeline] echo 
Calling A.a() 
[Pipeline] End of Pipeline 
Finished: SUCCESS 
+0

はあなたがマスター/スレーブ環境でこのソリューションを実行しようとしたがありますか?それはスクリプトのプロパティをシリアル化しようとすると失敗するようです。 – Ivo

+1

あなたはおそらく、メソッドA.a()に@NonNCPアノテーションを付ける必要があります。クラスは、メソッドを引数としてスクリプトを阻止して渡すSerializableインターフェイスを実装する必要があります... –

関連する問題