如何在同一个 Jenkins 节点中加载另一个 groovy 脚本?

Posted

技术标签:

【中文标题】如何在同一个 Jenkins 节点中加载另一个 groovy 脚本?【英文标题】:How to load another groovy script in the same Jenkins node? 【发布时间】:2016-08-10 14:29:58 【问题描述】:

从另一个管道脚本加载管道脚本时,两个管道不会在同一个节点上执行:第一个在我的主节点上执行,第二个在从节点上执行。

我正在使用带有Pipeline Script from SCM 选项的 Jenkins 管道以这种方式完成很多工作:

我的每个作业都使用 Poll SCM 选项定义了它们对应的 Git 存储库 URL,以便在对我的代码进行更改时自动轮询存储库(基本作业用法)。

我的每个作业都在其存储库的根目录中定义了一个简单的Jenkinsfile,其中的管道脚本基本上什么都不做,只是加载一个更通用的管道。

例如

node 
    // --- Load the generic pipeline ---
    checkout scm: [$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], submoduleCfg: [], userRemoteConfigs: [[url: 'http://github/owner/pipeline-repo.git']]]
    load 'common-pipeline.groovy'
()

我的 common-pipeline.groovy 管道执行实际的工作,例如构建、发布或部署工件,例如:

 ->
    node() 
        def functions = load 'common/functions.groovy'

        functions.build()
        functions.release()
        functions.deploy()
    

现在我不想为每个作业强制节点所以两个管道都有 node("master")node("remote") 因为我真的不想手动处理它,但是我'一旦第一个管道在特定节点(masterslave1slave2slave3)上运行,我会喜欢这样第二个/加载的管道在同一个节点上执行,否则我的实际 Git 存储库代码在其他节点的工作区中不可用...

有什么方法可以指定我希望我的第二个管道与第一个管道在同一个节点上执行,或者在使用load 步骤时传递一个参数?

【问题讨论】:

【参考方案1】:

在结帐之后和脚本加载之前存储工作区怎么样?:

例如

stash includes: '**', name: "source"

然后在另一个 node() 部分中取消存储它:

例如 unstash "source"

这样它就可以在其他节点上使用

别忘了清理工作区

或者如何创建一个包含结帐逻辑的通用函数(也许将分支作为参数传递)。然后您可以丢弃 Jenkins 文件中的 node(),而只在您的共享 groovy 脚本中使用 node() 条目?

例如詹金斯文件

load 'common-pipeline.groovy'
createWorlflow("*/master")

common-pipeline.groovy:

def createWorkflow(branches)
node() 
        def functions = load 'common/functions.groovy'
        functions.checkout(branches)
        functions.build()
        functions.release()
        functions.deploy()
    

【讨论】:

Stash/Unstash 似乎是个好主意,不幸的是由于某种原因我无法进入我的common-pipeline 闭包,加载命令在执行通用闭包之前失败...正在将第二个脚本作为函数加载也是一个好主意,因为它可以确保我两个步骤都在同一个节点上运行,但是在 createWorkflow 函数内结帐意味着我复制了结帐步骤(Jenkins 已经使用Poll SCM 配置完成了)...我认为我正在尝试结合您的两个解决方案:调用一个函数并在我加载的函数中取消存储我的初始工作区...... 实际上我永远无法从Poll SCM 配置中隐藏代码签出,因为当我的管道代码被执行时,我已经(可能)在另一个节点上运行代码,并且我无法控制Jenkins Poll SCM 执行...【参考方案2】:

你可以为第二个管道做一个参数化的作业,并在触发第二个作业时使用参数来控制节点。

第二个管道如下所示:

node(runhereParam) 


【讨论】:

我不明白这将如何解决我的问题?首先,我不想有一个单独的触发作业,因为这会导致并发问题(我的 10 个服务同时运行必须等待第二个参数化作业顺序执行),这就是我使用管道的原因,能够从不同的作业执行相同的代码。其次,即使使用您的解决方案,我在哪里可以获得第二份工作的参数 runhereParam ?我需要管道的两个部分在同一个节点上执行!

以上是关于如何在同一个 Jenkins 节点中加载另一个 groovy 脚本?的主要内容,如果未能解决你的问题,请参考以下文章

如何从sks文件加载节点,然后应用在Scene Editor中定义的操作

如何从另一个jenkins(本地)调用1个jenkins(远程jenkins)中配置的作业

如何在 Jenkins 中将现有工作从一个视图移动到另一个视图?

Jenkins-配置从节点

如何防止相同类型的两个管道 jenkins 作业在同一节点上并行运行?

jenkins 如何让job对应一个节点