1.公式のJenkins Pipeline Pluginを使用する
類似のもの(Build Pipeline plugin or Buildflow plugin)ではなく、公式のものを使用する。
- 公式のPipelline Pluginは日々改善している
- Jenkinsのマスターノードが再起動したとしても継続する機能を提供済みで、他のプラグインの機能を代替する機能を提供する予定。
2.Pipeline as Codeにする
JenkinsFileをバージョン管理システムに登録することで、他のソフトウェアと同様のバージョン管理とテストができる。
Pipelineスクリプトのデフォルト名はJenkinsFile。
IDE,GitHubにgroovyと認識され、コード補完、コードハイライトなどが効くように、スクリプトの始めに以下を追加する。
#!groovy
3. 論理的なまとまりを1つのstageに定義する
もともとstageは論理的なまとまりに用いる。セットアップなどは1つのstageにはせず、論理的なまとまりで1つのstageを定義する。
stage 'build'
//build
stage 'test'
//test
結果として、stageが可視化される。
4. 処理は1つのnodeブロックで囲う
- デフォルトでは、JenkinsFileスクリプトはリソースをあまり使わないマスターノードで動く。
- JavaのコンパイルなどはJenkinsの分散機能を使用して、slaveノードで行う。
stage 'build'
node{
checkout scm
sh 'mvn clean install'
}
5. なるべくparallel処理を書く
- parallel処理はPipeline処理を早くする。
- 開発者、チームへ早いフィードバックができる。
parallel 'shifting':{
//everything
}, 'left':{
//I can
}
6. parallel処理にも必ずnodeを定義する
parallel処理は複数のnodeで処理を分散して行うために使うので、nodeを定義しなければならない。
parallel 'integration-tests':{
node('mvn-3.3'){ ... }
}, 'functional-tests':{
node('selenium'){ ... }
}
7. nodeブロック内でinputは使ってはいけない
- inputはダイアログが押されるまでPipeline処理を停止する。そのダイアログが選択されるまでは時間がかかる。
- slaveノードは高リソースを処理するためのノードであり、ダイアログで停止してしまうとリソースの無駄遣いになってしまう。
そのため、inputはnodeの外側に記述する。
stage 'deployment'
input 'Do you approve deployment?'
node{
//deploy the things
}
8. inputはtimeoutでラップする
Pipelineにはタイムアウトを設定するtimeoutがあるので、inputはtimeoutでラップする。
- inputをtimeoutでラップすることで、ダイアログがずっと選択されない場合にも処理がクリーンアップされる
timeout(time:5, unit:'DAYS') {
input message:'Approve deployment?', submitter: 'it-ops'
}
9. 環境変数をglobal variableに定義してはならない
環境変数をglobalに設定(ex. export AA=BB)するのではなく、withEnvを使用して環境変数を設定する。
- 環境変数をglobalに設定すると、他にも影響が発生する。
withEnv(["PATH+MAVEN=${tool 'm3'}/bin"]) {
sh "mvn clean verify"
}
10. stashをなるべく使う
stage間またはnode間でファイルをやり取りする場合はarchiveではなくstash/unstashを使う。
- stash/unstashはstage間、node間でファイルを共有するためのコマンド。
- archiveは長期保存のためのコマンド。
- ソースをやりとりする場合はstash/unstash。中間成果物のバイナリーを保存する場合はarchive。
stash excludes: 'target/', name: 'source'
unstash 'source'
11. timestampsブロックを使いまくる
timestampsを使用すると、コンソールログに実施時間が表示される。
デフォルトでついていてほしい機能なので、timestampsブロックを多用する。
timestamps {
// process
}
参考