如何在舞台视图和Blue Ocean UI中设置Jenkins阶段或管道并行分支状态(不稳定,失败等)?

ink*_*ris 7 jenkins jenkins-pipeline jenkins-blueocean

概观

我目前正在配置一个由许多平台构建组成的管道.在管道的开头,用户可以选择要构建或跳过的平台.

根据每个平台的"构建"阶段是通过还是失败,下游阶段的步骤可以检查该平台构建的状态并确定是否运行.如果一个或多个平台发生故障,这允许管道尝试并完成其他平台(如果用户确认这样做).

进展

目前,我的管道实现了这一点,允许用户在管道开始时包含/排除平台,并授权管道在平台发生故障时继续构建(但将管道标记为故障).这允许存档构建文件/发布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'
            }
        }
    )
}
Run Code Online (Sandbox Code Playgroud)

我的全球职能:

// 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
}
Run Code Online (Sandbox Code Playgroud)

问题

虽然一般功能有效,但UI响应不会将管道标记为失败.我希望能够将并行分支标记为失败,以便在Blue Ocean UI中,很容易看出哪个平台无法构建.

蓝色海洋UI与尝试/捕获块中失败的并行分支

将阶段标记为失败也是有用的,因此当不在Blue Ocean UI中时,阶段视图显示哪一个失败(除非只有在该阶段终止管道时才会发生这种情况)尽管一旦蓝海离开Beta,这将不会真的不再是问题了.

舞台视图失败阶段(上方)和原样(下方)

  • 如何将并行分支标记为失败,以便它显示在带有红叉的Blue Ocean UI中?也许与环境变量一样currentBuild.result

  • 整个舞台是否有类似的事情可以在舞台视图中显示出来?(不太重要)

ink*_*ris 5

通过将并行步骤和阶段步骤都包装在try块中,将错误从并行分支内的try / catch块抛出到阶段块,可以实现UI响应。不像设置属性那样干净,但是对于Blue Ocean和Stage View确实具有正确的UI响应。

try {
    stage('example') {
        try {
            parallel (
                'A' : {
                    try {
                        // Example...
                    }
                    catch (error) {
                        // Mark branch as failed somewhere
                        throw error
                    }
                },
                'B' : {
                    try {
                        // Example...
                    }
                    catch (error) {
                        // Mark branch as failed somewhere
                        throw error
                    }
                }
            )
        }
        catch (error) {
            throw (error)
        }
        finally {
            // Parallel branch A failed, do you want to continue? etc...
        }
    }
}
catch (error) {
    println (error)
}
Run Code Online (Sandbox Code Playgroud)