Могу ли я создать динамические этапы в трубопроводе Дженкинса?

Мне нужно запустить динамический набор тестов в декларативном конвейере. Для лучшей визуализации я хотел бы создать сцену для каждого теста. Есть ли способ сделать это?

Единственный способ создать сцену, которую я знаю, это:

stage('foo') {
   ...
}

Я видел этот пример, но я не использую декларативный синтаксис.

Ответ 1

Используйте скриптовый синтаксис, который обеспечивает большую гибкость, чем декларативный синтаксис, хотя декларативный более документирован и рекомендуется.

Например, этапы могут быть созданы в цикле:

def tests = params.Tests.split(',')
for (int i = 0; i < tests.length; i++) {
    stage("Test ${tests[i]}") {
        sh '....'
    }
}

Ответ 2

Возможно, вы захотите взглянуть на этот пример - у вас может быть функция, возвращающая замыкание, в которой должна быть стадия.

Этот код показывает концепцию, но не имеет стадии в этом.

def transformDeployBuildStep(OS) {
    return {
        node ('master') { 
        wrap([$class: 'TimestamperBuildWrapper']) {
...
        } } // ts / node
    } // closure
} // transformDeployBuildStep

stage("Yum Deploy") {
  stepsForParallel = [:]
  for (int i = 0; i < TargetOSs.size(); i++) {
      def s = TargetOSs.get(i)
      def stepName = "CentOS ${s} Deployment"
      stepsForParallel[stepName] = transformDeployBuildStep(s)
  }
  stepsForParallel['failFast'] = false
  parallel stepsForParallel
} // stage

Ответ 3

@Jorge Machado: Потому что я не могу комментировать, мне пришлось опубликовать его в качестве ответа. Я решил это недавно. Надеюсь, это поможет вам.

Декларативный трубопровод:

Простой статический пример:

stage('Dynamic') {
        steps {
            script {
                stage('NewOne') {

                        echo('new one echo')

                }
            }
        }
    }

Динамический реальный пример:

    // in a declarative pipeline
        stage('Trigger Building') {
              when {
                environment(name: 'DO_BUILD_PACKAGES', value: 'true')
              }
              steps {
                executeModuleScripts('build') // local method, see at the end of this script
              }
            }


    // at the end of the file or in a shared library
        void executeModuleScripts(String operation) {

          def allModules = ['module1', 'module2', 'module3', 'module4', 'module11']

          allModules.each { module ->  
          String action = "${operation}:${module}"  

          echo("---- ${action.toUpperCase()} ----")        
          String command = "npm run ${action} -ddd"                   

            // here is the trick           
            script {
              stage(module) {
                bat(command)
              }
            }
          }

}

Ответ 4

Я использую это, чтобы генерировать мои этапы, которые содержат в них работу Дженкинса. build_list - это список заданий Jenkins, которые я хочу вызвать из моей основной работы Jenkins, но у вас есть сцена для каждого задания, которое является триггером.

build_list = ['job1', 'job2', 'job3']
        for(int i=0; i < build_list.size(); i++) {
          stage(build_list[i]){
               build job: build_list[i], propagate: false
          }
        }

Ответ 5

Как предположил JamesD, вы можете создавать этапы динамически (но они будут последовательными), например так:

def list
pipeline {
    agent none
    options {buildDiscarder(logRotator(daysToKeepStr: '7', numToKeepStr: '1'))}
    stages {
        stage('Create List') {
            agent {node 'nodename'}
            steps {
                script {
                    // you may create your list here, lets say reading from a file after checkout
                    list = ["Test-1", "Test-2", "Test-3", "Test-4", "Test-5"]
                }
            }
            post {
                cleanup {
                    cleanWs()
                }
            }
        }
        stage('Dynamic Stages') {
            agent {node 'nodename'}
            steps {
                script {
                    for(int i=0; i < list.size(); i++) {
                        stage(list[i]){
                            echo "Element: $i"
                        }
                    }
                }
            }
            post {
                cleanup {
                    cleanWs()
                }
            }
        }
    }
}

Это приведет к: динамическим последовательным этапам