Search code examples
jenkinsjenkins-pipeline

Make Jenkins not to skip stages when failure occure


I have a Jenkins pipeline file that has 3 stages:

stage('run SQL') {
    steps { 
        script {
                echo "Now run SQL on hosts"
                ansiblePlaybook become: true,
                colorized: true,
                credentialsId: 'me',
                installation: 'ansible',
                inventory: 'google/ansible/ansible-root/hosts',
                vaultCredentialsId: 'AnsibleVaultPassword',
                playbook: "ansible//playbooks/run-query.yml"
        }       
    }       
}       

stage('task2') {
    steps { 
        script {
                echo "Now run task2"
                ansiblePlaybook become: true,
                colorized: true,
                credentialsId: 'me',
                installation: 'ansible',
                inventory: 'google/ansible/ansible-root/hosts',
                vaultCredentialsId: 'AnsibleVaultPassword',
                playbook: "ansible//playbooks/task-2.yml"
        }       
    }       
}

stage('task3') {
    steps { 
        script {
                echo "Now run task3"
                ansiblePlaybook become: true,
                colorized: true,
                credentialsId: 'me',
                installation: 'ansible',
                inventory: 'google/ansible/ansible-root/hosts',
                vaultCredentialsId: 'AnsibleVaultPassword',
                playbook: "ansible//playbooks//task-3.yml"
        }       
    }       
}

The Ansible playbook run-query.yml runs on a list of hosts that defined in the google/ansible/ansible-root/hosts file, some of the hosts maybe shut down. When I run the Jenkinsfile, I get the output like this:

14:50:11  [0;32ok: [app-server1]
14:50:15  [1;31fatal: [app-server2]: UNREACHABLE! => {"changed": false, "msg": "Data could not be sent to remote host \"app-server2\". Make sure this host can be reached over ssh: ssh: connect to host app-server2 port 22: Connection timed out\r\n", "unreachable": true}

For those servers that are up, I can see the query run on them by the playbook run-query.yml.

The last part of the output looks like this:

14:51:19  FATAL: command execution failed
14:51:19  hudson.AbortException: Ansible playbook execution failed
14:51:19    at org.jenkinsci.plugins.ansible.AnsiblePlaybookBuilder.perform(AnsiblePlaybookBuilder.java:262)
...

14:51:20  Stage "task2" skipped due to earlier failure(s)
14:51:20  [Pipeline] }
14:51:20  [Pipeline] // stage
14:51:20  [Pipeline] stage
14:51:20  [Pipeline] { (create the report)
14:51:20  Stage "task3" skipped due to earlier failure(s)

It is expected that some of the servers are down, and I was hoping Jenkins can execute the next two stages after run-query.yml.

How can I make the code NOT to skip stage('task2') and stage('task3')?


Solution

  • You can wrap your stage with a catchError block:

    stage('run SQL') {
        steps { 
            catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
                script {
                    echo "Now run SQL on hosts"
                    ansiblePlaybook become: true,
                    colorized: true,
                    credentialsId: 'me',
                    installation: 'ansible',
                    inventory: 'google/ansible/ansible-root/hosts',
                    vaultCredentialsId: 'AnsibleVaultPassword',
                    playbook: "ansible//playbooks/run-query.yml"
                }
            }       
        }       
    }
    

    You can change the buildResult and stageResult to determine what happens when the stage fails. Whatever options you use there, the build will continue without skipping due to earlier failures. You can also do this to the other stages.