Access which stage failed in previous Jenkins build

喜你入骨 提交于 2021-02-18 20:39:35

问题


I have written a Jenkinsfile script which gets whether documents are updated or code is updated in the current Github commit and starts all the stages accordingly. If only documents are updated I don't run the code testing stage again.

So now if the previous build failed and now in the current Git commit only documents are updated then it will not run the code testing stage. So I want a method/way to know which stage failed during the last Jenkins build and if needed run the current Jenkins build.

For example if the code testing stage failed in the previous build, I'll need to run the code testing stage for this build, otherwise I can just run the documents zipping stage.


回答1:


As a workaround to get failed stages from Jenkins build such function can be used. I could not find a simpler way to do it. But this code requires to run without Groovy sandbox or you need to whitelist a lot of Jenkins method signatures (which is not recommeded). Also blueocean plugin has to be installed.

import io.jenkins.blueocean.rest.impl.pipeline.PipelineNodeGraphVisitor                                                                                                                                            
import io.jenkins.blueocean.rest.impl.pipeline.FlowNodeWrapper                                                                                                                                                     
import org.jenkinsci.plugins.workflow.flow.FlowExecution                                                                                                                                                           
import org.jenkinsci.plugins.workflow.graph.FlowNode                                                                                                                                                               
import org.jenkinsci.plugins.workflow.job.WorkflowRun                                                                                                                                                              

@NonCPS                                                                                                                                                                                                            
List getFailedStages(WorkflowRun run) {                                                                                                                                                                            
    List failedStages = []                                                                                                                                                                                         
    FlowExecution exec = run.getExecution()                                                                                                                                                                        
    PipelineNodeGraphVisitor visitor = new PipelineNodeGraphVisitor(run)                                                                                                                                           
    def flowNodes = visitor.getPipelineNodes()                                                                                                                                                                     

    for (node in flowNodes) {                                                                                                                                                                                      
        if (node.getType() != FlowNodeWrapper.NodeType.STAGE ) { continue; }                                                                                                                                       
        String nodeName = node.getDisplayName()                                                                                                                                                                    
        def nodeResult = node.getStatus().getResult()                                                                                                                                                              
        println String.format('{"displayName": "%s", "result": "%s"}',                                                                                                                                             
                              nodeName, nodeResult)                                                                                                                                                                
        def resultSuccess = io.jenkins.blueocean.rest.model.BlueRun$BlueRunResult.SUCCESS                                                                                                                          
        if (nodeResult != resultSuccess) {                                                                                                                                                                         
            failedStages.add(nodeName)                                                                                                                                                                             
        }                                                                                                                                                                                                          
    }                                                                                                                                                                                                              
    return failedStages                                                                                                                                                                                            
}                                                                                                                                                                                                                  

// Ex. Get last build of "test_job"                                                                                                                                                                                
WorkflowRun run = Jenkins.instance.getItemByFullName("test_job")._getRuns()[0]                                                                                                                                     
failedStages = getFailedStages(run) 




回答2:


I thing it could fit. Use buildVariables from previous build, timeout \ input in case You need to change something, try \ catch for setup stages status. Code example:

// yourJob
// with try/catch block

def stageOneStatus;
def stageTwoStatus;
def stageThreeStatus;

pipeline {
    agent any
    stages {
        stage("STAGE 1") {
            // For initial run every stage
            when { expression { params.stageOne == "FAILURE" } }
            steps {
                script {
                    try {
                        // make thing
                    } catch (Exception e) {
                        stageOneStatus = "FAILURE";
                    }
                }
            }
        }

        stage("STAGE 2") {
            when { expression { params.stageTwo == "FAILURE" } }
            steps {
                script {
                    try {
                        // make thing
                    } catch (Exception e) {
                        stageTwoStatus = "FAILURE";
                    }
                }
            }
        }

        stage("STAGE 3") {
            when { expression { params.stageThree == "FAILURE" } }
            steps {
                script {
                    try {
                        // make thing
                    } catch (Exception e) {
                        stageThreeStatus = "FAILURE";
                    }
                }
            }
        }
    }
}

// Checking JOB

def pJob;

pipeline {
    agent any
    stages {
        // Run job with inheriting variable from build
        stage("Inheriting job") {
            steps {
                script {
                    pJob = build(job: "yourJob", parameters: [
                            [$class: 'StringParameterValue', name: 'stageOne', value: 'FAILURE'],
                            [$class: 'StringParameterValue', name: 'stageTwo', value: 'FAILURE'],
                            [$class: 'StringParameterValue', name: 'stageThree', value: 'FAILURE']
                            ], propagate: false)
                    if (pJob.result == 'FAILURE') {
                    error("${pJob.projectName} FAILED")
                    }
                }
            }
        }
        // Wait for fix, and re run job 
        stage ('Wait for fix') {
            timeout(time: 24, unit: 'HOURS') {
            input "Ready to rerun?"
            }
        }
        // Re run job after changes in code
        stage("Re-run Job") {
            steps {
                script {
                    build(
                        job: "yourJob",
                        parameters: [
                            [$class: 'StringParameterValue',name: 'stageOne',value: pJob.buildVariables.stageOneStatus ],
                            [$class: 'StringParameterValue',name: 'stageTwo',value: pJob.buildVariables.stageTwoStatus ],
                            [$class: 'StringParameterValue',name: 'stageThree',value: pJob.buildVariables.stageThreeStatus ]

                        ]
                    )
                }
            }
        }
    }
}


来源:https://stackoverflow.com/questions/51490771/access-which-stage-failed-in-previous-jenkins-build

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!