TL; DR有没有办法将代码从本地存储库导入Jenkinsfile
(load
步骤除外)?
我经历过,对于复杂的版本,Jenkinsfile
变得笨重而且不易维护
既然构建作业是代码,那么使用与其他代码相同的方法会很棒。
也就是说,我想将它分成更小(更易于维护)的单元和单元测试它们。
load
Step:允许从存储库加载groovy 脚本
但是,文件必须是脚本而不是“完整”的groovy类,这使得很多文件或类很难相互依赖。例如继承是不可能的
另外,在Jenkins作业上执行replay时不会显示这些文件,这使得它们难以开发和调试。Jenkinsfile
相同的存储库中创建共享库,并将此库导入Jenkinsfile
?与为shared libs描述的目录结构类似,我希望在单个存储库中包含以下。
(root)
+- someModule
| +- ...
+- jenkins # Classes/Scripts used by Jenkins in a separate module
| +- src # Groovy source files
| +- org
| +- foo
| +- Bar.groovy # for org.foo.Bar class
| +- test # Groovy test files
| +- org
| +- foo
| +- BarTest.groovy # Test for org.foo.Bar class
| +- pom.xml or build.groovy # Build for local library
+- Jenkinsfile # Build "someModule", uses classes from "jenkins" module
答案 0 :(得分:5)
解决方法:
library identifier: 'shared-library@version', retriever: legacySCM(scm)
PR 37中当前采用的方法无法正常使用构建代理,并且无论如何仅适用于使用library
步骤的脚本,而不适用于@Library
注释。
顺便提一下,load
步骤 中加载的文件会出现在重播中。但是,您的脚本无法静态引用此类文件中定义的类型。换句话说,您可以模拟库vars/*.groovy
但不能模拟src/**/*.groovy
- 与当前PR 37相同的限制。
答案 1 :(得分:3)
我想这样做的正确方法是实现自定义SCMRetriever
。
但是,您可以使用以下hack:
假设您的本地仓库中的jenkins/vars/log.groovy
包含:
def info(message) {
echo "INFO: ${message}"
}
您的Jenkinsfile
可以使用jenkins/
步骤从library
目录加载该共享库:
node('node1') { // load library
checkout scm
// create new git repo inside jenkins subdirectory
sh('cd jenkins && git init && git add --all . && git commit -m init &> /dev/null')
def repoPath = sh(returnStdout: true, script: 'pwd').trim() + "/jenkins"
library identifier: 'local-lib@master', retriever: modernSCM([$class: 'GitSCMSource', remote: repoPath])
}
node('node2') {
stage('Build') {
log.info("called shared lib") // use the loaded library
}
}
答案 2 :(得分:3)
您可以查看我编写的插件,该插件可以使用repo的子目录,其中您的管道作为共享库:https://github.com/karolgil/SharedLibrary
在构建和安装它之后,您可以简单地将以下内容放入您的管道中:
@SharedLibrary('dir/in/repo') _
开始使用dir/in/repo
作为管道的共享库。
答案 3 :(得分:2)
想要做同样的事情并最终创造出来:
https://github.com/jenkinsci/workflow-cps-global-lib-plugin/pull/37
以下是我如何使用它:
https://github.com/syndesisio/syndesis-pipeline-library/blob/master/Jenkinsfile#L3
在我的情况下,我想创建一个实际上tests
存储库包含的管道库的Jenkins文件。
让我知道您的想法,并随时在PR上添加您的评论。
答案 4 :(得分:0)
如果您正在从SCM中检查管道(未嵌入Jenkins作业UI配置中),我发现Pawel的版本存在问题。这是我针对这些情况的版本:
node {
def jenkinsDir = sh(returnStdout: true, script: 'pwd').trim().replaceAll('(.*)(@[0-9]*$)', '$1') + "@script/jenkins"
sh("cd ${jenkinsDir} && if [ ! -d .git ]; then git init && git add --all . && git commit -m init; fi &> /dev/null")
library identifier: 'local-lib@master', retriever: modernSCM([$class: 'GitSCMSource', remote: jenkinsDir])
stage('Build') {
log.info("called shared lib") // use the loaded library
}
}
在这种情况下,管道本身在不同的工作空间(目录名称相同,但名称中带有@script
)中签出,而不是在其中执行管道本身(代码将在其中签出)的工作区中签出。也是如此)。
“ jenkins”目录仅在检出管道的工作空间中可用(至少具有最新版本的“ vars”文件夹),因为该管道尚未拉出并且是最新的(可能甚至在另一个分支中。
答案 5 :(得分:0)
我已经成功测试了具有两种协议(HTTPS和SSH)的GIT仓库的简单解决方法(我正在使用BitBucket)-只需按以下方式配置Jenkins作业(指向相同的存储库,但强制使用不同的获取方法):< / p>
在“分支源”中添加“通过SSH签出”选项
在管道库->源代码管理->项目存储库中使用HTTPS协议-例如像https:// ...
答案 6 :(得分:0)
是否有办法将代码从本地存储库导入到Jenkinsfile中(加载步骤除外)?
是否有一种方法(或解决方法)在与Jenkinsfile相同的存储库中创建共享库并将该库导入Jenkinsfile?
是的。只要按照规范观察 “共享库存储库的目录结构” ,那么它是绝对可行的,不需要任何解决方法即可使其工作。基本上,您的目录结构需要沿着以下几行进行调整:
+- src # Groovy source files
| +- org
| +- foo
| +- Bar.groovy # for org.foo.Bar class
+- vars
| +- foo.groovy # for global 'foo' variable
| +- foo.txt # help for 'foo' variable
+- resources # resource files (external libraries only)
| +- org
| +- foo
| +- bar.json # static helper data for org.foo.Bar
+- someModule
| +- ...
|
|
+- Jenkinsfile
此答案并非基于推测。尽管没有记录,但我已经将此模式应用到了多个项目和培训中,并且有效。无论如何,您都不需要修改工作配置。