Kal*_*ist 5 jenkins jenkins-pipeline
我有几个组件(带有自己的 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
}
}
Run Code Online (Sandbox Code Playgroud)
需要使用“包装器”管道,例如 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
}
}
}
Run Code Online (Sandbox Code Playgroud)
修改后的 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{}
Run Code Online (Sandbox Code Playgroud)
现在,我怀疑params对象(来自 Jenkinsfile 的属性)没有正确填充。例如
def buildInfoCommitId = config.commitId
.
.
.
println "buildInfoCommitId: "+buildInfoCommitId
Run Code Online (Sandbox Code Playgroud)
打印为空。
如何正确调用 wrapperPipeline?
注意:我是 Jenkins 管道和 Groovy 的新手 :)
因为这些是 Jenkins 参数,所以它们不在配置对象中。
您将访问 commitId 作为 params.commitId
如果您在调用 wrapperPipeline() 时在闭包中有某些内容,那么这些内容将在 config 对象中。例如
wrapperPipeline({
param="value"
})
Run Code Online (Sandbox Code Playgroud)
那么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
}
}
Run Code Online (Sandbox Code Playgroud)
然后在 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)
Run Code Online (Sandbox Code Playgroud)
然后,这允许您使用消除复杂性的 Maps,因此您可以例如(不是那样,因为您只使用 params.commitId)重新分配它。
wrapperPipeline ([
"commitId": params.commitId,
])
Run Code Online (Sandbox Code Playgroud)
这意味着config.commitId现在再次具有价值params.commitId
如果您需要更多详细信息,请告诉我。
TL;DR - 你应该使用 params 对象,因为你已经定义了参数。如果您确实开始通过共享 lib 调用传递参数,我将在闭包上使用映射。(需要一些最小的实现)
| 归档时间: |
|
| 查看次数: |
8470 次 |
| 最近记录: |