web-dev-qa-db-ja.com

Jenkins宣言型パイプライン構文の失敗した段階を過ぎて継続する方法

Jenkins宣言型パイプライン構文の複数のステージを定義し、それらのステージのいずれかが失敗しても継続できるようにします。スクリプト化された構文を想定または許可しているため、真の重複である既存の質問は見つかりません。

pipeline {
    agent any
    stages {
        stage('stage 1') {
            steps {
                echo "I need to run every time"
            }
        }
        stage('stage 2') {
            steps {
                echo "I need to run every time, even if stage 1 fails"
            }
        }
        stage('stage 3') {
            steps {
                echo "Bonus points if the solution is robust enough to allow me to continue *or* be halted based on previous stage status"
            }
        }
    }
}

明確にするために、スクリプト構文でこれを実現する方法を探していません。この種のフロー制御が宣言構文で実際にサポートおよび形式化されているかどうかを理解しようとしています。そのために、私が探しているものを正確に定義しようとします。

必須

  • 試行/キャッチなし。スクリプトモードにドロップダウンしたり、宣言型パイプラインを別の共有ライブラリやスクリプトブロックに「ラップ」したくありません。
  • post stepシェナンガンはありません。他のすべてのロジックを含むpost alwaysステップを持つ1つのステージではなく、真の複数のステージが必要です

オプショナル

  • 失敗した段階は失敗したと認識される必要があります。 「スキップ」または「継続」されたため、失敗したステージが緑色で表示されるのは望ましくありません。
  • 失敗したステージを含むビルドは、赤(または黄色、または緑以外のもの)としてマークする必要があります。

関連するが十分ではない

11
dolphy

私は何かを見逃しているかもしれませんが、宣言的な、opinionatedパイプラインのアイデアは、最も単純なユースケースを網羅することです。 opinionatedでカバーされていない何かが必要になった瞬間、スクリプト化されたパイプラインに頼る必要があります。これは、「宣言的パイプライン」の「要件」のみを指します。

他の「要件」に関しては、それらはほとんど意味がありません。全体のアイデアは、低レベルのlevelさを共有ライブラリにラップして、ユーザーに次のような構造を提供することです。

    mylib.failable_stages({
      stages {
        stage('stage 1') {
          steps {
            echo "I need to run every time"
          }
        }
        stage('stage 2') {
          steps {
            echo "I need to run every time, even if stage 1 fails"
          }
        }
        stage('stage 3') {
          steps {
            echo "Bonus points if the solution is robust enough to allow me to continue *or* be halted based on previous stage status"
          }
        }
      }
    })

当然、そのようなmylibクラスとfailable_stagesはクロージャを取得し、それをさまざまな配管/定型コードでラップします。

これがお役に立てば幸いです。

4
mvk_il

これが可能になりました:

pipeline {
    agent any
    stages {
        stage('1') {
            steps {
                sh 'exit 0'
            }
        }
        stage('2') {
            steps {
                catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
                    sh "exit 1"
                }
            }
        }
        stage('3') {
            steps {
                sh 'exit 0'
            }
        }
    }
}

上記の例では、すべてのステージが実行され、パイプラインは成功しますが、ステージ2は失敗として表示されます。

Pipeline Example

想像したかもしれませんが、buildResultstageResultを不安定にしたり、他のものにしたい場合は、自由に選択できます。ビルドに失敗して、パイプラインの実行を継続することもできます。

これはかなり新しい機能であるため、Jenkinsが最新であることを確認してください。

EDIT:これは、この回答が最初に書かれた質問です。また、他のいくつかの質問に対する正しい答えでもあるため、この答えもそこに掲載しました。これは、複数の同様の問題に対する正しいソリューションです。それを明確にするために、特定の質問に対する他の回答を調整しました。時間を節約するために答えをコピーしただけです。それはそれが良い正解ではないという意味ではありません。

2
Erik B

それは仕事がお互いにどれだけ依存しているかにかかっていると思う。あなたの例から導き出された

  • ステージ1は最初のステージであるため、他のすべてのステージから独立しています。
  • stage 2は、stage 1 =すぐに失敗する可能性があり、stage 2が実行に必要です
  • ステージ3は、stage 1 andステージ2

したがって、対応するパイプラインは

pipeline {
    stages {
        stage('Independent tasks') {
            parallel {
                stage('stage 1') {
                    steps {
                        sh 'exit 1' // failure
                    }
                }
                stage('stage 2') {
                    steps {
                        echo 'Happens even so stage 1 fails'
                        sh 'exit 0' // success
                    }
                }
            }
            post {  // 'stage 3'
                failure {
                    echo "... at least one failed"
                }
                success {
                    echo "Success!"
                }
            }
        }
        stage ('stage 4') {
            steps {
                echo 'Happens only if all previous succeed'
            }
        }
    }
}

stage 1およびstage 2は常に実行されます、stage 3は、成功/失敗の組み合わせに反応します。


追加の考え:この概念は、パイプラインの「最後」でのみ機能します。途中で必要になり、ビルドを続行する必要がある場合、それを独自のジョブに移動して build job プラグイン。

pipeline {
    stages {
    stage('Start own job for stage 1, 2, 3') {
        steps {
            build job: 'stageOneTwoThree', propagate: false, wait: true
        }
    }
    stage ('stage 4') {
        steps {
            echo 'Happens always, because "propagate: false"'
        }
    }
}
0
newur