Rob*_*der 2 jenkins jenkins-pipeline jenkins-declarative-pipeline
我已经尝试了一段时间,开始努力将我们的自由风格项目转移到管道上.为此,我觉得最好建立一个共享库,因为我们的大多数构建都是一样的.我通读了Jenkins的这篇博客文章.我想出了以下内容
// vars/buildGitWebProject.groovy
def call(body) {
def args= [:]
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = args
body()
pipeline {
agent {
node {
label 'master'
customWorkspace "c:\\jenkins_repos\\${args.repositoryName}\\${args.branchName}"
}
}
environment {
REPOSITORY_NAME = "${args.repositoryName}"
BRANCH_NAME = "${args.branchName}"
SOLUTION_NAME = "${args.solutionName}"
}
options {
buildDiscarder(logRotator(numToKeepStr: '3'))
skipStagesAfterUnstable()
timestamps()
}
stages {
stage("checkout") {
steps {
script{
assert REPOSITORY_NAME != null : "repositoryName is null. Please include it in configuration."
assert BRANCH_NAME != null : "branchName is null. Please include it in configuration."
assert SOLUTION_NAME != null : "solutionName is null. Please include it in configuration."
}
echo "building with ${REPOSITORY_NAME}"
echo "building with ${BRANCH_NAME}"
echo "building with ${SOLUTION_NAME}"
checkoutFromGitWeb(args)
}
}
stage('build and test') {
steps {
executeRake(
"set_assembly_to_current_version",
"build_solution[$args.solutionName, Release, Any CPU]",
"copy_to_deployment_folder",
"execute_dev_dropkick"
)
}
}
}
post {
always {
sendEmail(args)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
在我的管道项目中,我将Pipeline配置为使用Pipeline脚本,脚本如下:
buildGitWebProject {
repositoryName:'my-git-repo'
branchName: 'qa'
solutionName: 'my_csharp_solution.sln'
emailTo='testuser@domain.com'
}
Run Code Online (Sandbox Code Playgroud)
我已尝试使用和不使用环境块,但结果最终与每个参数的值为"null"相同.奇怪的是,代码的脚本部分也没有使构建失败......所以不确定这有什么问题.回声部分也显示为空.我究竟做错了什么?
你的Closure身体没有按照你期望/相信它的方式行事.
在您的方法开始时,您有:
def call(body) {
def args= [:]
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = args
body()
Run Code Online (Sandbox Code Playgroud)
你的通话机构是:
buildGitWebProject {
repositoryName:'my-git-repo'
branchName: 'qa'
solutionName: 'my_csharp_solution.sln'
emailTo='testuser@domain.com'
}
Run Code Online (Sandbox Code Playgroud)
让我们来试试这个.
如果你在方法println(args)之后添加一个,你会看到如下内容:body()call(body)
[emailTo:testuser@domain.com]
但是,只有一个值得到了设定.到底是怎么回事?
这里有几点需要了解:
delegate一个Closure做什么?repositoryName:'my-git-repo'不做任何事情?emailTo='testuser@domain.com'在地图中设置属性?设置
delegate一个Closure做什么?
这一点大多是直截了当的,但我认为这有助于理解.Closure是强大的,是Groovy的瑞士军刀.在delegate本质上设置什么this是的身体Closure.您也使用了resolveStrategyof Closure.DELEGATE_FIRST,因此委托中的方法和属性可以在委托中进行搜索,然后从封闭范围(所有者)进行检查 - 请参阅Javadoc以获得深入的解释.如果调用类似的方法size(),put(...),entrySet(),等等,它们都是第一次呼吁delegate.财产访问也是如此.
为什么
repositoryName:'my-git-repo'不做任何事情?
这似乎是一个Groovy地图文字,但事实并非如此.这些实际上是标签语句.如果你用方括号包围它,[repositoryName:'my-git-repo']那么就像地图文字一样.但是,这就是你在那里所做的一切 - 创建一个地图文字.我们希望确保在这些对象中使用这些对象Closure
为什么要
emailTo='testuser@domain.com'在地图中设置属性?
这是使用Groovy 的map属性表示法功能.如前所述,你已经设置delegate了Closureto def args= [:],这是一个Map.您还可以设置resolveStrategy的Closure.DELEGATE_FIRST.这使您emailTo='testuser@domain.com'可以调用args,这就是将emailTo键设置为值的原因.这相当于打电话args.emailTo='testuser@domain.com'.
那么,你如何解决这个问题呢?
如果要保持Closure语法方法,可以将调用主体更改为在委派args映射中实际存储值的任何内容:
buildGitWebProject {
repositoryName = 'my-git-repo'
branchName = 'qa'
solutionName = 'my_csharp_solution.sln'
emailTo = 'testuser@domain.com'
}
buildGitWebProject {
put('repositoryName', 'my-git-repo')
put('branchName', 'qa')
put('solutionName', 'my_csharp_solution.sln')
put('emailTo', 'testuser@domain.com')
}
buildGitWebProject {
delegate.repositoryName = 'my-git-repo'
delegate.branchName = 'qa'
delegate.solutionName = 'my_csharp_solution.sln'
delegate.emailTo = 'testuser@domain.com'
}
buildGitWebProject {
// example of Map literal where the square brackets are not needed
putAll(
repositoryName:'my-git-repo',
branchName: 'qa',
solutionName: 'my_csharp_solution.sln',
emailTo: 'testuser@domain.com'
)
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是让你call把它Map作为一个参数并删除你的Closure.
def call(Map args) {
// no more args and delegates needed right now
}
Run Code Online (Sandbox Code Playgroud)
buildGitWebProject(
repositoryName: 'my-git-repo',
branchName: 'qa',
solutionName: 'my_csharp_solution.sln',
emailTo: 'testuser@domain.com'
)
Run Code Online (Sandbox Code Playgroud)
您还可以使用其他一些方法对API进行建模,这取决于您要提供的UX.
关于共享库代码中声明性管道的旁注:
值得记住共享库中声明性管道的局限性.看起来你已经在做了vars,但我只是为了完整性而添加它.在文档的最后说明:
到目前为止,只能
pipeline在共享库中定义整个s.这vars/*.groovy只能在call方法中完成,并且只能在方法中完成.在单个构建中只能执行一个Declarative Pipeline,如果您尝试执行第二个,那么构建将因此失败.
| 归档时间: |
|
| 查看次数: |
1135 次 |
| 最近记录: |