首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Jenkins管道多配置项目

Jenkins管道多配置项目
EN

Stack Overflow用户
提问于 2017-10-06 08:56:21
回答 2查看 10.5K关注 0票数 9

原始情况:

我在詹金斯有一份工作是运行一个蚂蚁脚本。我很容易就在不止一个使用“多配置项目”的软件版本上测试了这个ant脚本。

这种类型的项目非常酷,因为它允许我指定我需要的两个软件的所有版本(在我的例子中是Java和Matlab),它将使用参数的所有组合来运行我的ant脚本。

然后,这些参数被用作字符串,在定义我的ant将要使用的可执行文件的位置时将其连接起来。

示例: env.MATLAB_EXE=/usr/local/MATLAB/${MATLAB_VERSION}/bin/matlab

这是完美的工作,但现在我将这个脚本迁移到它的一个线性版本。

管道迁移:

我使用参数化管道插件以流水线方式实现了相同的脚本。这样,如果我手动触发构建,我就可以手动选择我的软件的哪个版本,并且我还找到了一种定期执行此操作的方法,在每次运行时选择我想要的参数。

这个解决方案似乎相当有效,但是并不是真正令人满意的。

我的多配置项目有一些特性,但这不是这样的:

  1. 使用多个参数,我可以设置为插值它们并执行每个组合。
  2. 执行显然是分开的,并且在构建历史/构建细节中很容易识别使用了哪些设置。
  3. 只要向参数添加一个新的“可能”值,就会产生所需的执行。

请求

因此,我想知道是否有一个更好的解决方案,我的问题,也可以满足上述观点。

长话短说:是否有办法在jenkins实现多配置项目,但使用管道技术?

EN

回答 2

Stack Overflow用户

发布于 2017-10-10 20:16:09

我最近见过很多类似的问题,所以这似乎是一个有趣的练习来解决这个问题。

一个矩阵/多配置作业,在代码中可视化,实际上只是几个嵌套的循环,每个参数轴一个。

您可以构建一些相当简单的东西,使用一些硬编码的循环来循环几个列表。或者,您可以变得更加复杂,并执行一些递归循环,这样您就不必硬编码特定的循环。

免责声明:--我做的操作比我编写的代码多得多。我对groovy也很陌生,所以这可能可以做得更干净一些,而且可能有很多可以完成的事情,但无论如何,这就完成了任务。

只需做一点点工作,这个matrixBuilder就可以封装在一个类中,这样您就可以传递任务闭包和轴列表,并获得任务映射。把它放在一个共享库中,并在任何地方使用它。应该很容易从多配置作业中添加一些其他特性,比如过滤器。

此尝试使用递归matrixBuilder函数处理任意数量的参数轴并构建所有组合。然后,它并行地执行它们(显然取决于节点可用性)。

代码语言:javascript
复制
/*
    All the config axes are defined here
    Add as many lists of axes in the axisList as you need.
    All combinations will be built
*/
def axisList = [
    ["ubuntu","rhel","windows","osx"],           //agents
    ["jdk6","jdk7","jdk8"],                      //tools
    ["banana","apple","orange","pineapple"]      //fruit
]



def tasks = [:]
def comboBuilder
def comboEntry = []


def task = {
    // builds and returns the task for each combination

    /* Map the entries back to a more readable format
       the index will correspond to the position of this axis in axisList[] */
    def myAgent = it[0]
    def myJdk   = it[1]
    def myFruit = it[2]

    return {
        // This is where the important work happens for each combination
        node(myAgent) {
            println "Executing combination ${it.join('-')}"
            def javaHome = tool myJdk
            println "Node=${env.NODE_NAME}"
            println "Java=${javaHome}"
        }

        //We won't declare a specific agent this part
        node {
            println "fruit=${myFruit}"
        }
    }
}


/*
    This is where the magic happens
    recursively work through the axisList and build all combinations
*/
comboBuilder = { def axes, int level ->
    for ( entry in axes[0] ) {
        comboEntry[level] = entry
        if (axes.size() > 1 ) {
            comboBuilder(axes[1..-1], level + 1)
        }
        else {
            tasks[comboEntry.join("-")] = task(comboEntry.collect())
        }
    }
}

stage ("Setup") {
    node {
        println "Initial Setup"
    }
}

stage ("Setup Combinations") {
    node {
        comboBuilder(axisList, 0)
    }
}

stage ("Multiconfiguration Parallel Tasks") {
    //Run the tasks in parallel
    parallel tasks
}

stage("The End") {
    node {
        echo "That's all folks"
    }
}

您可以在http://localhost:8080/job/multi-configPipeline/[build]/flowGraphTable/上看到更详细的作业流程(可以在构建页面的管道步骤链接下面找到)。

编辑:您可以将阶段向下移动到“任务”创建中,然后更清楚地看到每个阶段的细节,但不能像多配置作业那样在一个整洁的矩阵中查看。

代码语言:javascript
复制
...
return {
    // This is where the important work happens for each combination
    stage ("${it.join('-')}--build") {
        node(myAgent) {
            println "Executing combination ${it.join('-')}"
            def javaHome = tool myJdk
            println "Node=${env.NODE_NAME}"
            println "Java=${javaHome}"
        }
        //Node irrelevant for this part
        node {
            println "fruit=${myFruit}"
        }
    }
}
...

或者,您可以用自己的stage包装每个stage以获得更多的细节。

当我这样做时,我注意到我以前的代码中有一个bug (现在已经修复了)。我将comboEntry引用传递给任务。我应该发送一个副本,因为,虽然阶段的名称是正确的,但当它实际执行它们时,这些值当然是最后遇到的所有条目。所以我把它改成了tasks[comboEntry.join("-")] = task(comboEntry.collect())

我注意到,您可以在执行并行任务时保留原始的stage ("Multiconfiguration Parallel Tasks") {}。从技术上讲现在你有了嵌套的阶段。我不知道詹金斯该怎么处理,但它不抱怨。然而,“父级”阶段的时间并不包括平行阶段的时间。

我还注意到,当一个新的构建开始运行时,在作业的“舞台视图”上,所有以前的构建都消失了,大概是因为艺名不完全匹配。但是,在构建完成运行后,它们再次匹配,旧的构建再次出现。

最后,蓝海似乎并没有以同样的方式来实现这一点。它不承认并行过程中的“阶段”,只有包围阶段(如果它存在的话),或者如果不是,则识别“并行”,然后只显示单个并行过程,而不是内部的各个阶段。

票数 9
EN

Stack Overflow用户

发布于 2017-10-10 07:44:49

在我看来,第1点和第3点并不完全清楚,但我怀疑你只是想使用“脚本化”而不是“声明式”管道语法,在这种情况下,你可以让你的工作做你想做的任何事情--矩阵项目轴和轴过滤器所允许的任何东西,等等,包括并行执行。为了灵活起见,声明式语法放弃了语法的简单性(以及对“往返”编辑工具和“指针”的友好性)。

第2点是关于结果的可视化,而不是执行本身。虽然这是一个复杂的主题,但通常的具体要求是能够看到由轴组合区分的测试结果,而现有的可视化(如蓝海)并不支持这种请求。这是由詹金斯-27395跟踪和一些相关的问题,与设计正在进行。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46601999

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档