在Jenkins管道中实现矩阵配置

时间:2017-12-14 13:46:36

标签: jenkins jenkins-pipeline nested-loops

我最近搬到了Jenkins的Pipeline插件。我之前成功地使用过自由式作业,但现在想测试新的东西。

我的项目为Windows和Linux构建,在发布和调试模式下,并使用名为device的参数来配置一些C预处理器宏:全局#define d frame_widthframe_height会有所不同,具体取决于device值。

这是我的Jenkinsfile:

def device_config(device) {
    def device_config = "";
    switch(device) {
        case ~/^dev_[Aa]$/:
            device_config="""-DGLOBAL_FRAME_WIDTH=640\
                             -DGLOBAL_FRAME_HEIGHT=480"""
        break;
    case ~/^dev_[Ss]$/:
        device_config="""-DGLOBAL_FRAME_WIDTH=320\
                         -DGLOBAL_FRAME_HEIGHT=240"""
        break;
    default: 
        echo "warning: Unknown device \"$device\" using default config from CMake"
        break;
    }
    return device_config
}

pipeline {
    agent {
        label 'project_device_linux'
    }
    environment {
        device='dev_A'
    }
    stages {
        stage('Configure') {
            steps {
                script {
                    dc = device_config("${env.device}")
                }
                dir('build') {
                    sh """cmake .. -DOpenCV_DIR="/usr/local" -DCMAKE_BUILD_TYPE="Debug"\
                               -DCHECK_MEMORY_LEAKS=ON\
                               -DENABLE_DEVELOPER_MODE=OFF\
                               -DUNIT_TEST_RAW_PATH=${env.tmpfs_path}\
                               $dc"""
               }
            }
        }
        stage('Build') {
            steps { 
                dir('build') { 
                    sh "make -j 16"
                }
            }
        }
        stage('Test'){
            steps {
                dir('build') {
                   sh "make check"
                }
            }
        }
    }
}

现在,我想为其他设备重复所有这些阶段,dev_s,“发布”构建类型,以及Windows。根据参数的不同,也存在一些细微差别:例如,“Release”构建应包括发布已编译的二进制文件并排除内存泄漏检查。此外,如果我说得对,Windows奴隶不理解sh构建步骤并为此目的使用bat

如果没有代码的复制粘贴,并且在2个节点上并行运行,如果运行Linux,另一个运行Windows,我怎么能这样做呢?

显然,应该有几个嵌套循环,但我不清楚每个循环迭代要发出什么。

忘了提一下,我想在推送活动的Gitlab触发器上运行一切。

更新

目前我最终会得到以下内容

#!/usr/bin/env groovy

def device_config(device) {
    def result = "";
    switch(device) {
        case ~/^dev_[Aa]$/:
            result ="""-DFRAME_WIDTH=640\
                       -DFRAME_HEIGHT=480"""
            break;
        case ~/^dev_[Ss]$/:
            result ="""-DFRAME_WIDTH=320\
                       -DFRAME_HEIGHT=240"""
            break;
        default:
            echo "warning: Unknown device \"$device\" using default config from CMake"
            break;
    }
    return result;
}


oses = ['linux', 'windows']
devices = ['dev_A', 'dev_S']
build_types = ['Debug', 'Release']


node {
    stage('Checkout') {
        checkout_steps = [:]
        for (os in oses) {
            for (device in devices) {
                for (build_type in build_types) {
                    def label = "co-${os}-${device}-${build_type}"
                    def node_label = "project && ${os}"

                    checkout_steps[label] = {
                        node(node_label) {
                            checkout scm
                        }
                    }
                }
            }
        }

        parallel checkout_steps

    }


    stage('Configure') {

        config_steps = [:]

        for (os in oses) {
            for (device in devices) {
                for (build_type in build_types) {
                    def label = "configure-${os}-${device}-${build_type}"
                    def node_label = "project && ${os}"
                    def dc = device_config("${device}")

                    cmake_parameters = """-DCMAKE_BUILD_TYPE="${build_type}"\
                                          -DCHECK_MEMORY_LEAKS=ON\
                                          $dc"""

                    if(os == 'linux') {
                        config_steps[label] = {
                            node(node_label) {
                                dir('build') {
                                    sh """cmake .. -DOpenCV_DIR=/usr/local ${cmake_parameters}"""
                                }
                            }
                        }
                    } else {
                        config_steps[label] = {
                            node(node_label) {
                                dir('build') {
                                    bat """cmake .. -G"Ninja" -DOpenCV_DIR=G:/opencv_2_4_11/build ${cmake_parameters}"""
                                }
                            }
                        }
                    }
                }
            }
        }

        parallel config_steps
    }

}

我不喜欢的是在Jenkins文件中设置了一些特定于节点的设置,比如路径。希望弄明白,如何在Jenkins的节点设置中设置它们。

我还在日志中看到,只应用Release + dev_S配置 - 有某种闭包和后期绑定。搜索显示它是已知且已经修复的问题 - 我必须计划弄清楚如何处理闭包。

0 个答案:

没有答案