2017-02-10 19 views
1

我正在迭代构建Jenkins管道共享库,因此我的Jenkinsfile稍微清洁一些。println在“vars/foo.groovy”的“调用”方法中工作,但不在类中的方法中

我使用以下页面进行指导:https://jenkins.io/doc/book/pipeline/shared-libraries/

我首先在单个文件中定义了几种方法,如“vars/methodName.groovy”,在代码中使用“call()”方法。这工作正常,我特别注意到在这些方法中的“println”调用可以在Jenkins控制台输出中看到。

然后我决定我想保存方法调用之间的一些状态,所以我在“vars”命名为“uslutils.groovy”是这样开始增加了一个新的文件(减去一些需要进口):

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”行或“Ins​​ide uslutils.toString()”。线。不过,我修改了迄今为止添加到“uslutils”(除了“with”方法)之外的一个函数方法,它返回一个字符串值,并且我只为该值添加了一个“x”。我的Jenkinsfile正在打印结果,它确实显示了额外的“x”。

请注意,这里没有发生任何错误,它似乎忽略了共享库类中的“println”输出,甚至更奇怪的是,省略了Jenkins文件中“println”调用的输出,它隐式地调用“ 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,基本上在正常的管道脚本中println被别名为echo的一步。但是当你在上课时,例如在流水线CPS之外,那么回声步骤不可用,并且println被忽略(因为据我了解,没有可用的记录器)。

您可以做的是使用变量将脚本环境传播到您的类方法中,并通过变量(found solution in this thread)调用echo。就像这样:

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接口,它阻止,然后将脚本作为参数传递给方法... –

相关问题