Jenkins Pipeline を使ってみたメモ その2

notifyCommit を呼び出したときに実行されるビルドについて、フリースタイルと Pipeline で下記の違いが合った。

  • フリースタイル
    • 1回の notifyCommit で複数のブランチがビルドされる(こともある)
    • Git ポーリングで見つかった、更新されたすべてのブランチのビルドがキューに入る
  • Pipeline
    • 1回の notifyCommit で1つのブランチしかビルドされない
    • Git ポーリングで見つかった、更新されたブランチのうち1つだけがキューに入る
    • さらに、Pending のビルドがあると notifyCommit を呼んでもキューに入らない

なので、下記のようにブランチ [A] が「Pending 〜 開始」の間に別のブランチ [B] がプッシュされるとビルドされない。

  1. [A] ブランチをプッシュ
  2. [A] notifyCommit 呼び出し
  3. [A] ビルドが Pending
  4. [B] ブランチをプッシュ
  5. [B] notifyCommit 呼び出し
  6. [A] ビルドが開始

もっとも、[A] のビルドが開始された後に何らかの方法で notifyCommit を呼べば [B] のブランチはビルドされるし、3. から 6. までの時間はそんなに掛からないはずなので(待機時間を 0 すれば Git のポーリングの時間だけのはず)、あまり困らないような気もしたけど・・

下記のように3つのブランチがプッシュされた状況だと普通に起こりえる。

  1. [A] ブランチをプッシュ
  2. [A] notifyCommit 呼び出し
  3. [A] ビルドが開始
  4. [B] ブランチをプッシュ
  5. [B] notifyCommit 呼び出し
  6. [B] ビルドが Pending (並列実行は無効にしている)
  7. [C] ブランチをプッシュ
  8. [C] notifyCommit 呼び出し
    • [B] が Pending なのでビルドのキューに入らない
  9. [A] ビルドがが終了
  10. [B] ビルドが開始

このケース、[C][A] だった場合も同じだと思う。

うーん、Pipeline は Git の notifyCommit との連携が微妙な感じ・・・

解決?

と思ってたんだけど、Pipeline の前段にフリースタイルジョブを置いて Parameterized Trigger の Pass-through Git Commit that was built でコミット ID を渡せばすべて解決した気がする。

↑の問題はそもそもフリースタイルなら問題ないので、フリースタイルのジョブから Pipeline をトリガすれば良い。

また、下記の記事に書いた checkout scm でコミットが指定されない問題も解決できているように思う。

checkout scm でコミットが指定されない問題は、要するに次のような Jenkinsfile だったときに

node ('ore') {
    stage 'first'
    checkout scm
    sleep 60
}

node ('are') {
    stage 'second'
    checkout scm
}

sleep 60 している間にブランチがプッシュされると、次のステージの checkout scm で異なるコミットがチェックアウトされてしまう、ということ。

がしかし、Parameterized Trigger でコミット ID を渡してやれば大丈夫。

また、BRANCH_NAME が設定されない問題も Parameterized Trigger で $GIT_BRANCH を元に設定してやれば良い。

ただ、Pipeline のジョブを手動で実行した場合はダメなので注意が必要。手動でビルドしたければ前段のフリースタイルジョブをビルドしなければならない・・・