Kesinの知見置き場

知見を共有していきたいじゃないですか

Jenkins2のPipeline入門のメモ

Jenkins2のPipelineに入門した際にメモした内容をせっかくなので公開しておきます。

基本

step, node, stage

パイプラインのチュートリアルでいきなり図と共に登場するので最初はどう違うのか分かりにくいが、Jenkinsのビルドの流れにそれぞれ対応しているので実は難しくない。

step

今までのbuild stepと同じ。普通に1ジョブ内でやることを分割する。
主にプラグインの機能を呼び出すときにスニペットビルダー(後述)から生成する。

node

キューに独立して乗せられ、毎回削除されるWorkspaceが割り当てられる。
ということがチュートリアルでは書かれているが、要はnodeのブロック単位でJenkinsのキューに積まれるということ。

stage

stepやnodeと違って明確な役割はないが、パイプライン中の処理に名前を付けることができる。
GUI上でどのstageまで通過したか、どこで失敗したか分かりやすくなるのである程度の処理の固まりをstageに分割すると分かりやすい。
一般的にはinstall, build, test, deployみたいな単位でstageを分けると良さそう。

実際にパイプラインを書くときにはnode, stage, stepという順にブロックを作っていくことになる。

node {
    stage('build') {
        echo 'hoge'
    }
}

変数

パイプライン中でのローカル変数は以下のように作れる。

def hoge = 1

Jenkins1系では1ビルド内で新たに変数を作ることができなかったので何気にすごい嬉しい。
(自分が知らなかったでそのようなプラグインはあったかもしれませんが)

関数

パイプライン中での関数も定義することができる。

def hoge(arg) {
  echo 'hoge'
}

これも変数と同じく今までできなかったのでとてもありがたい。

条件分岐・例外処理

ifやtryなど基本的な文法はgroovyのものが使える。 buildで呼び出したジョブがfailしたかはtry-catch-finallyでハンドリングできる。

具体例は後述

別のジョブ呼び出し

build jobで既に作られているジョブやパイプラインを呼び出すことができる。
自分で書いてもいいが、スニペットビルダーを使うとジョブ名の補完が効いたり、必要なパラメータをフォームに入力するとコードを出力してくれるのでこれを使うべし。

f:id:Kesin:20161013013452p:plain

イディオム集

ビルド中に下流ビルドを実行する

今までもParameterized Trigger Pluginを使うことで実現できていましたが、ビルド途中でパラメータの中身を改変したりパラメータの名前を変えることが大変でした。

パイプラインでは変数を新たに定義したり、パラメータを途中で書き換えることも容易です。

node {
    stage ('build start'){
        def text = 'hoge'
        build job: 'my_echo', parameters: [text(name: 'text', value: text)]
    }
}

条件付きで別ジョブを走らせたい

パラメータの内容によって次に走らせるジョブを変更したり、そもそも実行させなかったりするような条件分岐は今まではFlexible Publishを使っていましたが、GUIで条件を設定する必要があったのでめんどくさかった奴です。

パイプラインではif-elseやtry-catch-finallyで制御できるので、普段からコーディングで使ってる我々からすると直感的に書けるようになりました。

前のジョブが失敗したときに次のジョブをスキップして通知を出すというサンプル

node {
    stage ('build'){
        num = 1
        try {
           // failになるジョブ
           build job: 'odd_error', parameters: [string(name: 'num', value: num)]
        } catch (err) {
            currentBuild.result = 'FAILURE'
        } finally {
            echo 'end try block'
        }

        if(currentBuild.result == 'FAILURE') {
            // 実際にはechoの代わりにSlack通知など
            echo 'job failed'
        }
    }

並列に下流ジョブを走らせたい

今までのParameterized Trigger Pluginでは下流ジョブの名前をカンマ区切りで並べていけば実現できていましたが、パイプラインではちょっと複雑な書き方になりました。

job = [:]
job['job1'] = { build job: 'my_echo', parameters: [text(name: 'text', value: 'job1')] }
job['job2'] = { build job: 'my_echo', parameters: [text(name: 'text', value: 'job2')] }
parallel job

この記述でjob1, job2は並列にキューに乗って実行されます。

参考