如果复制失败,Jenkins 管道将跳过阶段

时间:2021-04-17 14:29:52

标签: linux jenkins groovy

假设我们有一个简单的管道设置,如下所示:

pipeline {
   stages {
      stage('Stage1') {
         sh '''
           echo 'Copying files'
           cp ./file1 ./directory1
         '''
      }
      stage('Stage2') {
         sh '''
           echo 'This stage should still work and run'
           cp ./directory2/files ./directory2/subdirectory
         '''
      }
      stage('Stage3') { ... }
      ...
   }
}

每当我在 Stage1 或 Stage2 中没有文件时,它就会失败,说:

'cp cannot stat ./file1 ./directory1''cp cannot stat ./directory2/files ./directory2/subdirectory'

当然,如果文件存在,两个阶段都可以正常工作。问题在于,如果一个阶段失败,其余阶段的构建就会失败。因此,如果 Stage1 因为没有文件而失败,那么它之后的每个阶段都会失败并且它们甚至不运行,如果 Stage2 失败也是如此,那么我们知道 Stage1 成功了,但 Stage3 及以后的阶段失败了,甚至不运行。

有没有办法让它在 cp 命令失败并显示 cp cannot stat 时跳过阶段并继续下一个阶段?或者至少让那个阶段失败,它可以继续构建下一个阶段?

3 个答案:

答案 0 :(得分:1)

这可以使用 catchError

pipeline {
    agent any
    stages {
       
        stage('1') {
            steps {
                script{
                catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
                    echo 'Copying files'
                    cp ./file1 ./directory1
                }
              }
            }
        }
        stage('2') {
            steps {
                script{
                catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
                    echo 'This stage should still work and run'
                    cp ./directory2/files ./directory2/subdirectory
                }
              }
            }
        }

        stage('3') {
            steps {
                sh 'exit 0'
            }
        }
    }
}

从上面的管道脚本,所有阶段都将被执行。如果 cp 命令不适用于第 1 阶段或第 2 阶段,它将在该特定阶段显示为失败,但其余所有阶段都将执行。

类似于下面的截图:

enter image description here


修改后的答案

以下管道脚本包括 sh ''' ''',它不必出现在 catchError 块中。

您只能在 catchError 中包含要捕获错误的命令。


pipeline {
    agent any
    stages {

        stage('1') {
            steps {
                sh """
                
                echo 'Hello World!!!!!!!!'
                curl https://www.google.com/
                
                """ 

                catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
                    echo 'Copying files'
                    cp ./file1 ./directory1
                }
            }
        }
        stage('2') {
            steps {
                catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
                    echo 'This stage should still work and run'
                    cp ./directory2/files ./directory2/subdirectory
                }
            }
        }

        stage('3') {
            steps {
                sh 'exit 0'
            }
        }
    }
}

答案 1 :(得分:1)

这是一种在文件不存在时跳过阶段的简单方法,使用 when 指令:

pipeline {
   agent any   
   stages {
      stage('Stage1') {
         when { expression { fileExists './file1' } }
         steps {
            sh '''
            echo 'Copying files'
            cp ./file1 ./directory1
            '''
         }
      }
      stage('Stage2') {
         when { expression { fileExists './directory2/files' } }
         steps {
            sh '''
            echo 'This stage should still work and run'
            cp ./directory2/files ./directory2/subdirectory
            '''
         }
      }
      stage('Stage3') {
         steps {
            echo "stage 3"
         }
      }
   }
}

在上述情况下,您必须在 when 指令和 sh 步骤中两次指定路径,最好以另一种方式处理它,例如使用变量或闭包。 由于声明式管道的限制,我建议您改用脚本式管道。

答案 2 :(得分:0)

您可以在尝试使用如下条件复制文件之前检查文件是否存在:

[ -f ./directory2/files ] && cp ./directory2/files ./directory2/subdirectory || echo "File does not exist"

Source and more info