Jenkins-pipeline: нет такого метода DSL

У меня есть Jenkins Pipeline JOB, где я объявил несколько этапов, использующих внешнюю функцию, которую я создал сам в том же groovy script.

errorList = ["badGatewayMsg", "closedByRemoteHostMsg", "connectionTimedOut"]
def boolean someFunction(name) {
    String jobLog = jenkins.model.Jenkins.instance.getItemByFullName(name).lastBuild.log
    for (error in errorList) {
        if (jobLog.contains(error))
            return true
    }
    return false
}

stage('stage1') {
        if(someFunction('job1Name'))
           // do Something
    }

stage('stage2') {
        if(someFunction('job2Name'))
           // do Something
    }

Когда я хочу запустить эту сборку конвейера, я получаю следующую ошибку:

java.lang.NoSuchMethodError: No such DSL method 'someFunction' found among steps ....

Спасибо за вашу помощь!


person marherbi    schedule 03.08.2018    source источник
comment
Код отредактирован или он действительно сообщает о методе, который никогда не использовался или не объявлялся в вашем коде? Также поможет полная трассировка стека исключения.   -  person Oliver Gondža    schedule 03.08.2018
comment
Этот метод действительно используется на всех моих этапах, я просто не знаю, где я могу объявить его видимым во всех моих отличных сценариях.   -  person marherbi    schedule 03.08.2018
comment
@marherbi Я не думаю, что ты понял его вопрос. Вы вызываете метод, который вы не объявили или не определили в показанном коде. Он спрашивает, не отображали ли вы код или он не существует, и в этом случае проблема в этом.   -  person Matt Schuchard    schedule 03.08.2018
comment
Похоже, вы используете метод someFunction, но исключение жалуется на isOnError, который, по-видимому, не является внутренним идентификатором, основанным на причинно-следственном поиске.   -  person Oliver Gondža    schedule 03.08.2018
comment
Ах!!! вы правы, я просто изменил имя метода, извините!!   -  person marherbi    schedule 03.08.2018
comment
Не уверен, что проблема все еще существует. Может быть, это потому, что вы используете как «def», так и тип данных (логический) при объявлении этого метода? Однако я бы ожидал другой ошибки.   -  person Joerg S    schedule 04.08.2018
comment
@Joerg S, вы имеете в виду, что я должен опустить ключевое слово «def»? Я думаю, что проблема сохраняется, потому что этот метод не виден на этапах, и я хочу знать, как написать целый скрипт, где мой метод будет виден везде.   -  person marherbi    schedule 05.08.2018
comment
Вы уже пытались опустить ключевое слово def? Не уверен, что это допустимый синтаксис Groovy. Либо используйте def, либо тип данных, но не оба.   -  person Joerg S    schedule 11.08.2018


Ответы (1)


Из любопытства я скопировал код в свой локальный Jenkins - и он сработал (после исправления очевидных проблем, таких как создание отсутствующих заданий и исправление условий if).

Тем не менее, чтобы очистить код, вам необходимо:

  1. Избавьтесь от ключевого слова def (или, в качестве альтернативы, избавьтесь от определения типа данных boolean). Вы можете проверить: Groovy: ключевое слово def против конкретного типа

  2. Добавьте ключевое слово @NonCPS при доступе к внутренним компонентам Jenkins, которые нельзя сериализовать.

  3. Для полноты: в дополнение к тому, что, конечно, для доступа к внутренностям Jenkins вам необходимо переключить режим песочницы или поместить свой код в глобальную общую библиотеку.

Вот мой рабочий пример:

errorList = ["badGatewayMsg", "closedByRemoteHostMsg", "connectionTimedOut"]
@NonCPS
boolean someFunction(name) {
    String jobLog = jenkins.model.Jenkins.instance.getItemByFullName(name).lastBuild.log
    for (error in errorList) {
        if (jobLog.contains(error))
            return true
    }
    return false
}

stage('stage1') {
    if(someFunction('job1Name')) {
       // do Something
    }
}

stage('stage2') {
    if(someFunction('job2Name')) {
       // do Something
    }
}
person Joerg S    schedule 11.08.2018