我想在流水线步骤中运行一个 job-dsl 脚本。一般来说,这应该是可能的,如 此处 所述。以下代码片段已添加到流水线步骤中:
当运行此流水线时,Jenkins会抱怨。
DotNetJob.groovy的内容如下,仅供测试目的:
我认为问题在于,管道作业和包含作业 DSL 的脚本位于不同的工作区。设置如下:
现在,实际代码存储库中的管道非常小。它只转发到共享库中的管道定义。
这个功能非常好用,因为全局管道库被隐式导入。这个dotNetStandardPipeline 包含了上面提到的步骤,尝试使用一个目标设置为与dotNetStandardPipeline本身在同一仓库中的DotNetJob.groovy脚本调用jobDsl管道步骤。
现在问题似乎是,在“代码仓库”的工作区执行管道,因此路径“src/breuer/jenkins/utils”不存在。
我如何知道脚本的真实位置,并指定一个作为目标的jobDsl,它本身存在于另一个仓库?或者我完全走错了吗?
编辑
经过进一步的调查,事实似乎是共享库存储库被检出到与“真实”工作区相邻的目录中,具有@libs后缀。因此,我认为使用以下方法是一个好主意:
很遗憾,这似乎完全破坏了某些东西,因为现在jenkins将在构建输出中抱怨以下消息:
看起来,即使我能确定groovy文件的位置,调用它仍然是不可能的?!
注意:当将src目录直接复制到工作区并设置目标参数为src/breuer/jenkins...等时,它可以工作。
这是否意味着,groovy脚本必须与jenkinsfile在同一个代码库中?
编辑2:
由于很难用言语解释我的计划结构和思想,我创建了一个小演示组织,在GitHub上有两个演示存储库。here你可以找到包含两个C#解决方案和jenkinsfile的源代码存储库。自述文件描述了CI集成的计划。
包含groovy脚本的CI库位于here 编辑3和结论
对于大多数来到这里的人,请查看mkobit提供的被接受的答案(感谢您的努力!)。特别是解决实际问题的方法非常有帮助。将job-dsl脚本放入资源中绝对是一个选项。
与此同时,我采取了另一种方法,并想通报一下。
我已经在jenkins上使用了“GitHub组织”作业。目标是使这个成为唯一手动创建的工作,通过代码(即通过Jenkinsfile)创建所有其他所需的工作。
我要关心的真正存储库之一是一个规模巨大的repo,从svn移动到git,其中包含约300个.Net解决方案。每个这些解决方案都应该由jenkins上的单独的作业构建。我们可以在管道内部执行此操作,但这意味着要在管道中拥有很多阶段,或者一开始就没有有关单独失败解决方案的信息。 因此,我必须为每个解决方案动态构建单独的工作。
代码仓库本身不应该被大量的Jenkins相关内容污染,因此我想严格分离这两个东西。
现在,我决定手动创建一个自由风格任务作为种子任务,并添加一些参数(工作区、项目、分支等)。
然后,流水线将触发种子任务的构建,种子任务将使用所需信息运行job-dsl。
在流水线中完成这个阶段后,流水线将触发所需任务的构建。
这可能不是最优雅的解决方案,但通过这种方法,我可以实现一个完全自动化、在代码中定义的Jenkins环境,只需要手动创建两个任务。
stage('Add new jobs') {
steps {
echo 'Scanning...'
jobDsl(additionalClasspath: 'src/breuer/jenkins/utils', removedJobAction: 'DELETE', removedViewAction: 'DELETE',
targets: 'src/breuer/jenkins/utils/DotNetJob.groovy', unstableOnDeprecation: true)
}
}
当运行此流水线时,Jenkins会抱怨。
ERROR: no Job DSL script(s) found at src/breuer/jenkins/utils/DotNetJob.groovy
Finished: FAILURE
DotNetJob.groovy的内容如下,仅供测试目的:
#!/usr/bin/env groovy
package breuer.jenkins.utils
import javaposse.jobdsl.dsl.Job
def solutions = findFiles glob: '**/*.sln'
echo "Solution count: ${solutions.size()}"
job("TestDotNet") {
steps {
shell 'echo Hello from new DotNet job'
}
}
我认为问题在于,管道作业和包含作业 DSL 的脚本位于不同的工作区。设置如下:
- 1个 GitHub 组织
- 该组织内有2个存储库
- 1个存储库包含用 Groovy 代码编写的共享库/作业构建器
- 1个存储库包含多个 .Net 解决方案,并在根目录中具有 Jenkinsfile
现在,实际代码存储库中的管道非常小。它只转发到共享库中的管道定义。
#!/usr/bin/env groovy
dotNetStandardPipeline {
message = "Hello World!"
}
这个功能非常好用,因为全局管道库被隐式导入。这个dotNetStandardPipeline 包含了上面提到的步骤,尝试使用一个目标设置为与dotNetStandardPipeline本身在同一仓库中的DotNetJob.groovy脚本调用jobDsl管道步骤。
现在问题似乎是,在“代码仓库”的工作区执行管道,因此路径“src/breuer/jenkins/utils”不存在。
我如何知道脚本的真实位置,并指定一个作为目标的jobDsl,它本身存在于另一个仓库?或者我完全走错了吗?
编辑
经过进一步的调查,事实似乎是共享库存储库被检出到与“真实”工作区相邻的目录中,具有@libs后缀。因此,我认为使用以下方法是一个好主意:
script {
def wsName = "${WORKSPACE}".split("\\\\")[ -1 ]
echo "wsName: ${wsName}"
echo "RelDir: ../${wsName}@libs/breuer-jenkins-lib/src/breuer/jenkins/utils/DotNetJob.groovy"
jobDsl(removedJobAction: 'DELETE', removedViewAction: 'DELETE',
targets: "../${wsName}@libs/breuer-jenkins-lib/src/breuer/jenkins/utils/DotNetJob.groovy", unstableOnDeprecation: true)
}
很遗憾,这似乎完全破坏了某些东西,因为现在jenkins将在构建输出中抱怨以下消息:
java.nio.file.AccessDeniedException: D:\Road to Git\Jenkins\JenkinsGit\workspace\t_TestCIIntegration_develop-RKLAJXSET2S232SE6RNISESVW75KUNU4E3CPSAAP42MHZAGO6Z2A\.git
at sun.nio.fs.WindowsException.translateToIOException(Unknown Source)
at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
at sun.nio.fs.WindowsFileSystemProvider.newByteChannel(Unknown Source)
at java.nio.file.Files.newByteChannel(Unknown Source)
at java.nio.file.Files.newByteChannel(Unknown Source)
at java.nio.file.spi.FileSystemProvider.newInputStream(Unknown Source)
at java.nio.file.Files.newInputStream(Unknown Source)
at hudson.FilePath.read(FilePath.java:1771)
at hudson.FilePath$read$8.call(Unknown Source)
at javaposse.jobdsl.plugin.ScriptRequestGenerator.readFile(ScriptRequestGenerator.groovy:103)
看起来,即使我能确定groovy文件的位置,调用它仍然是不可能的?!
注意:当将src目录直接复制到工作区并设置目标参数为src/breuer/jenkins...等时,它可以工作。
这是否意味着,groovy脚本必须与jenkinsfile在同一个代码库中?
编辑2:
由于很难用言语解释我的计划结构和思想,我创建了一个小演示组织,在GitHub上有两个演示存储库。here你可以找到包含两个C#解决方案和jenkinsfile的源代码存储库。自述文件描述了CI集成的计划。
包含groovy脚本的CI库位于here 编辑3和结论
对于大多数来到这里的人,请查看mkobit提供的被接受的答案(感谢您的努力!)。特别是解决实际问题的方法非常有帮助。将job-dsl脚本放入资源中绝对是一个选项。
与此同时,我采取了另一种方法,并想通报一下。
我已经在jenkins上使用了“GitHub组织”作业。目标是使这个成为唯一手动创建的工作,通过代码(即通过Jenkinsfile)创建所有其他所需的工作。
我要关心的真正存储库之一是一个规模巨大的repo,从svn移动到git,其中包含约300个.Net解决方案。每个这些解决方案都应该由jenkins上的单独的作业构建。我们可以在管道内部执行此操作,但这意味着要在管道中拥有很多阶段,或者一开始就没有有关单独失败解决方案的信息。 因此,我必须为每个解决方案动态构建单独的工作。
代码仓库本身不应该被大量的Jenkins相关内容污染,因此我想严格分离这两个东西。
现在,我决定手动创建一个自由风格任务作为种子任务,并添加一些参数(工作区、项目、分支等)。
然后,流水线将触发种子任务的构建,种子任务将使用所需信息运行job-dsl。
在流水线中完成这个阶段后,流水线将触发所需任务的构建。
这可能不是最优雅的解决方案,但通过这种方法,我可以实现一个完全自动化、在代码中定义的Jenkins环境,只需要手动创建两个任务。
jobDsl
的相对路径来定位它,而不是直接使用jenkins-pipeline DSL呢? - Matt Schucharddef myJob = job('jobName)
这样的操作。您只能执行步骤jobDsl
,该步骤可以获取脚本文本或要执行的目标... - Tobias BreuerjobDsl
步骤),以及使用什么内容。此外,你是说你的jobDsl
脚本与全局管道库位于同一源代码中吗? - mkobit