从同一存储库

时间:2017-09-14 08:16:11

标签: jenkins groovy shared-libraries jenkins-pipeline

TL; DR有没有办法将代码从本地存储库导入Jenkinsfile load步骤除外)?

为什么?

我经历过,对于复杂的版本,Jenkinsfile变得笨重而且不易维护 既然构建作业是代码,那么使用与其他代码相同的方法会很棒。 也就是说,我想将它分成更小(更易于维护)的单元和单元测试它们。

我尝试了什么

  • shared libraries:允许将我们的Jenkins管道逻辑划分为单独模块中的较小文件,甚至对其进行单元测试。
    但是,它们需要位于不同的存储库中(如果不在GitHub上)必须配置到Jenkins中。
  • 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

7 个答案:

答案 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

此答案并非基于推测。尽管没有记录,但我已经将此模式应用到了多个项目和培训中,并且有效。无论如何,您都不需要修改工作配置。