Edited at

【Jenkins】Declarative Pipeline入門

More than 1 year has passed since last update.

新卒の@Toriyabotです。

情報系の学部出身ではないのですがエンジニアとして入社し、最近では弊社のCI環境の改善を行なっています。

その過程でJenkinsのPipeline機能の導入を行なったのですが、これについて簡単に紹介したいと思います。


Pipelineとは

Jenkinsはビルドやテスト、インスペクション、デプロイ(まとめてビルドと総称)などを自動化して「継続的インテグレーション(CI)」をサポートするツールですが、この自動化された一連の流れを定義するために導入されたのがPipelineです。

ジョブの新規作成画面から選ぶことができます。


ビルドスクリプトの一連の流れをJenkinsfileに記述する

Pipelineでは"ビルド"の流れをJenkinsfileと呼ばれるgroovyベースのDSLで記述します。

groovyのコードとして書くことで、今まで設定できなかった項目も自由に記述できますし、何よりも複雑になりがちな一連のビルドの流れをJenkinsfileとしてバージョン管理できることが大きな利点だと思います。


Scripted PipelineとDeclarative Pipeline

ちなみにPipeline Plugin 2.5までは文法としてScripted Pipelineという書き方が使われていましたが、2.5以降はDeclarative Pipelineという書き方が推奨されるようになりました(部分的にScripted Pipelineを混ぜることもできます)。

情報を検索するときにはScripted/Declarativeの違いに注意する必要があります。


サンプルコード

以下に示すサンプルもDeclarative Pipelineのスタイルで書かれています。

コメントを多めにしたので何をしているかはわかりやすいのではないかなと思います。


Jenkinsfile

#!groovy

pipeline { // Declarative pipelineであることを宣言する
agent any // どこで実行するか等の情報(どのノードか、どういうdocker imageかとかを指定する)
stages { // Stageを列挙する
stage('チェックアウト') {
steps { // stageは必ずstepsをもつ
// Slack通知
// グローバルな環境変数がenvに入っている
slackSend color: "good", message: "${env.JOB_NAME} - #${env.BUILD_NUMBER} Started! (<${env.BUILD_URL}|Open>)"
// Githubのprivateリポジトリを使う時は認証情報の記述が必要
checkout([$class: 'GitSCM',
branches: [[name: '*/master']],
doGenerateSubmoduleConfigurations: false,
extensions: [],
submoduleCfg: [],
userRemoteConfigs: [[credentialsId: 'idだよ', url: 'git@hogehoge']]
])
}
}
stage('環境設定') {
steps {
sh './prepare_env.sh'
}
}
stage('テスト') {
parallel { // parallelはstageの直下に書く
stage('フロントテスト') {
steps {
sh './front_test.sh'
}
}
stage('サーバサイドテスト') {
steps {
sh './server_test.sh'
}
}
}
}
}
post { // ビルド終了後の処理はここに書く
always { // ビルド終了後、必ず行う処理
junit "junit_output.xml" // 出力されたテスト結果ファイルを読み込む
}
success { // 成功した場合
postBuildSlackSend("good", "SUCCESS")
}
failure { // 失敗した場合(どこかのステップでエラーを吐いた場合)
postBuildSlackSend("danger", "FAILURE")
}
aborted { // 中断した場合
postBuildSlackSend("warning", "ABORTED")
}
// changed, unstableもあるよ!
}
}

// 自身で定義した関数の例
def postBuildSlackSend(bar_color, result) {
slackSend color: bar_color, message:"${env.JOB_NAME} - #${env.BUILD_NUMBER} ${result} after ${currentBuild.durationString.split(" and")[0]} (<${env.BUILD_URL}|Open>)"
}



コード記述のためのサポート: コードジェネレータが使える!

さて、このコードをいざ自分で書くとなるとgroovy知らないし困ったな、みたいな気持ちになりますが、そういう人でもすぐに使えるようにコードスニペットを自動で生成してくれる機能がJenkinsにはついています。

ジョブの「設定」画面から「Pipeline Syntax」というリンクを開きます。



「Snippet Generator」が開きます。これはcheckout処理を行うコードを生成しようとしているところです。

こういった必要事項を入力するだけでコードを生成する機能が、結構な数、用意されているので意外とすぐ、使えるJenkinsfileが出来上がるのではないでしょうか。


結果の可視化: Stage View

Jenkinsの推奨プラグインである、Stage View Pluginを使うとPipelineを可視化することができます。

各Stageでの所要時間のところからログ(の末尾部分)を出すこともでき、結果の要約を簡単に確認することもできます。

どこのステップに時間がかかっているか一目瞭然なので、CIの高速化を目指す場合などに大変便利です。


まとめ

Pipelineを使うとビルドの流れをコードとして管理できるだけでなく、サクッと並列処理が書けたり複数マシンをまたがるような処理もシンプルに書けたりという利点があります。他にもビルドの途中でJenkinsが終了しても、Pipelineで作成したジョブだったらJenkinsが途中で終了してしまっても、Jenkinsを起動し直せばジョブを継続できるようになっています。


所感

実際にパイプラインのジョブを運用してみて、限られた計算資源しかない中、並列処理を行いビルドの実行時間を短くできたのはよかったです。またGUIで行う大量の設定をコードに落とし込んでバージョン管理できるようになったのは安心感がありました。Stage Viewも現代的なUIで良いですね。

皆さんもPipelineで快適なJenkins生活を送りましょう!