使用共享库进行扩展

随着一个组织中越来越多的项目采用了Pipeline,常见的模式很可能会出现。通常,在不同的项目之间共享管道的部分是有用的,以减少冗余并保持代码“DRY”

Pipeline支持创建“共享库”,这些库可以在外部源代码控制存储库中定义并加载到现有的管道中。

定义共享库

共享库由名称、源代码检索方法(如SCM)和默认版本定义。该名称应为短标识符,因为它将在脚本中使用。

版本可以是SCM所理解的任何内容;例如,分支、标签和提交散列都可以在Git中工作。您还可以声明脚本是否需要显式请求该库(详细内容如下),或者是否默认存在该库。此外,如果您在Jenkins配置中指定了一个版本,您可以阻止脚本选择必威国际有限公司不同的的版本。

指定SCM的最好方法是使用SCM插件,该插件已经被特别更新,以支持一个新的API来检出任意命名的版本(现代供应链管理选项)。在撰写本文时,最新版本的Git和Subversion插件支持这种模式;其他人应该遵循。

如果您的SCM插件尚未集成,您可以选择传统供应链管理选择任何提供的东西。在这种情况下,您需要包括${library.yourLibName.version}在SCM配置的某个地方,以便在签出期间插件将扩展此变量以选择所需的版本存储库URLsvnserver /项目/ $ {library.yourLibName.version}然后使用诸如树干分支机构/发展标签/1.0

目录结构

共享库的目录结构如下:

(root)+-src#Groovy源文件|+-org |+-foo |+-Bar.Groovy#用于org.foo.Bar类+-vars |+-foo.Groovy#用于全局“foo”变量|+-foo.txt#“foo”变量的帮助+-resources#资源文件(仅外部库)124+-org 124+-foo |-Bar.json#用于静态数据|

src目录应该看起来像标准的Java源目录结构。在执行pipeline时,将此目录添加到类路径中。

瓦尔斯目录存放在管道中作为变量公开的脚本文件。文件的名称是管道中变量的名称。如果你有一个文件叫var / log.groovy有一个函数def信息(消息)…在它里面,你可以像这样访问这个函数log.info“hello world”在进行中您可以在这个文件中放入任意多的函数。阅读下面的例子和选项。

每个的基本名称B.groovy文件通常应该是一个Groovy (~ Java)标识符camelCased.匹配的. txt,如果存在,可以包含文档,通过系统的配置进行处理标记格式化程序(所以可能真的是HTML、降价等等,尽管. txt此文档将仅在全局变量引用从导入共享库的Pipeline作业的导航侧栏中访问的页面。此外,在生成共享库文档之前,这些作业必须成功运行一次。

这些目录中的Groovy源文件得到了与Scripted Pipeline中相同的“CPS转换”。

一个资源目录允许libraryResource从外部库加载相关的非groovy文件。目前内部库不支持此特性。

根目录下的其他目录为将来的增强保留。

全球共享库

有几个地方可以定义共享库,具体取决于用例。管理Jenki必威国际有限公司ns»配置系统»全局管道库可以配置尽可能多的库。

添加一个全局管道库">
            </div>
           </div>
           <div class=

因为这些库是全局可用的,所以系统中的任何管道都可以利用这些库中实现的功能。

这些库被认为是“可信的”:它们可以运行Java、Groovy、Jenkins内部api、Jenkins插件或第三方库中的任何方法。必威国际有限公司这允许您定义库,将单个不安全的api封装在高级包装器中,以便从任何管道安全使用。注意,任何能够将提交推入这个SCM存储库的人都可以获得对Jenkins的无限访问权必威国际有限公司.你需要总体/ RunScripts配置这些库的权限(通常会授予Jenkins管理员)。必威国际有限公司

目录级共享库

创建的任何文件夹都可以具有与之关联的共享库。这种机制允许将特定库的作用域限定到文件夹或子文件夹中的所有pipeline。

基于文件夹的库不被认为是“可信的”:它们像典型的管道一样在Groovy沙箱中运行。

自动共享库

其他插件可能会添加动态定义库的方法。例如,GitHub分支源插件提供了一个“GitHub组织文件夹”项,允许脚本使用不受信任的库,例如github.com/someorg/somerepo无需任何额外配置。在这种情况下,指定的GitHub存储库将从主人分支,使用匿名签出。

使用图书馆

共享库标记隐式加载允许管道立即使用任何此类库定义的类或全局变量。要访问其他共享库,请使用必威国际有限公司Jenkinsfile需要使用@Library注释,指定库的名称:

配置全局管道库">
           </div>
          </div>
          <div class=
@Librarymy-shared-library) _/*使用版本说明符,如分支、标记等*/@Library我的共享-library@1.0) _/*用一条语句访问多个库*/@Library([my-shared-libraryotherlib@abc1234) _

注释可以位于脚本中Groovy允许注释的任何位置src /目录),通常注释在进口声明:

@Librarysomelib进口com.mycorp.pipeline.somelib.UsefulClass

对于只定义全局变量的共享库(var /),或必威国际有限公司Jenkinsfile它只需要一个全局变量注释模式@Library (my-shared-library) _可能对保持代码简洁有用。在本质上,代替了不必要的注释进口声明中,符号_是注释。

不推荐进口一个全局变量/函数,因为这将迫使编译器将字段和方法解释为静态即使他们想成为实例。在这种情况下,Groovy编译器会产生令人困惑的错误消息。

过程中解析和加载库汇编在脚本开始执行之前。这允许Groovy编译器理解静态类型检查中使用的符号的含义,并允许它们在脚本的类型声明中使用,例如:

@Librarysomelib进口com.mycorp.pipeline.somelib.HelperintuseSomeLib(Helper Helper) {Helper .prepare()返回helper.count()}echo useSomeLib(辅助(一些文本))

然而,全局变量在运行时解析。

动态加载库

版本2.7管道:共享Groovy库插件中,有一个新选项用于在脚本中加载(非隐式)库:a图书馆加载库的步骤动态,在构建期间的任何时候。

如果您只对使用全局变量/函数感兴趣(从var /目录),语法非常简单:

图书馆my-shared-library

此后,脚本将可访问库中的任何全局变量。

使用来自src /Directory也有可能,但更棘手。而@Library注释在编译之前准备脚本的“类路径”图书馆步骤中遇到的脚本已被编译。因此你不能进口或者“静态地”引用库中的类型。

但是,可以动态地使用库类(不需要类型检查),通过返回值的全限定名访问它们图书馆的一步。静态方法可以使用类似java的语法调用:

图书馆(my-shared-library).com.mycorp.pipeline.Utils.someStaticMethod()

你也可以访问静态字段,并调用构造函数静态方法命名

defuseSomeLib(辅助){//动态:不能声明为Helperhelper.prepare ()返回helper.count()}def自由=库(my-shared-library) .com.mycorp.pipeline//预选择包回声useSomeLib (lib.Helper.new (lib.Constants.SOME_TEXT))

库版本

例如,当勾选“隐式加载”时,或者当管道仅通过名称引用库时,将使用配置的共享库的“默认版本”@Library (my-shared-library) _.如果“默认版本”为定义时,管道必须指定版本,例如@Library (my-shared-library@master) _

如果在共享库的配置中启用了“允许覆盖默认版本”,则可以使用@Library注释还可以覆盖为库定义的默认版本。这还允许在必要时从不同版本加载带有“Load隐式”的库。

当使用图书馆步骤你也可以指定一个版本:

图书馆my-shared-library@master

由于这是一个常规步骤,这个版本可能是计算而不是像注释一样的常量;例如:

图书馆my-shared-library@分行名称

将使用与多分支相同的SCM分支加载库必威国际有限公司Jenkinsfile.另一个例子是,你可以通过参数选择一个库:

属性(([[参数字符串(的名字LIB_VERSIONdefaultValue主人)])])图书馆my-shared-library@$ {参数个数。LIB_VERSION

请注意,图书馆步骤不能用于覆盖隐式加载的库的版本。在脚本开始时,它已经加载了,给定名称的库可能不会加载两次。

检索方法

指定SCM的最好方法是使用SCM插件,该插件已经被特别更新,以支持一个新的API来检出任意命名的版本(现代供应链管理选项)。在撰写本文时,最新版本的Git和Subversion插件支持这种模式。

为流水线库配置“现代SCM”">
            </div>
           </div>
           <div class=

传统供应链管理

尚未更新以支持共享库所需的新功能的SCM插件,仍可通过传统供应链管理选择。在这种情况下,包括${library.yourlibrarynamehere.version}当分支/tag/ref可能被配置为特定的SCM插件时。这确保了在检出库的源代码时,SCM插件将扩展该变量以检出库的适当版本。

为管道库配置“传统SCM”">
             </div>
            </div>
           </div>
           <div class=

动态检索

如果仅指定库名称(可选地在之后指定版本))图书馆步骤,Jen必威国际有限公司kins将查找该名称的预配置库。(或在github.com/owner/repo自动库(它将加载该库。)

但是,您也可以动态地指定检索方法,在这种情况下,不需要在Jenkins中预定义库。必威国际有限公司下面是一个例子:

图书馆标识符custom-lib@master寻回犬: modernSCM ([GitSCMSource远程git@git.mycorp.com: my必威国际有限公司-jenkins-utils.git身份证my-private-key])

最好参考管道的语法获取SCM的精确语法。

注意库的版本必须在这些情况下应加以说明。

写库

在基本级别,任何有效Groovy代码可以使用。不同的数据结构、实用方法等,例如:

/ / src / org/foo/Point.groovyorg.foo//三维空间中的点指向浮动x、 y,z}

访问步骤

库类不能直接调用以下步骤git.但是,它们可以在外围类的作用域之外实现方法,这些方法会调用Pipeline步骤,例如:

/ / src / org/foo/Zot.groovyorg.foodefcheckOutFrom(回购){giturlgit@github.com:必威国际有限公司 jenkinsci /$ {回购返回

然后可以从脚本化的管道调用它:

defz=org.foo.Zot () z.checkOutFrom(回购)

这种方法有局限性;例如,它阻止声明超类。

或者,一组步骤可以使用到一个标准库类、构造函数或一个方法中:

org.foo公用事业公司实现了可序列化的def步骤公用事业公司(步骤){.steps=steps}defmvn(args) {steps.sh$ {steps.toolMaven/bin/mvn - o$ {arg游戏} }

当在类上保存状态时,例如上面,类必须实现可序列化的接口。这确保了使用这个类的Pipeline(如下例所示)可以在Jenkins中正确地挂起和恢复。必威国际有限公司

@Library乌提尔斯进口org.foo.Utilitiesdef跑龙套=公用事业公司)节点{utils.mvn清洁包装

如果库需要访问全局变量,例如env,应该以类似的方式显式地传递给标准库类或方法。

不再从Scripted Pipeline将大量变量传递到库中,

org.foo公用事业公司静态defmvn(script, args) {script.sh$ {script.toolMaven/bin/mvn - s$ {script.env.HOME/必威国际有限公司jenkins.xml-o$ {arg游戏} }

上面的例子显示了传递给一个人的脚本静态方法,从脚本化管道调用如下:

@Library乌提尔斯进口静态org.foo.Utilities。*节点{mvn清洁包装

定义全局变量

中的脚本在内部瓦尔斯目录按需实例化为单例。这允许在单个方法中定义多个方法B.groovy为了方便的文件。例如:

var / log.groovy
def信息(消息){呼应信息:$ {消息def警告(消息){呼应警告:$ {消息
必威国际有限公司Jenkinsfile
@Library乌提尔斯) _ log.info启动log.warning无事可做!

注意,如果你想在全局中使用某个状态的字段,可以这样注释:

@groovy.transform.FielddefyourField = [:]defyourFunction……

声明式管道不允许对“脚本”块之外的对象进行方法调用。(必威国际有限公司詹金斯-42360).上面的方法调用需要放在脚本指令:

必威国际有限公司Jenkinsfile
@Library乌提尔斯) _管道{代理无阶段{阶段(例子){步骤{/ / log.info“开始”(1)剧本{(2)log.info启动log.warning无事可做!} } } } }
1 该方法调用将失败,因为它位于脚本指令。
2 脚本访问声明性管道中的全局变量所需的指令。

在共享库中定义的变量只会显示在全局变量的引用(在管道的语法),然后Jenk必威国际有限公司ins加载并使用该库作为成功的Pipeline运行的一部分。

避免在全局变量中保留状态

避免使用交互或保留状态的方法定义全局变量。请改用静态类或实例化类的局部变量。

定义定制的步骤

共享库还可以定义与内置步骤行为类似的全局变量,例如git.共享库中定义的全局变量必须以小写或“驼峰式”命名,以便管道正确加载。

例如,定义sayHello,档案var / sayHello.groovy应该创建并实现呼叫方法。的呼叫方法允许以类似于步骤的方式调用全局变量:

//vars/sayHello.groovydef呼叫字符串name =人类) {//任何有效的步骤都可以从这段代码中调用,就像在其他代码中一样/ /脚本管道回响你好,$ {的名字

然后,管道将能够引用和调用这个变量:

sayHellosayHello ()/*使用默认参数调用*/

如果使用块调用,则呼叫方法将收到关闭.类型应该明确定义,以阐明步骤的意图,例如:

/ / var / windows.groovydef呼叫(闭包体){节点(窗户) {body()}}

然后,管道可以像任何接受块的内置步骤一样使用此变量:

windows{蝙蝠cmd / ?

定义更结构化的DSL

如果你有很多相似的管道,那么全局变量机制提供了一个方便的工具来构建更高级别的DSL来捕获相似性。例如,所有Jenkins插件都是以相同的方式构建和测试的,因此我们可以编写一个名为必威国际有限公司buildPlugin

/ / var / buildPlugin.groovydef呼叫地图config){node{giturlhttps://github.com/必威国际有限公司jenkinsci/$ {config.name-plugin.gitmvn install邮件...主题$ {config.name插件构建身体...} }

假设脚本被加载为全球共享库或作为一个目录级共享库由此产生的必威国际有限公司Jenkinsfile将会非常简单:

必威国际有限公司Jenkinsfile(照本宣科的管道)
buildPlugin的名字git

使用Groovy还有一个“构建器模式”技巧关闭。DELEGATE_FIRST,这允许必威国际有限公司Jenkinsfile看起来更像一个配置文件,而不是一个程序,但这更复杂,更容易出错,不推荐使用。

使用第三方库

在可能的情况下,使用@Grab来自受信任的库有各种问题,不推荐使用。而不是使用@Grab,推荐的方法是使用您选择的编程语言(使用任何您想要的第三方库)创建独立的可执行文件,将其安装到您的管道使用的Jenkins代理上,然后使用必威国际有限公司蝙蝠的一步。

可以使用第三方Java库,通常可以在Maven中央从…起受信任的库代码使用@Grab注释。指的是葡萄文献详情,但简单地说:

@Graborg.apache.commons: commons-math3:3.4.1进口org.apache.commons.math3.primes.Primes无效并行化(int数){如果(!Primes.isPrime(count)){错误$ {没有'// …

中默认缓存第三方库~ / . groovy /葡萄/在Jenkin必威国际有限公司s控制器上。

加载资源

外部库可以从资源/目录使用libraryResource该参数是一个相对路径名,类似于Java资源加载:

def请求= libraryResourcecom/mycorp/pipeline/somelib/request.json

该文件作为字符串加载,适用于传递到某些API或使用写文件

建议使用唯一的包结构,以免与其他库发生意外冲突。

事前测试库的变化

如果在使用不受信任库的生成中发现错误,只需单击重播链接,尝试编辑它的一个或多个源文件,并查看生成的构建行为是否符合预期。一旦您对结果感到满意,沿着构建状态页面上的diff链接,并将diff应用到库存储库并提交。

(即使库请求的版本是一个分支,而不是像标记这样的固定版本,重放的构建将使用与原始构建完全相同的版本:库源将不会再次检出。)

重播受信任的库当前不支持。期间当前也不支持修改资源文件重播

定义声明性管道

从2017年9月下旬发布的声明式1.2开始,您也可以在共享库中定义声明式管道。下面是一个例子,它将根据构建号是奇数还是偶数执行一个不同的声明式管道:

/ / var / evenOrOdd.groovydef呼叫intbuildNumber) {如果(buildNumber %2= =0){管道{代理任何阶段{阶段(甚至阶段){步骤{回音构建数为偶数} } } } }其他的{管道{代理任何阶段{阶段(奇怪的阶段){步骤{回音构造号是奇数} } } } } }
/ /必威国际有限公司 Jenkinsfile@Librarymy-shared-library) _ evenOrOdd (currentBuild.getNumber ())

只有整个管道S可以在此时在共享库中定义。这只能在vars/*.groovy,而且只在一个呼叫方法。在单个构建中只能执行一个声明式管道,如果试图执行第二个,则构建将会失败。



这个页面有用吗?

请通过这个提交你对这个页面的反馈快速形成

或者,如果您不希望完成快速表单,您可以简单地指出,如果您觉得这个页面有帮助?

是的


在这里.