生産性向上ブログ@miyajan

圧倒的生産性向上を目指すエンジニアのためのブログ

Jenkins Pipeline の when + branch は通常のパイプラインジョブでは使えない

Jenkins Pipeline についての小ネタメモです。

まず、when + branch の条件について簡単に説明しますと、ビルドが特定のブランチに対して実行されるときだけ処理を実行するように書ける文法です。

pipeline {
    agent any
    stages {
        stage('Example Build') {
            steps {
                echo 'Hello World'
            }
        }
        stage('Example Deploy') {
            when {
                branch 'production'
            }
            steps {
                echo 'Deploying'
            }
        }
    }
}

↑の例をマルチブランチパイプラインジョブで実行すると、production ブランチに対してトリガされたときだけ “Example Deploy” ステージが実行されます。

しかし、これを通常のパイプラインジョブで実行すると、ブランチに production を指定しても、

Stage 'Example Deploy' skipped due to when conditional

としてスキップされてしまいます。

不具合かと思って関連issueをウォッチしていたのですが、どうやらこれは仕様となったようです。公式ドキュメントにも明記されました。

branch
Execute the stage when the branch being built matches the branch pattern given, for example: when { branch ‘master’ }. Note that this only works on a multibranch Pipeline.

内部的に通常のパイプラインジョブとマルチパイプラインジョブでソースコード管理に依存しているプラグインが異なるのが原因なのですが、ユーザー側としては通常のパイプラインジョブでも同様に使えるほうが自然に思えるので、残念です。前回の記事で書いたように、通常のパイプラインジョブでもパラメータでブランチ名を受け取ってビルドのような用途は普通にありそうです。

一応、expression で git コマンドを叩いてブランチ名を比較するという回避策が issue のコメント上で紹介されていました。

when {
  expression {
    return sh(script: "git rev-parse --abbrev-ref HEAD", returnStdout: true).trim() == "master"
  }
}

ただ、手元で試したところ、通常だとブランチ指定子を設定しても Detached HEAD 扱いになるので、SCM の追加処理で “Check out to specific local branch” を設定しないとダメでした。(関連issue

通常のパイプラインジョブでブランチ名による分岐をしたいときは要注意です。