jenkins - 多个节点上的声明式 Jenkins 管道中的并行结帐
问题描述
我正在为 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
}
}
}
}
}
}
如果 add 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)
}
}
}
}
}
git_url
声明and git_credentials_id
without也很重要def
,以便函数可以读取它们。
这个问题的更多细节
推荐阅读
- html - 在 laravel 6 的同一页面上获取显示任务的完整详细信息
- javascript - 两个数组的 p5 碰撞检测不起作用
- angular - 如何在分组行上设置字符串值
- python - 在 Keras 的图形执行时将我的张量调整为另一个张量的大小
- android - 如何将浮动按钮固定在屏幕的右下角而不固定在布局上
- java - 从 blob 读取数据时创建损坏的 docx 文件
- apache-spark - 在 ADLS Gen2 的顶部使用 Delta 湖中的非托管表
- java - 我有一个导航抽屉,想打开另一个孤立的片段
- django - 从 orderitem drf 创建订单
- c# - 在 c# 中连接到 SQL 'Connection is invalid' 错误