gpt4 book ai didi

jenkins - 将参数从 Jenkinsfile 传递到共享库

转载 作者:行者123 更新时间:2023-12-03 16:24:10 26 4
gpt4 key购买 nike

我有几个组件(带有自己的 Bitbucket 存储库的代码项目),每个组件都有一个 Jenkinsfile,如下所示:

properties([parameters([string(defaultValue: "", description: "List of components", name: 'componentsToUpdate'),
string(defaultValue: "refs%2Fheads%2Fproject%2Fintegration", description: "BuildInfo CommitID", name: 'commitId'),
string(defaultValue: "", description: "Tag to release, e.g. 1.1.0-integration", name: 'releaseTag'),
string(defaultValue: "", description: "Forked buildInfo repo. Be aware right commit ID!!!", name: 'fork')]),
[$class: 'BuildDiscarderProperty', strategy: [$class: 'LogRotator', artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '7', numToKeepStr: '5']],
disableConcurrentBuilds()])

@Library('jenkins-shared-stages')

import mergePipeline
import releasePipeline
import ripplePipeline
import componentPipeline


def branchName = env.BRANCH_NAME
def rewriteDependencies = ""
def returnValue = null
def forkedRepo = params.fork
def buildInfoCommitId = params.commitId
def tagToRelease = params.releaseTag
println "buildInfoCommitId: " + buildInfoCommitId
if(params.componentsToUpdate) {
rewriteDependencies = params.componentsToUpdate
}

if (branchName == "project/integration") {
mergePipeline {
}
} else if (branchName == 'master') {
releasePipeline {
releaseTag = tagToRelease
}
} else {
returnValue = componentPipeline {
componentsToUpdate = rewriteDependencies
commitId = buildInfoCommitId
runOnForkedRepo = forkedRepo
}

rewriteDependencies = rewriteDependencies.isEmpty() ? returnValue : rewriteDependencies + "," + returnValue
println "WHAT is rewriteDependencies? " + rewriteDependencies
println "The return value: " + returnValue
ripplePipeline {
commitId = buildInfoCommitId
componentName = returnValue
runOnForkedRepo = forkedRepo
componentsToUpdate = rewriteDependencies
}
}

需要使用“包装器”管道,例如 wrapperPipeline.groovy:
import mergePipeline
import releasePipeline
import ripplePipeline
import componentPipeline
import org.slf4j.Logger
import org.slf4j.LoggerFactory

def call(body) {

final Logger logger = LoggerFactory.getLogger(wrapperPipeline)

def config = [:]
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = config
body()

// Assuming we have multibranch pipeline job or defined branch name in the env
def branchName = env.BRANCH_NAME
// There is a bug in the Jenkins it will pass a string "null" as a gradle build parameter instead of NULL object if there is
// empty parameter has been passed!!!
def rewriteDependencies = ""
def returnValue = null
def forkedRepo = config.runOnForkedRepo
def buildInfoCommitId = config.commitId
def tagToRelease = config.releaseTag

def globalVars = new se.GlobalVars()
def notifyHandler = new se.NotifyHandler()

node(globalVars.getAgent('buildAgent')) {
def PIPELINE_NAME = "wrapperPipeline"

try {
logger.info("The buildInfoCommitId is {}", buildInfoCommitId)
logger.info("Branch name: {}", branchName)

println "buildInfoCommitId: "+buildInfoCommitId
println"Branch name: "+branchName

if (config.componentsToUpdate) {
rewriteDependencies = config.componentsToUpdate
}

// keep the same integration pipeline for the master branch for now
if (branchName == "project/integration") {
logger.info("Invoking mergePipeline")
println "Invoking mergePipeline"
mergePipeline {
}
} else if (branchName == 'master') {
logger.info("Invoking releasePipeline")
println "Invoking releasePipeline"
releasePipeline {
releaseTag = tagToRelease
}
} else {
logger.info("Invoking componentPipeline")
println "Invoking componentPipeline"

returnValue = componentPipeline {
componentsToUpdate = rewriteDependencies
commitId = buildInfoCommitId
runOnForkedRepo = forkedRepo
}
logger.info("Component pipeline has returned {}", returnValue)
println "Component pipeline has returned"+returnValue

// We need to provide new version of the component to the Ripple builds
rewriteDependencies = rewriteDependencies.isEmpty() ? returnValue : rewriteDependencies + "," + returnValue
logger.info("rewriteDependencies: {}", rewriteDependencies)
println "The return value: " + returnValue
ripplePipeline {
commitId = buildInfoCommitId
componentName = returnValue
runOnForkedRepo = forkedRepo
componentsToUpdate = rewriteDependencies
}
}
}
catch (err) {
def build_status = "Exception ${err.message} in build ${env.BUILD_ID}"
logger.error(build_status,err)
notifyHandler.NotifyFail(build_status, PIPELINE_NAME)

throw err
}

}
}

修改后的 Jenkinsfile:
properties([parameters([string(defaultValue: "", description: "List of components", name: 'componentsToUpdate'),
string(defaultValue: "refs%2Fheads%2Fproject%2Fintegration", description: "BuildInfo CommitID", name: 'commitId'),
string(defaultValue: "", description: "Tag to release, e.g. 1.1.0-integration", name: 'releaseTag'),
string(defaultValue: "", description: "Forked buildInfo repo. Be aware right commit ID!!!", name: 'fork')]),
[$class: 'BuildDiscarderProperty', strategy: [$class: 'LogRotator', artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '7', numToKeepStr: '5']],
disableConcurrentBuilds()])

@Library('jenkins-shared-stages@integration/CICD-959-wrapper-pipeline-for-the-jenkinsfile') _

import wrapperPipeline

wrapperPipeline{}

现在,我怀疑 参数 对象(来自 Jenkinsfile 的属性)未正确填充。例如
def buildInfoCommitId = config.commitId
.
.
.
println "buildInfoCommitId: "+buildInfoCommitId

打印为空。

如何正确调用 wrapperPipeline?

注意:我是 Jenkins 管道和 Groovy 的新手 :)

最佳答案

因为这些是 Jenkins 参数,所以它们不在配置对象中。

您将访问 commitId 为 params.commitId
如果您在调用 wrapperPipeline() 时在闭包中有某些内容,那么这些内容将在 config 对象中。例如

wrapperPipeline({
param="value"
})

然后 config.param将导致 "value"
但是,作为建议,我建议在调用共享库中 vars/下存储的库时避免使用闭包。见 http://groovy-lang.org/closures.html什么是闭包。问题的关键是,它们相当复杂,如果由于闭包实例化而最终尝试传入动态变量,则可能会引入一些问题。 (他们有自己的位置,但对于简单的事情,我认为避免更好)

我建议改为实现一个辅助函数,该函数将允许您使用映射或闭包来调用共享库。

在 src 路径下添加一个名为 buildConfig 的共享库:
package net.my.jenkins.workflow
import com.cloudbees.groovy.cps.NonCPS

class BuildConfig implements Serializable {
static Map resolve(def body = [:]) {

Map config = [:]
config = body
if (body in Map) {
config = body
} else if (body in Closure) {
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = config
body()
} else {
throw new Exception(sprintf("Unsupported build config type:%s", [config.getClass()]))
}
return config
}
}

然后在 vars/下的共享库中以
import net.my.jenkins.workflow.BuildConfig

def call(def body = [:]) {
// evaluate the body block, and collect configuration into the object
config = BuildConfig.resolve(body)

然后,这允许您使用消除复杂性的 Maps,因此您可以例如(不是那样,因为您只使用 params.commitId)重新分配它。
wrapperPipeline ([
"commitId": params.commitId,
])

这又意味着 config.commitId现在的值为 params.commitId
如果您需要更多详细信息,请告诉我。

TL;DR - 你应该使用 params 对象,因为你已经定义了参数。
如果您确实开始通过共享 lib 调用传递参数,我将在闭包上使用映射。 (需要一些最小的实现)

关于jenkins - 将参数从 Jenkinsfile 传递到共享库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54124966/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com