我目前正在配置一个由许多平台构建组成的管道。在管道的开头,用户可以选择要构建或跳过的平台。
根据每个平台的“构建”阶段是通过还是失败,下游阶段的步骤可以检查该平台构建的状态并确定是否运行。如果一个或多个平台发生故障,这允许管道尝试并完成其他平台(如果用户确认这样做)。
目前,我的管道实现了这一点,允许用户在管道开始时包含/排除平台,并授权管道在平台发生故障时继续构建(但将管道标记为故障)。这允许存档构建文件/发布gtests等,这可以在下游阶段/步骤中完成。这是我的Jenkinsfile:
// Specify whether or not to build platform by default
def buildDefinitions = [ 'windows' : true , 'macos' : true , 'ubuntu' : true ]
// Keep track of builds that fail
def failedBuilds = [:]
stage('Build Customisation') {
try {
// Wait limited amount of time for user input
timeout(time: 30, unit: 'SECONDS') {
// Update the build definitions based on user input
buildDefinitions = input(
message: 'Toggle which builds to run (Abort will use default)',
// Use custom global function to generate boolean input parameters based on a map
// Sets default value to value in input map
parameters: generateInputBoolParams( buildDefinitions )
)
}
// Continue pipeline if user input not provided within time limit
} catch ( error ) {
echo 'Using default pipeline configuration...'
}
// Check that at least one build platform is selected
if ( !mapContainsTrue( buildDefinitions ) ) {
error 'No builds selected, aborting pipeline'
}
}
stage('Conditional Build') {
parallel (
'Windows' : {
// Prevent a build failure from terminating the pipeline after this stage
try {
// Check if windows build is set to run
if ( buildDefinitions['windows'] ) {
node('windows') {
checkout(scm)
bat 'build.bat default-windows'
}
} else {
echo 'Build was disabled by user'
}
// Catch an error in the build
} catch ( error ) {
// Make note that the build failed
failedBuilds['windows'] = true
// Set the pipeline status as failure
currentBuild.result = 'FAILURE'
}
},
'MacOS' : {
try {
if ( buildDefinitions['macos'] ) {
node('macos') {
checkout(scm)
sh './build.sh default-macos'
}
} else {
echo 'Build was disabled by user'
}
} catch ( error ) {
failedBuilds['macos'] = true
currentBuild.result = 'FAILURE'
}
},
'Ubuntu' : {
try {
if ( buildDefinitions['ubuntu'] ) {
node('ubuntu') {
checkout(scm)
sh './build.sh default-ubuntu'
}
} else {
echo 'Build was disabled by user'
}
error 'test error'
} catch ( error ) {
failedBuilds['ubuntu'] = true
currentBuild.result = 'FAILURE'
}
}
)
// Check if any builds have been marked as failed
if ( mapContainsTrue( failedBuilds ) ) {
// Remove failed builds from the original map of enabled builds
def updatedBuildDefinitions = subtractMap( buildDefinitions, failedBuilds )
// Check that there are builds left to run
if ( mapContainsTrue( updatedBuildDefinitions ) ) {
// Update the original build map
buildDefinitions = updatedBuildDefinitions
// Lists the failed builds and asks whether to continue or abort the pipeline
timeout(time: 30, unit: 'SECONDS') {
input(
message: 'Builds failed ' + getKeyset( failedBuilds ) + ', do you want to continue the pipeline and skip failed builds?'
)
}
} else {
// Throw an error to terminate the pipeline if no builds are left to run
error 'No builds left to run'
}
}
}
stage('Conditional Downstream') {
parallel (
'Windows' : {
if ( buildDefinitions['windows'] ) {
echo 'You chose to run the windows build!'
} else {
echo 'The windows build was skipped'
}
},
'MacOS' : {
if ( buildDefinitions['macos'] ) {
echo 'You chose to run the macos build!'
} else {
echo 'The macos build was skipped'
}
},
'Ubuntu' : {
if ( buildDefinitions['ubuntu'] ) {
echo 'You chose to run the ubuntu build!'
} else {
echo 'The ubuntu build was skipped'
}
}
)
}
我的全球职能:
// subtractMap.groovy
def call ( map1, map2 ) {
return map1 - map2
}
// mapContainsTrue.groovy
boolean call ( array ) {
for ( entry in array ) {
if ( entry.value == true ) {
isBuildConfigValid = true
return true
} else {
return false
}
}
}
// getKeyset.groovy
def call ( map ) {
return map.keySet() as String[]
}
// generateInputBoolParams.groovy
def call ( array ) {
def parameterList = []
for ( item in array ) {
parameterList.add( booleanParam(defaultValue: item.value, name: item.key) )
}
return parameterList
}
虽然一般功能有效,但除了将管道标记为失败之外,UI响应不会。我希望能够将并行分支标记为失败,以便在Blue Ocean UI中,很容易看出哪个平台无法构建。
Blue Ocean UI with failed parallel branch in try/catch block
将舞台标记为失败也是有用的,因此当不在Blue Ocean UI中时,舞台视图会显示哪一个失败(除非只有在该阶段终止管道时才会发生这种情况)尽管一旦蓝海离开Beta这不再是一个问题了。
Stage View failed stage (Above) and as is (Below)
如何将并行分支标记为失败,以便在蓝海UI中显示红叉?也许使用像currentBuild.result
整个舞台是否有类似的事情可以在舞台视图中显示出来? (不太重要)
答案 0 :(得分:4)
可以通过将并行步骤和阶段步骤包装在try块中来实现UI响应,将错误从并行分支内的try / catch块抛出到stage块。不像设置属性那样干净,但对Blue Ocean和Stage View都有正确的UI响应。
switch (l, r) {
case let (l as A, r as A):
print("(\(l), \(r)) is (A, A)")
default:
print("failed to match tuple")
}
答案 1 :(得分:1)
这在蓝海对我有效:
stage("Global Stage") {
def parallelStages = [failfast: false]
parallelStages["Branch 1"] = {
//Code for branch 1
}
parallelStages["Branch 2"] = {
//Code for branch 2
}
catchError(buildResult: 'SUCCESS', message: 'Branch Failed', stageResult: 'UNSTABLE')
{ parallel parallelStages }
}
这可以正确地将失败的并行分支标记为Blue Ocean中的UNSTABLE,不影响其他阶段的结果,并将整个构建标记为SUCCESS