Jenkins 流水线/带有未定义变量的 Groovy 脚本 [英] Jenkins Pipeline / Groovy Script with undefined variables

查看:80
本文介绍了Jenkins 流水线/带有未定义变量的 Groovy 脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将我的大型多配置 Jenkins 作业转换为管道语法,以便除其他外,将它拆分到多个节点并将我的多个阶段合并到一个作业中.这是我遇到问题的部分:

I'm trying to convert my large multi-config Jenkins job over to pipeline syntax so I can, among other things, split it across multiple nodes and combine my multiple stages into one job. Here's the part where I'm seeing trouble:

def build_test_configs = [:]
def compilers = ['gnu', 'icc']
def configs = ['debug', 'default', 'opt']

for (int i = 0; i < configs.size(); i++) {
    for (int j = 0; j < compilers.size(); j++) {
        def node_name = ""
        if ("${compilers[j]}" == "gnu") {
            node_name = "node001"
        } else {
            node_name = "node002"
        }
        build_test_configs["${node_name} ${configs[i]}"] = {
            node ("${node_name}") {
                stage("Build Test ${node_name} ${compilers[j]} ${configs[i]}") {
                    unstash "${node_name}-tarball"
                    sh "$HOME/software/jenkins_scripts/nightly.sh ${configs[i]} ${compilers[j]} yes $WORKSPACE"
                }
            }
        }
    }
}

parallel build_test_configs

我的问题是 ${compilers[j]$configs[i] 当我到达我试图建立一个第 13 行的 build_test_configs 字典.看起来第 8 行的检查工作正常.

My problem is that ${compilers[j] and $configs[i] are undefined when I get to the part where I'm trying to build up a dictionary of build_test_configs on line 13. It would appear that the check on line 8 is working just fine.

我本身没有错误消息.该脚本不会产生任何运行时错误.意外的输出是阶段的名称是:

I don't have an error message per se. The script doesn't produce any runtime errors. The unexpected output is that the names of the stages are:

  • 构建测试 node001 null null
  • 构建测试 node001 null null
  • 构建测试 node002 null null

nightly.sh 脚本也被传递了 null 参数.

And the nightly.sh script is getting passed null parameters as well.

推荐答案

我认为这是预期的行为:Jenkins Pipeline 脚本是用 Groovy 编写的,但实际执行的是它的转换(他们使用的术语是继续-传递风格转换").例如,有些部分会在主节点上运行,有些会在从节点上运行.

I think this is the expected behavior: Jenkins Pipeline scripts are written in Groovy but what is actually executed is a transformation of that (the term they use is "continuation-passing style transformation"). For example, some parts will run on the master, some on the slave nodes.

这涉及到很多不可思议的魔法,但在我们的水平上,这意味着我们必须处理语法中的约束&我们使用的结构.

This involves a lot of magic that flies way above my head, but at our level it means we have to work with constraints in the syntax & constructs we use.

请参阅本文的基础知识"段落:

要了解流水线行为,您必须了解有关它如何执行的几点.

To understand Pipeline behavior you must understand a few points about how it executes.

  1. 除了步骤本身,所有的流水线逻辑,Groovy 条件、循环等在 master 上执行.无论简单或复杂!即使在节点块内!
  2. 步骤可能会在适当的情况下使用执行程序来完成工作,但每个步骤也有少量的主系统开销.
  3. 流水线代码被写成 Groovy 但执行模型在编译时从根本上转变为 Continuation传球风格 (CPS).
  4. 这种转变提供了宝贵的安全性和管道的耐用性保证,但它附带权衡:步骤可以调用Java并快速高效地执行,但是 Groovy 的运行速度比正常情况要慢得多.Groovy 逻辑需要更多的内存,因为保留了基于对象的语法/块树在内存中.
  5. 管道经常将程序及其状态持久化到能够在主人的失败中幸存下来.

另请参阅 JENKINS-41335 讨论对脚本中变量的支持.

Also see JENKINS-41335 discussing support of variables across the script.

啊,是的,正如评论中所指出的,新的声明性模型允许定义一个 环境 带有将按照您需要的方式传递的变量...不知道如何在没有 JENKINS-41335 的脚本化管道中执行此操作,但现在似乎会发生进一步的演变在声明性的土地上:/

ah, yes, as pointed in the comments, the new declarative model allows to define an environment with variables that would be passed the way you need... Don't know how to do that in scripted pipeline without JENKINS-41335 but it seems further evolutions will now happen in declarative land :/

这篇关于Jenkins 流水线/带有未定义变量的 Groovy 脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆