次のビルドパイプラインをジョブとして設定しています。
Stage 1 - verify all dependencies exist
Stage 2 - build the new jar
Stage 3 - Run integration tests
Stage 4 - Deploy to staging environment (manual step)
Stage 5 - Deploy to production environment (manual step)
一時的な障害が発生した場合に、特定の段階からビルドパイプラインを開始する方法を探しています。たとえば、ユーザーが本番環境にデプロイするためにクリックしたときにネットワークの問題があったとしましょう。ステージ1からパイプラインを開始することは理にかなっていないと思います...そのステップをもう一度試して、そこからパイプラインで続行したいと思います。 Build Pipeline Pluginにはこのような機能はありません。
ありがとう!!
checkpoint
が探しているものだと思います。残念ながら、無料版ではなく、CloudBees Jenkins Enterpriseスイートでのみ利用できます。
非常に一般的なユースケースのように見えるので、それがオープンソースバージョンになることを期待しましょう。
より良い解決策は、私が この質問 で提案したものと同様の解決策です。
次のように、シングルステージの周りに「if」ガードがあるパイプラインスクリプトを記述します。
stage "s1"
if (theStage in ["s1"]) {
sleep 2
}
stage "s2"
if (theStage in ["s1", "s2"]) {
sleep 2
}
stage "s3"
if (theStage in ["s1", "s2", "s3"]) {
sleep 2
}
次に、パラメーター「theStage」を「s1」に設定することにより、このスクリプトを使用してすべてのステージを一度に実行する「メイン」ジョブを作成できます。このジョブは、すべてのステージが一度に実行されるときに統計を収集し、有用な推定時間を提供します。
さらに、このスクリプトを使用し、開始したいステージでパラメーター化された「部分実行」ジョブを作成できます。ただし、推定はあまり有用ではありません。
一方、Jenkinsには任意のステージからジョブを再開できる組み込みソリューションが用意されているため、他の多くの回答は廃止されています。 https://jenkins.io/doc/book/pipeline/running-pipelines/ これは 宣言的パイプラインのみ に適用されます。
コードを retry
ステップでラップできます。
stage "Deployment"
retry(3) {
sh "deploy.."
}
編集:これはジェンキンスの無料版で役立つかもしれません。 CloudBees Enterpriseのユーザーは、@ tarantogaの回答を参照してください。
少し古いトピックですが、Jenkinsはまだ(!)をサポートしていないため、スクリプト化されたパイプライン実装のための別のソリューションを送信しています。パイプラインを実行するときに、ステージのリストを動的に作成することに基づいています。
enum Steps { PREPARE(0, "prepare"), BUILD(1, "build"), ANALYSE(2, "analyse"), CHECKQG(3, "checkQG"), PROVISION(4, "provision"), DEPLOY(5, "deploy"), ACTIVATE(6, "activate"), VERIFY(7, "verify"), CLEANUP(8, "cleanup") Steps(int id, String name) { this.id = id this.name = name } private final int id private final String name int getId() { id } String getName() { name } public static Steps getByName(String name) { println "getting by name " + name for(Steps step : Steps.values()) { if(step.name.equalsIgnoreCase(name)) { return step } } throw new IllegalArgumentException() } }
def prepareStages(def startPoint){ println "preparing build steps starting from " + startPoint Set steps = new LinkedHashSet() steps.add(Steps.PREPARE) steps.add(Steps.BUILD) steps.add(Steps.ANALYSE) steps.add(Steps.CHECKQG) steps.add(Steps.PROVISION) steps.add(Steps.DEPLOY) steps.add(Steps.ACTIVATE) steps.add(Steps.VERIFY) steps.add(Steps.CLEANUP) List finalSteps = new ArrayList() steps.each{ step -> if (step.id >= startPoint.id) { finalSteps.add(step) } } return finalSteps }
def stage = prepareStages(Steps.getByName( "$ {startStage}"))
node {
try {
//pipelineTriggers([pollSCM('${settings.scmPoolInterval}')]) //this can be used in future to get rid build hooks
sh "echo building " + buildVersionNumber(${settings.isTagDriven})
tool name: 'mvn_339_jenkins', type: 'maven'
script {
println "running: " + stages
}
stage('Prepare') {
if (stages.contains(Steps.PREPARE)) {
script { currentStage = 'Prepare' }
//.....
}
} //...
「startStage」は、次のように定義されたビルドパラメーターです。
パラメータ{choiceParam( 'startStage'、['prepare'、 'build'、 'analyse'、 'checkQG'、 'provision'、 'deploy'、 'activate'、 'verify'、 'cleanup']、 'Pick up開始したいステージ ')}
これにより、パイプラインを開始するステージを選択できます(準備ステージはデフォルトで設定されています)
ステージビュープラグインの履歴を壊さずに条件付きでステージを実行する別のスケッチを次に示します。
彼らが言う :
動的ステージ:一般に、動的に変化するステージを視覚化する場合は、ステージを含めることを条件とせず、ステージのコンテンツを実行することを条件にします
これが私がこれまでに思いついたものです。主に動作しているようです:(他のダミーの手順は無視してください)
JP_STAGE
Jenkins Jobパラメーターからのステージ名チェックをきれいにラップする小さなconditionalStage
ヘルパー関数を定義します。
conditionalStage
firstがstage
を開き、ステージ内でstageIsActive
をチェックする方法に注意してください。すべての手順。このようにして、Stage View Pluginはすべてのステージを認識し、混乱することはありませんが、ステージのステップはまだスキップされます。
def stageSelect = JP_STAGE.toLowerCase()
// test if stage or any of sub-stages is active
def stageIsActive(theStage, theStages) {
// echo "pass: $theStages"
// ARGL: https://issues.jenkins-ci.org/browse/JENKINS-26481
// def lcStages = theStages.collect {it.toLowerCase()}
def lcStages = []
for (def s : theStages) { lcStages += s.toLowerCase() }
def lcAllStages = lcStages + ['all']
// echo "check: $lcAllStages"
// echo JP_STAGE.toLowerCase()
if (JP_STAGE.toLowerCase() in lcAllStages) {
echo "Run: Stage '$theStage' is active through '$JP_STAGE'."
return true
} else {
echo "Skip: Stage '$theStage' is NOT active through '$JP_STAGE'."
return false
}
}
// 1st element should be the stage, optionally followed by all sub-stages
def conditionalStage(names, stageBody) {
stage(names[0]) { if (stageIsActive(names[0], names)) {
stageBody()
}}
}
timestamps {
// --S--
conditionalStage(['Intro']) {
echo 'Outside Node'
build job: 'FreeX', wait: true
sleep 3
}
// --S--
conditionalStage(['AtNode', 'Hello', 'Done']) {
node {
// Cloudbees Enterprise Only: checkpoint 'Now'
conditionalStage(['Hello']) {
echo 'Hello World @ Node'
sleep 4
}
conditionalStage(['Done']) {
dir('C:/local') {
echo pwd()
}
}
}
}
}//timestamps
できることは、groovyスクリプトに単一のステップを入れることです。次に、すべてのスクリプトを正しい順序でロードする「runAll」ジョブと、さまざまなステップの単一ジョブを作成できます。
これは機能するはずの方法ですが、ステップが独立して実行できるように、異なるステップが情報を交換する方法に注意する必要があるため、これが理想的なソリューションだとは思いません。
組み込みのソリューションの方がはるかに優れています。