我最近搬到了Jenkins的Pipeline插件。我之前成功地使用过自由式作业,但现在想测试新的东西。
我的项目为Windows和Linux构建,在发布和调试模式下,并使用名为device
的参数来配置一些C预处理器宏:全局#define
d frame_width
和frame_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
配置 - 有某种闭包和后期绑定。搜索显示它是已知且已经修复的问题 - 我必须计划弄清楚如何处理闭包。