2017-02-10 8 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 { 

I определенные некоторые методы «with<property>», которые устанавливают свойство и возвращают это.

Я тогда написал «public String toString()» метод в «uslutils», который выглядит примерно так:

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» или «Inside uslutils.toString()». линия. Однако я модифицировал один функциональный метод, который я добавил до сих пор в «uslutils» (помимо методов «with»), который возвращает строковое значение, и я просто добавил «x» к значению. Мой Jenkinsfile напечатал результат из этого, и он показал дополнительный «x».

Обратите внимание, что здесь не было ошибок, казалось, что он просто опускает вывод «println» из класса общей библиотеки и даже незнакомец, опускает вывод «println» в файле Jenkins, который неявно вызывает « uslutils.toString() "способ. Обратите внимание, что вызовы println в исходных методах «call()» были видны на выходе консоли.

Любые идеи, что может случиться здесь?

Update:

теперь у меня есть следующие строки в моем 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 игнорируется (поскольку, насколько я понимаю, нет доступного регистратора).

Что вы можете сделать, это распространить среду сценария на методы класса с помощью переменной и вызвать 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, который предотвращает и затем передает скрипт в качестве аргумента для метода ... –

 Смежные вопросы

  • Нет связанных вопросов^_^