声明式Jenkins管道中多个节点上的并行签出

时间:2019-05-14 07:39:38

标签: jenkins jenkins-declarative-pipeline

我正在开发一个由Gitlab触发的用于CI构建的声明性Jenkins管道。我现在所拥有的:


// variable definitions

pipeline {
    agent none

    parameters {
            string(defaultValue: 'develop',
                description: 'Commit ID or branch name to build', 
                name: 'branch', 
                trim: false)
    }

    stages {
        stage('Checkout') {
            parallel {
                stage ('Windows') {
                    agent {
                        label 'build' && 'windows'
                    }

                    steps {
                        script {

                            def checkout_ext = [[$class: 'CleanCheckout'],
                                                [$class: 'CleanBeforeCheckout']] // calls git clean -fdx and git reset --hard

                            if (env.gitlabActionType == "MERGE"){   
                                  checkout_ext.add([$class: 'PreBuildMerge', 
                                                    options: [ mergeRemote: "origin",
                                                              mergeTarget: "${env.gitlabTargetBranch}"]])
                            }
                        }

                        checkout([
                                $class: 'GitSCM', 
                                branches: [[name: "${params.branch}"]],
                                userRemoteConfigs: [[ url: "${git_url}",                                          credentialsId: "${git_credentials_id}" ]],
                                extensions:   checkout_ext 
                        ])
                    }
                }

                stage('Linux') {
                    agent {
                        label 'build' && 'linux'
                    }
                    steps {
                        script {

                            def checkout_ext = [[$class: 'CleanCheckout'], 
                                                [$class: 'CleanBeforeCheckout']] // calls git clean -fdx and git reset --hard

                            if (env.gitlabActionType == "MERGE"){   
                               checkout_ext.add([$class: 'PreBuildMerge', 
                                                 options: [ mergeRemote: "origin",
                                                 mergeTarget: "${env.gitlabTargetBranch}"]])
                            }
                        }

                        checkout([
                                $class: 'GitSCM', 
                                branches: [[name: "${params.branch}"]],
                                userRemoteConfigs: [[ url: "${git_url}", credentialsId: "${git_credentials_id}"]],
                                extensions:   checkout_ext 
                        ])
                    }
                }
            }
        }
    }
}

结帐阶段有些复杂。如果gitlabActionTypeMERGE,则首先尝试合并到目标分支中,以确保合并请求不会破坏其中的任何内容。

两个操作系统的此代码相同。我想避免代码重复,但是无法找出正确的语法。

我尝试将结帐步骤的定义移至全局变量,但是出现语法错误。


def checkout_step = {
    script {
   ...
    }
    checkout (... )
}

pipeline {
...
   stages {
        stage('Checkout') {
            parallel {
                stage ('Windows') {
                    agent {
                        label 'build' && 'windows'
                    }

                    steps {
                        checkout_step
                    }
                }
                stage ('Linux') {
                    agent {
                        label 'build' && 'linux'
                    }

                    steps {
                        checkout_step
                    }
                }
            }
        }
    }
}

如果添加steps,也会出现错误:


def checkout_step = steps {
    script {
   ...
    }
    checkout (... )
}

pipeline {
...
   stages {
        stage('Checkout') {
            parallel {
                stage ('Windows') {
                    agent {
                        label 'build' && 'windows'
                    }

                    checkout_step

                }
                stage ('Linux') {
                    agent {
                        label 'build' && 'linux'
                    }

                    checkout_step

                }
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

已找到solution here


git_url = "git@gitserver.corp.com:group/repo.git"
git_credentials_id = 'aaaaaaa-bbbb-cccc-dddd-eefefefefef'


def checkout_tasks(os_labels) {
    tasks = [:]

    for (int i = 0; i < os_labels.size(); i++) {
        def os = os_labels[i]
        tasks["${os}"] = {
            node("build && ${os}"){

                def checkout_ext = [[$class: 'CleanCheckout'], [$class: 'CleanBeforeCheckout']] // calls git clean -fdx and git reset --hard

                if (env.gitlabActionType == "MERGE"){   
                    checkout_ext.add([
                            $class: 'PreBuildMerge', 
                            options: [ 
                            mergeRemote: "origin", 
                            mergeTarget: "${env.gitlabTargetBranch}" 
                            ]
                    ])
                         /* using this extension requires .gitconfig with section [user for Jenkins]
                            Example
                            [user]
                            email = jenkins@builder
                            name = Jenkins

                          */
                }

                checkout([
                        $class: 'GitSCM', 
                        branches: [[name: "${params.branch}"]],
                        userRemoteConfigs: [[
                            url: "${git_url}", 
                            credentialsId: "${git_credentials_id}"
                        ]],
                        extensions:  checkout_ext 
                ])

            }
        }
    }
    return tasks
}


pipeline {
    agent none

    parameters {
        string(defaultValue: 'develop',
               description: 'Commit ID or branch name to build', 
               name: 'branch', 
               trim: false)
    }

    stages {
        stage('Checkout') {
            steps {
                script {
                    def OSes = ["windows", "linux"]
                    parallel checkout_tasks(OSes)
                }
            }
        }
   }
}

同样重要的是声明git_urlgit_credentials_id不包含def,以便函数可以读取它们。

this question

中的更多详细信息