Jenkinsfileで複数ジョブまたがるやつをコード化できました
Jenkins pipline scriptとは?
昔はpluginで提供されてたみたいだけど、Jenkins2からは標準pluginになったという代物。Groovy DSLと、groovyのscriptでJenkinsおじさんのジョブをコードに落とせます。
Jenkinsfileでジョブを書くときのメリットとデメリットでまとめました。デメリット多そうですがそれ自体は小粒なのと、がんばれば解消できると思うのでメリットの方が大きいかなと思ってます!
今回使いたいと思った理由として、あるパラメータを指定したときだけは、既存のマイグレーションジョブをtriggerして、そうじゃないときはスキップしてほしいというのを実現したかったんですが、shだけじゃできませんでした。 これができるのがJenkins pipline scriptだけなので、これがでかい気がします💯
pros
- shでは無理だった条件付きでの別ジョブのトリガーやスキップができるようになる!!
- ステージごとにビルドごとの時間が表示されてCircleCiっぽい見た目になる
- ジョブの全て(パラメータ設定からビルド後のアクションまで)をコード化できる
cons
- ヒアドキュメントで複数行のshを書いた時にパイプが使えない・・
- groovyスクリプトでやるか、sh自体をファイルにしといて実行するだけにする
- groovyのsandbox環境で実行されるので、自作データクラスとかGroovyのリッチなクラスがそのままだと使えない
- 設定で権限解放みたいなことすれば使えるみたい(試してない)
- shの標準出力を受けたらtrimしないと改行が入る
- Slackのnotifier pluginなどGUIだったらポチポチとチェックボックスつけるだけでいい感じにメッセージ通知してくれたけど、あれを全部自分で書かないといけない・・
- 誰かが書いてそれを部全体でパクればOK
- Groovyとしては正しいんだけど、JenkinsのPipilineとしては受け付けないみたいなやつがあるので最初辛い
- パラメータのデフォルト値を変えるときはリポジトリへのプッシュが必要(画面から上書きできない)
実際のJenkinsfile
ポイントはこの辺ですね。
parametersでパラメータ設定ができるstageがビルドの論理的な箱的な感じwhenでstageをskipするか設定できるbuild jobで別jobをtriggerできるpostディレクティブでビルド後の処理を書く
下のやつは動かない仮のコードですが雰囲気を味わってもらうことはできるかと思います。
pipeline {
agent any
parameters {
choice(
choices: "develop\nstaging\nproduction",
description: "デプロイ先の環境",
name: "ENV")
string (
defaultValue: "",
description: "ビルドのコミットハッシュ",
name : "BUILD_VERSION")
}
stages {
stage ("start notification") {
steps {
slackSend color: "good", message: "$JOB_NAMEのデプロイが開始されました"
}
}
stage ("migration") {
when {
expression {
// as you like
}
}
steps {
build job: migration_job,
parameters: [
string(name: "ENV", value: ENV),
string(name: "BUILD_VERSION", value: BUILD_VERSION)
]
}
}
stage ("deploy") {
steps {
script {
echo "start deploy"
slackSend color: "good", message: "$JOB_NAMEのデプロイが完了しました :ok_woman: リビジョン: ${BUILD_VERSION}"
}
}
}
post {
success {
slackSend color: "good", message: "$JOB_NAME [$ENV] SUCCESS - ${currentBuild.displayName} ${BUILD_VERSION}"
}
unstable {
slackSend color: "warning", message: "$JOB_NAME [$ENV] UNSTABLE - ${currentBuild.displayName} ${BUILD_VERSION}"
}
failure {
slackSend color: "danger", message: "$JOB_NAME [$ENV] FAILURE - ${currentBuild.displayName} ${BUILD_VERSION}"
}
}
}