Jenkins PipeLine 使いどころと、利用メモ

# Jenkins パイプラインを使ってみて。（GUI操作からの移行期間）

## はじめに
### Jenkins パイプラインを利用しないほうが良いケース

Jenkinsのパイプラインを最近利用しはじめました。コードですべてかけて修正も簡単なため、コーディングが慣れているアプリ開発からJenkinsを触り始めた人にはJenkinsのパイプラインはとても魅力的に思うと思います。
ただし、以下の取り組みを利用したい場合、Jenkinsのパイプラインを利用するには不都合に感じるかもしれません。

- ジョブの実行結果をJenkinsのコンソール画面からWorkSpaceを利用して調査・確認がしたい場合
    - Workspace 内部にログが存在して、そのログをジョブ失敗時の調査に利用している場合（Jenkinsから別スレッドでサーバーを立てるなど）、Workspace 内部を確認するユーザービリティが著しく悪いです。
    - GUIで作成したジョブはジョブのトップ画面からWSをクリックして探すことができます。
    - Pipeline で実施したWSのモジュールは、最後に実行したジョブであっても一度ジョブの実行履歴から該当ジョブをクリックしてPipelineのステップからWorkspaceを見つけるところから始まります（どんなに早くても3クリック余計にかかる。） 
- Jenkins のプラグインを利用してジョブ結果の変遷を確認したい見たい場合
    - 2020年11月時点では可能。（@dmc@github さんに教えていただきました。）
    - Warning-Next-Generationプラグインを利用することで、グラフ表示が可能です。
    - 参考：https://ci.jenkins.io/job/Plugins/job/ec2-plugin/job/master/
- ジョブの完了結果のメール通知の文面に多くのコンテンツを盛り込みたい場合
- pipeline でもメール通知及び本文の作成はできます。ただし、これをコード上に記載する必要があるため、文面として見た場合コードの可読性は低くなります。
- 改行の位置や、横線のハイフンなどレイアウトの工夫を行いたい場合(ユーザへの通知向け)で利用する場合は、レイアウトの変更がしやすいGUI で設定するほうがオススメです。


### Jenkins パイプラインを利用したほうが良いケース

- 1度作成したジョブを該当プロジェクト外でも利用するケースが多い場合。（再利用）
- パラメーター違いのコピージョブが数多くある場合。（集約）
- 実行して完了なジョブで、Jenkinsコンソール上でジョブの結果を確認する作業がほとんどない場合。（実行のみ）


## Jenkins pipeline を利用した場合

Jenkins のパイプラインは2種類あります。

### scripted Pipeline

下記のような記法です。

```
node() {
	try {
		stage("setup"){
			// 分岐
			if( step == "step1" ){
			    project_stage = "01"
			} else if ( step == "step2" ){
			    project_stage = "02"
			}
			echo project_stage 
		}
	}
	catch (exc) {
		mail to:"me@example.com", subject:"FAILURE: ${currentBuild.fullDisplayName}", body: "ジョブが落ちました."
	}
	finally {
		echo "終了" 
	}

}

```
#### メリット

文法が比較的簡単で、処理を記載する自由度が高いです。
シェルと記法が似ているため、シェルのように、内部で処理を記載することが可能です。
後述する、declarative pipelineとは異なり、if 文が使えるため、IF分岐で処理を記載できるのがとてもよいです。


#### デメリット

ジョブの処理終了後に、メール通知などをしたい場合、
try-catchを記載しないとできないなど、ややわかりづらい実装になります。
特に、Jenkinsジョブでできていた内容をそのまま、pipeline に移行しようとした場合、処理が1対1 とならないため、ハマりやすいです。



### declarative pipeline

下記のような記法です。

```
pipeline {
	stages{
		stage("setup-step1"){
			when { 
				environment name: 'step', value: 'step1' 
			}
			steps{
				script{
					project_stage = "01"
				}
				echo project_stage 
			}
		}

		stage("setup-step2"){
			when { 
				environment name: 'step', value: 'step2' 
			}
			steps{
				script{
					project_stage = "02"
				}
				echo project_stage 
			}
		}
	}

post {
	always {
		echo "終了" 
	}
	success {
		mail to:"me@example.com", subject:"SUCCESS: ${currentBuild.fullDisplayName}", body: "ジョブが成功！."
	}
	failure {
		mail to:"me@example.com", subject:"FAILURE: ${currentBuild.fullDisplayName}", body: "ジョブが失敗！."
	}
}

```


#### メリット

可読性が非常に高いです。文法や記法がはっきりしているため、
どういう条件で、どんな処理をしているのか非常にわかりやすい。

また、ステージの区切りがはっきりしているため、
どのジョブがどの処理を実行中であるのか、切り分けも簡単になります。

#### デメリット

上記のサンプルを、scripted Pipeline と比較すると、ネストが非常に深いです。
分岐処理も、when 句で丁寧に実装する必要があるため、すぐにジョブを作成したいなどの場合は、煩わしさを感じることになるでしょう。
特に、scripted Pipelineから移行すると、if 分岐が利用できないため、想定以上に修正が必要なケースが発生しやすいです。



## まとめ

Jenkinsのパイプラインは、メンテナンスをモジュール管理でできるため、非常に運用がしやすいので、ぜひしたほうが良いでしょう。

scripted pipeline とdeclarative pipelineはどちらを使うかは要件次第になります。（通知が必要かどうか。）筆者は、scripted pipelineから、declarative pipelineへ、そして、declarative pipelineからscripted pipelineへと好みが戻ってきました。
日常的に、Programingをしていると、scripted pipelineのほうが書きやすいように思えます。