Как загрузить отличный файл и запустить его

У меня есть файл jenkinsfile, помещенный в корень моего проекта, и я хотел бы загрузить файл groovy для моего конвейера и выполнить его. Единственный способ заставить это работать - создать отдельный проект и использовать команду fileLoader.fromGit. Я бы хотел сделать

def pipeline = load 'groovy-file-name.groovy'
pipeline.pipeline()

person user301693    schedule 13.06.2016    source источник


Ответы (5)


Если ваш Jenkinsfile и файл groovy в одном репозитории и Jenkinsfile загружен из SCM, вам необходимо сделать:

Example.Groovy

def exampleMethod() {
    //do something
}

def otherExampleMethod() {
    //do something else
}
return this

JenkinsFile

node {
    def rootDir = pwd()
    def exampleModule = load "${rootDir}@script/Example.Groovy "
    exampleModule.exampleMethod()
    exampleModule.otherExampleMethod()
}
person Anton Shishkin    schedule 29.06.2016
comment
Читатели, обратите внимание, что в Groovy вернуть это очень важно. - person Michael Easter; 21.01.2017
comment
@anton, можно ли также вызывать методы из загруженного скрипта без постоянного использования example.? Кроме того, может потребоваться, чтобы загруженный сценарий мог читать и записывать переменные из внешнего сценария. Это возможно? - person nepa; 24.01.2017
comment
@nepa нет, это невозможно. Для работы с переменными необходимо указать аргументы метода - person Anton Shishkin; 25.01.2017
comment
@anton тем временем я нашел оператор .& (например: def exampleMethod = example.&exampleMethod., который работает очень хорошо ... - person nepa; 29.01.2017
comment
@MichaelEaster да, я пропустил эту кучу. И, что важно: это вне области функции - person Christian Bongiorno; 19.07.2017
comment
@MichaelEaster, что именно возвращает "это"? Если это будет скрипт gradle, он вернет экземпляр класса Project в качестве привязки. Но в простом отличном файле я не мог этого понять. - person stdout; 04.01.2018
comment
Я получаю NoSuchFileException - person Saikat; 17.02.2019
comment
@AntonShishkin, что такое переменная ${rootDir}, и где / как она выставляется? Это присуще Дженкинсу или обычаю? Я получаю groovy.lang.MissingPropertyException: No such property: rootDir for class: groovy.lang.Binding. - person cowlinator; 11.04.2019
comment
Хорошо, это устарело. Вместо ${rootDir} используйте ${workspace}, установленный Jenkins. Кроме того, не забудьте снять флажок Облегченная проверка в конфигурации задания конвейера, иначе ваши .groovy скрипты не будут загружены из SCM. - person cowlinator; 11.04.2019
comment
Итак, я обнаружил предостережение - при запуске 2 одновременных экземпляров одного и того же задания Дженкинс добавит @2 к имени рабочей области ... однако это не так для каталога @script, что означает, что ${workspace}@script/Example.Groovy не будет работать при одновременном запуске строит. - person cowlinator; 20.04.2019
comment
Я нашел решение - используйте вместо этого ${jenkins_home}/workspace/${job_name}@script/Example.Groovy. - person cowlinator; 20.04.2019
comment
Что для этого эквивалентно декларативному стилю? - person Kanagavelu Sugumar; 21.11.2019

Перед выполнением load необходимо выполнить checkout scm (или другой способ проверки кода из SCM).

person Krzysztof Krasoń    schedule 14.06.2016
comment
Предполагается, что загружаемый файл находится в SCM. - person Roy Tinker; 30.09.2016
comment
Вы правы, если файл находится в SCM, то вам нужно получить его оттуда, прежде чем пытаться его загрузить. Но если файл библиотеки находится в том же репо, что и основной jenkinsfile, вам не нужно вызывать checkout, если конвейер настроен на автоматическое извлечение репо; в конфигурации работы. - person steve; 28.02.2021

Если у вас есть конвейер, который загружает более одного файла groovy, и эти файлы Groovy также обмениваются данными между собой:

JenkinsFile.groovy

def modules = [:]
pipeline {
    agent any
    stages {
        stage('test') {
            steps {
                script{
                    modules.first = load "first.groovy"
                    modules.second = load "second.groovy"
                    modules.second.init(modules.first)
                    modules.first.test1()
                    modules.second.test2()
                }
            }
        }
    }
}

first.groovy

def test1(){
    //add code for this method
}
def test2(){
    //add code for this method
}
return this

second.groovy

import groovy.transform.Field
@Field private First = null

def init(first) {
    First = first
}
def test1(){
    //add code for this method
}
def test2(){
    First.test2()
}
return this
person awefsome    schedule 10.08.2018
comment
можно вернуть что-то не то же вернуть это - например вернуть это? - person Nikolay Baranenko; 05.07.2021

Спасибо @anton и @Krzysztof Krasori, все работало нормально, если я объединил checkout scm и точный исходный файл

Example.Groovy

def exampleMethod() {
    println("exampleMethod")
}

def otherExampleMethod() {
    println("otherExampleMethod")
}
return this

JenkinsFile

node {
    // Git checkout before load source the file
    checkout scm

    // To know files are checked out or not
    sh '''
        ls -lhrt
    '''

    def rootDir = pwd()
    println("Current Directory: " + rootDir)

    // point to exact source file
    def example = load "${rootDir}/Example.Groovy"

    example.exampleMethod()
    example.otherExampleMethod()
}
person Mallikarjunarao Kosuri    schedule 05.09.2017
comment
Это было то, что мне нужно, чтобы позволить конвейеру Jenkins из SCM работать, теперь у меня есть все мои константы и функции, централизованные в общем Jenkinsfile.common.Groovy, который используется совместно моим конвейером выпуска и моим конвейером тестирования интеграции. - person ChrisPrime; 20.11.2018
comment
jenkins.io/doc/pipeline/steps/workflow-cps/ - person Saikat; 18.02.2019

Очень полезная ветка, была та же проблема, решенная после вас.

Моя проблема заключалась в следующем: Jenkinsfile -> позвонить first.groovy -> позвонить second.groovy

Вот мое решение:

Jenkinsfile

node {
  checkout scm
  //other commands if you have

  def runner = load pwd() + '/first.groovy'
  runner.whateverMethod(arg1,arg2)
}

first.groovy

def first.groovy(arg1,arg2){
  //whatever others commands

  def caller = load pwd() + '/second.groovy'
  caller.otherMethod(arg1,arg2)
}

NB: аргументы необязательны, добавьте их, если они есть, или оставьте поле пустым.

Надеюсь, это поможет в дальнейшем.

person kancio    schedule 13.07.2018
comment
Напоминаем, что load () работает только внутри node (). Второй load () работает, потому что somethingMethod () вызывается внутри node (). - person sterdun; 08.11.2019