在多个节点上的声明性 Jenkins 管道中并行检出
Parallel checkout in declarative Jenkins pipeline on multiple nodes
我正在为 CI 构建开发声明性 Jenkins 管道,从 Gitlab 触发。我现在拥有的:
// 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
])
}
}
}
}
}
}
结帐阶段有些复杂。如果 gitlabActionType
是 MERGE
,则首先尝试合并到目标分支,以确保合并请求不会破坏其中的任何内容。
此代码对于两个操作系统都是相同的。我想避免代码重复,但无法找出正确的语法。
我尝试将结帐步骤的定义移至全局变量,但出现语法错误。
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
}
}
}
}
}
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)
}
}
}
}
}
在没有 def
的情况下声明 git_url
和 git_credentials_id
也很重要,以便函数可以读取它们。
this question
中有更多详细信息
我正在为 CI 构建开发声明性 Jenkins 管道,从 Gitlab 触发。我现在拥有的:
// 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
])
}
}
}
}
}
}
结帐阶段有些复杂。如果 gitlabActionType
是 MERGE
,则首先尝试合并到目标分支,以确保合并请求不会破坏其中的任何内容。
此代码对于两个操作系统都是相同的。我想避免代码重复,但无法找出正确的语法。
我尝试将结帐步骤的定义移至全局变量,但出现语法错误。
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
}
}
}
}
}
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)
}
}
}
}
}
在没有 def
的情况下声明 git_url
和 git_credentials_id
也很重要,以便函数可以读取它们。
this question
中有更多详细信息