Доступ к какому этапу неудачен в предыдущей сборке Дженкинса

Я написал сценарий Jenkinsfile, который определяет, обновляются ли документы или код в текущем коммите Github, и запускает все этапы соответствующим образом. Если обновляются только документы, я больше не запускаю этап тестирования кода.

Так что теперь, если предыдущая сборка не удалась и теперь в текущей Git-коммите обновляются только документы, он не будет запускать этап тестирования кода. Поэтому мне нужен метод/способ узнать, какой этап не удался во время последней сборки Jenkins, и при необходимости запустить текущую сборку Jenkins.

enter image description here

Например, если этап тестирования кода не удался в предыдущей сборке, мне нужно будет запустить этап тестирования кода для этой сборки, в противном случае я могу просто запустить этап архивирования документов.

Ответ 1

В качестве обходного пути для получения неудачных этапов сборки Jenkins можно использовать такую функцию. Я не мог найти более простой способ сделать это. Но этот код требует выполнения без песочницы Groovy, или вам нужно внести в белый список большое количество сигнатур метода Дженкинса (что не рекомендуется). Также должен быть установлен плагин blueocean.

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

Я думаю, что это может поместиться. Используйте buildVariables из предыдущей сборки, timeout\input в случае, если вам нужно что-то изменить, try\catch для статуса этапов установки. Пример кода:

// 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 ]

                        ]
                    )
                }
            }
        }
    }
}